# 画面設計書 5-MFA設定画面

## 概要

本ドキュメントはInvenTreeシステムのMFA設定画面の設計仕様を記載する。二要素認証の初期設定を行うための画面である。

### 本画面の処理概要

MFA設定画面は、ユーザーがログイン後にMFA（多要素認証）の設定を求められた場合に表示される画面である。TOTP（Time-based One-Time Password）認証の初期設定を行い、認証アプリにシークレットキーを登録させる。QRコードをスキャンするか、シークレットキーを手動入力して認証アプリを設定し、生成されたコードで認証を検証する。

**業務上の目的・背景**：組織のセキュリティポリシーによりMFA設定が必須化されている場合、ログイン後に本画面でMFAの初期設定を完了させる必要がある。ユーザーの認証アプリ（Google Authenticator、Microsoft Authenticator等）との連携を確立し、以降のログイン時にMFAによる追加認証を可能にする。

**画面へのアクセス方法**：ログイン認証成功後、MFA設定が未完了かつMFA設定が必須化されている場合に自動的にリダイレクトされる（401レスポンスでMfaRegisterフローが要求された場合）。

**主要な操作・処理内容**：
1. QRコードを認証アプリでスキャン（または手動でシークレットキーを入力）
2. 認証アプリに表示されたTOTPコードを入力
3. 「Add TOTP」ボタン押下による設定の検証と保存
4. 設定完了後、再ログインを促す

**画面遷移**：
- 遷移元：ログイン画面（MFA設定必須時）、MFA認証画面（MFA設定必須時）
- 遷移先：ログイン画面（設定完了後、再ログインが必要）

**権限による表示制御**：
- MFA設定が必須化されているユーザーのみアクセス可能
- ログオフボタンが表示され、設定をキャンセルしてログアウト可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | 認証・ログイン | 主機能 | 二要素認証の初期設定・有効化処理 |

## 画面種別

設定画面

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/mfa-setup` | MFA設定画面 |

## 入出力項目

### 入力項目

| No | 項目名 | 項目ID | 必須 | 型 | 最大長 | 説明 |
|----|--------|--------|------|-----|--------|------|
| 1 | TOTPコード | value | Yes | テキスト | 6 | 認証アプリから取得した6桁コード |

### 出力項目

| No | 項目名 | 説明 |
|----|--------|------|
| 1 | QRコード | TOTP登録用QRコード画像 |
| 2 | シークレットキー | 手動入力用のシークレット文字列 |

## 表示項目

| No | 項目名 | 表示条件 | 説明 |
|----|--------|----------|------|
| 1 | 画面タイトル | 常時 | "MFA Setup Required" |
| 2 | QRコード | シークレット取得後 | 認証アプリ登録用QRコード |
| 3 | シークレットキー | シークレット取得後 | 手動入力用シークレット |
| 4 | TOTPコード入力欄 | 常時 | 検証用コード入力フィールド |
| 5 | Add TOTPボタン | コード入力後 | 設定完了ボタン（コード未入力時は無効化） |
| 6 | ログオフボタン | 常時 | 設定をキャンセルしてログアウト |

## イベント仕様

### 1-画面マウント時

画面表示時にTOTPシークレットを取得する。

**処理フロー**：
1. `useEffect`フックにより画面マウント時に`getTotpSecret`関数を呼び出し
2. `GET /api/auth/v1/account/authenticators/totp` APIを呼び出し
3. 404レスポンスでシークレット情報を取得（未設定の場合）
   - `totp_url`: QRコード用URL
   - `secret`: 手動入力用シークレット
4. エラー時は通知を表示

### 2-Add TOTPボタン押下

入力されたTOTPコードで設定を検証し、保存する。

**処理フロー**：
1. `handleVerifyTotp`関数を呼び出し
2. `POST /api/auth/v1/account/authenticators/totp` APIを呼び出し（codeパラメータ付き）
3. 設定成功時：
   - 「MFA Setup successful / MFA via TOTP has been set up successfully...」通知を表示
   - `doLogout`関数を呼び出してログアウト
   - ログイン画面へリダイレクト（再ログインが必要）
4. 設定失敗時：エラー通知を表示

### 3-ログオフボタン押下

MFA設定をキャンセルしてログアウトする。

**処理フロー**：
1. Wrapperコンポーネントの`logOff`機能により`doLogout`関数を呼び出し
2. セッションを終了
3. ログイン画面へ遷移

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| TOTP設定完了 | user_authenticators | INSERT | TOTP認証器の登録 |

### テーブル別更新項目詳細

#### user_authenticators

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id | 認証されたユーザーID | 外部キー |
| INSERT | type | "totp" | 認証器タイプ |
| INSERT | secret | 暗号化されたシークレット | サーバー側で暗号化 |
| INSERT | created_at | 現在日時 | 作成日時 |

## メッセージ仕様

| No | メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|-------------|---------------|---------------|----------|
| 1 | mfa-setup-success | 成功 | MFA Setup successful / MFA via TOTP has been set up successfully; you will need to login again. | 設定成功時 |
| 2 | mfa-setup-failed | エラー | Failed to set up MFA / {エラー詳細} | シークレット取得失敗時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|----------|----------|
| 1 | シークレット取得失敗 | エラー通知を表示、設定続行不可 |
| 2 | コード検証失敗 | エラー通知を表示、再入力を促す |
| 3 | 既にTOTP設定済み | 404以外のレスポンス、エラー処理 |

## 備考

- TOTP設定完了後は必ず再ログインが必要
- QRコードはTOTP URLから生成される（認証アプリ互換形式）
- シークレットキーはQRコードをスキャンできない場合の手動入力用
- 画面表示中にログオフすると、MFA設定は完了せずに終了する

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

MFA設定に関連するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | `auth_totp`エンドポイント（行34） |
| 1-2 | Auth.ts | `src/frontend/lib/types/Auth.ts` | `FlowEnum.MfaRegister`の定義 |

**読解のコツ**: TOTPエンドポイントがGETでシークレット取得、POSTで検証を行うことを理解する。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MFASetup.tsx | `src/frontend/src/pages/Auth/MFASetup.tsx` | MFA設定画面のメインコンポーネント |

**主要処理フロー**:
1. **行11-16**: 状態初期化（navigate, location, totpQr, value）
2. **行18-20**: シークレット取得（useEffectでgetTotpSecret呼び出し）
3. **行22-37**: JSX描画（QrRegistrationForm、Add TOTPボタン）

#### Step 3: QRコードフォームコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | QrRegistrationForm.tsx | `src/frontend/src/pages/Index/Settings/AccountSettings/QrRegistrationForm.tsx` | QRコード表示とコード入力フォーム |

**読解ポイント**:
- QRコード画像の生成・表示
- シークレットキーの表示
- TOTPコード入力フィールド

#### Step 4: TOTP設定関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | auth.tsx | `src/frontend/src/functions/auth.tsx` | `getTotpSecret`, `handleVerifyTotp`関数 |

**主要処理フロー**:
- **行560-575**: `getTotpSecret`関数
  - 行561: GET auth_totpエンドポイント呼び出し
  - 行562-564: 404レスポンスからシークレット情報を取得
  - 行565-571: エラー時の通知表示
- **行577-594**: `handleVerifyTotp`関数
  - 行583-584: POST auth_totpエンドポイント呼び出し
  - 行585-590: 成功時の通知表示とログアウト

### プログラム呼び出し階層図

```
MFASetup.tsx (エントリーポイント)
    │
    ├─ useNavigate(), useLocation()
    │
    ├─ useState (totpQr, value)
    │
    ├─ useEffect() [マウント時]
    │      └─ getTotpSecret(setTotpQr)
    │             └─ GET auth/v1/account/authenticators/totp
    │                    └─ 404レスポンス: {totp_url, secret}
    │
    ├─ Wrapper (titleText="MFA Setup Required", logOff=true)
    │      │
    │      ├─ QrRegistrationForm
    │      │      ├─ QRコード表示 (totp_url)
    │      │      ├─ シークレット表示 (secret)
    │      │      └─ TextInput (value, setValue)
    │      │
    │      └─ Button (Add TOTP)
    │             └─ handleVerifyTotp(value, navigate, location)
    │                    ├─ POST auth/v1/account/authenticators/totp
    │                    ├─ showNotification (成功)
    │                    └─ doLogout(navigate)
    │
    └─ ログオフボタン
           └─ doLogout(navigate)
```

### データフロー図

```
[入力]                    [処理]                              [出力]

画面マウント ─────────▶ getTotpSecret()
                            │
                            └─ GET auth/totp ────────────────▶ {totp_url, secret}
                                                                    │
                                                                    ▼
                                                            QRコード表示
                                                            シークレット表示

TOTPコード入力 ───────▶ handleVerifyTotp()
                            │
                            ├─ POST auth/totp ───────────────▶ TOTP設定保存
                            │
                            ├─ showNotification ─────────────▶ 成功通知
                            │
                            └─ doLogout() ───────────────────▶ /login へ遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MFASetup.tsx | `src/frontend/src/pages/Auth/MFASetup.tsx` | ソース | MFA設定画面メインコンポーネント |
| auth.tsx | `src/frontend/src/functions/auth.tsx` | ソース | TOTP設定関数（getTotpSecret, handleVerifyTotp） |
| QrRegistrationForm.tsx | `src/frontend/src/pages/Index/Settings/AccountSettings/QrRegistrationForm.tsx` | ソース | QRコードフォームコンポーネント |
| Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | ソース | 認証画面レイアウト |
| ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | ソース | APIエンドポイント定義 |
| router.tsx | `src/frontend/src/router.tsx` | ソース | ルーティング定義 |
