# 画面設計書 207-2FA有効化完了

## 概要

本ドキュメントは、2要素認証（2FA）の有効化が完了した際にリカバリーコードを表示する画面について定義する。2FA設定完了直後に一度だけ表示される重要な画面である。

### 本画面の処理概要

本画面は、2要素認証の初回有効化が完了した直後に表示され、生成されたリカバリーコード（バックアップコード）をユーザーに提示する。リカバリーコードは認証デバイス紛失時のバックアップ手段として極めて重要であり、この画面でのみ平文で表示される。

**業務上の目的・背景**：2要素認証を有効化したユーザーが、スマートフォン紛失や機種変更などで認証アプリやセキュリティキーが使用できなくなった場合に備え、バックアップ認証手段を提供する。リカバリーコードは1回のみ使用可能で、使用後は無効となる。セキュリティ上、この画面で表示された後はサーバー側で平文として参照できないため、ユーザーは安全な場所に保管する必要がある。

**画面へのアクセス方法**：
1. 2要素認証設定画面でOTPまたはWebAuthn登録を完了
2. createアクション成功後、本画面に自動遷移
3. URL: `/-/profile/two_factor_auth`（POST成功後のレンダリング）

**主要な操作・処理内容**：
1. 生成されたリカバリーコード（10個）の表示
2. コードのコピー（クリップボードへ）
3. コードの印刷
4. コードのダウンロード（テキストファイル）
5. 設定画面への遷移（Proceed）

**画面遷移**：
- 遷移元：2要素認証設定画面（OTP/WebAuthn登録成功後）
- 遷移先：2要素認証設定画面（passkeysフラグ有効時）またはアカウント設定画面

**権限による表示制御**：
- ログインユーザーのみアクセス可能
- 2FA登録処理成功後のみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|-------------------|
| 79 | 2要素認証 | 主機能 | 2要素認証有効化の完了 |

## 画面種別

表示（完了）

## URL/ルーティング

- **URL**: `/-/profile/two_factor_auth`
- **HTTPメソッド**: POST（createアクション成功後のレンダリング）
- **ルーティング**: `profiles/two_factor_auths#create`
- **ビュー**: `create.html.haml`

## 入出力項目

本画面は表示専用であり、入力項目はない。

## 表示項目

| 項目名 | 表示内容 | データソース |
|--------|----------|--------------|
| リカバリーコード一覧 | 10個のリカバリーコード | @codes |
| 成功メッセージ | 2FA有効化完了メッセージ | show_success_alert: true |

## イベント仕様

### 1-コードコピーボタン押下

**処理内容**：
1. JavaScriptで全リカバリーコードをクリップボードにコピー
2. コピー成功通知を表示

### 2-印刷ボタン押下

**処理内容**：
1. ブラウザの印刷ダイアログを表示
2. リカバリーコード部分を印刷用フォーマットで出力

### 3-ダウンロードボタン押下

**処理内容**：
1. リカバリーコードをテキストファイルとして生成
2. ファイルをダウンロード

### 4-「Proceed」ボタン押下

**処理内容**：
1. passkeysフラグが有効な場合：`/-/profile/two_factor_auth?two_factor_auth_enabled_successfully=true`へ遷移
2. passkeysフラグが無効な場合：`/-/profile/account?two_factor_auth_enabled_successfully=true`へ遷移

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

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

本画面は表示専用であり、データベース更新は発生しない。
（コード生成はcreateアクション内で事前に実行済み）

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし（表示のみ） | - | - | - |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| 成功 | You have set up 2FA for your account! | 常時表示（show_success_alert: true） |
| 警告 | 各コードは1回のみ使用可能 | 常時表示（UIテキスト） |
| 情報 | 安全な場所にコードを保管してください | 常時表示（UIテキスト） |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| @codesが空 | コード表示部分が空になる |
| 未認証アクセス | ログイン画面へリダイレクト |

## 備考

- 本画面は2FA初回有効化時のみ表示される
- codes.html.haml（再生成時）との違いはshow_success_alert: trueのみ
- _codes.html.hamlパーシャルがVue.jsコンポーネント（js-2fa-recovery-codes）をレンダリング
- リダイレクト先はpasskeysフィーチャーフラグで動的に決定
- リカバリーコードはJSON形式でdata属性に埋め込まれる

---

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

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

### 推奨読解順序

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

リカバリーコードの生成と格納の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb（otp関連） | `app/models/user.rb` | generate_otp_backup_codes!メソッド |

**読解のコツ**: リカバリーコードはUserモデルのotp_backup_codesカラムに暗号化して保存される。@codesには平文が一時的に格納される。

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

コントローラーの処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | two_factor_auths_controller.rb | `app/controllers/profiles/two_factor_auths_controller.rb` | createアクション |

**主要処理フロー**:
1. **24-52行目**: create - OTP登録処理
2. **39行目**: generate_otp_backup_codes!でコード生成
3. **49行目**: render :createでcreate.html.hamlをレンダリング

#### Step 3: ビューレイヤーを理解する

画面の構成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create.html.haml | `app/views/profiles/two_factor_auths/create.html.haml` | 2FA有効化完了画面 |
| 3-2 | _codes.html.haml | `app/views/profiles/two_factor_auths/_codes.html.haml` | コード表示パーシャル |

**主要処理フロー**:
- **create.html.haml 1行目**: ページタイトル設定
- **create.html.haml 5行目**: _codesパーシャルをshow_success_alert: trueで呼び出し
- **_codes.html.haml 2行目**: passkeysフラグに応じたリダイレクト先を決定
- **_codes.html.haml 4行目**: js-2fa-recovery-codesクラスでVue.jsコンポーネントをマウント

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

```
TwoFactorAuthsController#create
    │
    ├─ validate_current_password（before_action、条件付き）
    │
    ├─ Devise::OtpMethods::ValidateManualOtpService
    │        │
    │        └─ OTPコード検証
    │
    └─ [検証成功時]
           │
           ├─ user.otp_required_for_login = true
           │
           ├─ user.otp_secret = session[:otp_secret]
           │
           └─ user.generate_otp_backup_codes!
                  │
                  └─ @codes = 10個のランダムコード
                         │
                         ▼
                   render :create
                         │
                         └─ create.html.haml
                                  │
                                  └─ _codes.html.haml
                                           │
                                           └─ js-2fa-recovery-codes (Vue.js)
```

### データフロー図

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

POST /profile/two_factor_auth
(pin_code)
         │
         ▼
  ValidateManualOtpService
         │
         ├─ session[:otp_secret]と照合
         │
         └─ [成功]
                │
                ▼
         generate_otp_backup_codes!
                │
                ├─ 10個のランダムコード生成
                │
                ├─ usersテーブル更新
                │   ├─ otp_required_for_login = true
                │   └─ otp_backup_codes（暗号化）
                │
                └─ @codes（平文）
                         │
                         ▼
                  create.html.haml
                         │
                         └─ _codes.html.haml
                                  │
                                  ├─ @codes.to_json → data-codes属性
                                  │
                                  └─ redirect_path → data-redirect-path属性
                                           │
                                           ▼
                                    Vue.jsコンポーネント
                                           │
                                           └─ リカバリーコード表示UI
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| two_factor_auths_controller.rb | `app/controllers/profiles/two_factor_auths_controller.rb` | コントローラー | create処理でコード生成 |
| create.html.haml | `app/views/profiles/two_factor_auths/create.html.haml` | ビュー | 2FA有効化完了画面 |
| _codes.html.haml | `app/views/profiles/two_factor_auths/_codes.html.haml` | パーシャル | コード表示・Vue.jsマウント |
| profile_two_factor_auth.scss | `app/assets/stylesheets/page_bundles/profile_two_factor_auth.scss` | スタイル | 画面固有スタイル |
| profile.rb | `config/routes/profile.rb` | ルーティング | URLルーティング定義 |
