# 画面設計書 7-パスワードリセット要求画面

## 概要

本ドキュメントはInvenTreeシステムのパスワードリセット要求画面の設計仕様を記載する。パスワードを忘れたユーザーがリセットメールを要求するための画面である。

### 本画面の処理概要

パスワードリセット要求画面は、パスワードを忘れたユーザーがパスワードリセット用のメールを要求するための画面である。登録済みのメールアドレスを入力してリセットメールを送信し、メール内のリンクからパスワード再設定画面にアクセスできる。

**業務上の目的・背景**：ユーザーがパスワードを忘れた場合に、自己解決でパスワードをリセットできる機能を提供する。管理者の介入なしにパスワードを再設定できることで、サポート負荷を軽減し、ユーザーの利便性を向上させる。

**画面へのアクセス方法**：ログイン画面の「Reset password」リンクをクリックするか、ブラウザで `/reset-password` URLに直接アクセスする。

**主要な操作・処理内容**：
1. 登録済みメールアドレスの入力
2. 「Send Email」ボタン押下によるリセットメール送信要求
3. メール送信成功後、ログイン画面へ遷移

**画面遷移**：
- 遷移元：ログイン画面（Reset passwordリンク経由）
- 遷移先：ログイン画面（メール送信後）

**権限による表示制御**：
- 未認証ユーザーがアクセス可能
- サーバー設定によりパスワードリセット機能の有効/無効が制御される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | 認証・ログイン | 主機能 | メールアドレス入力、リセットメール送信要求処理 |

## 画面種別

入力画面

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/reset-password` | パスワードリセット要求画面 |

## 入出力項目

### 入力項目

| No | 項目名 | 項目ID | 必須 | 型 | 最大長 | 説明 |
|----|--------|--------|------|-----|--------|------|
| 1 | メールアドレス | email | Yes | メール | - | 登録済みのメールアドレス |

### 出力項目

なし

## 表示項目

| No | 項目名 | 表示条件 | 説明 |
|----|--------|----------|------|
| 1 | 画面タイトル | 常時 | "Reset Password" |
| 2 | メールアドレス入力欄 | 常時 | メール入力フィールド |
| 3 | 説明文 | 常時 | "We will send you a link to login - if you are registered" |
| 4 | プレースホルダー | 常時 | "email@example.org" |
| 5 | Send Emailボタン | 常時 | リセットメール送信ボタン |

## イベント仕様

### 1-Send Emailボタン押下

パスワードリセット用メールの送信を要求する。

**処理フロー**：
1. `handleReset`関数を呼び出し
2. CSRFトークンの確認・取得（`ensureCsrf`）
3. `POST /api/auth/v1/auth/password/request` APIを呼び出し
4. 成功時（200レスポンス）：
   - 「Mail delivery successful / Check your inbox for a reset link...」通知を表示
   - ログイン画面へ遷移
5. 失敗時：
   - 「Reset failed / Check your input and try again.」エラー通知を表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| リセットメール送信成功 | password_reset_tokens | INSERT | リセットトークンの作成 |

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

#### password_reset_tokens

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id | メールアドレスに対応するユーザーID | 外部キー |
| INSERT | token | ランダム生成されたトークン | 一意 |
| INSERT | created_at | 現在日時 | 作成日時 |
| INSERT | expires_at | 作成日時 + 有効期間 | 有効期限 |

## メッセージ仕様

| No | メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|-------------|---------------|---------------|----------|
| 1 | mail-success | 成功 | Mail delivery successful / Check your inbox for a reset link. This only works if you have an account. Check in spam too. | メール送信成功時 |
| 2 | reset-failed | エラー | Reset failed / Check your input and try again. | メール送信失敗時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|----------|----------|
| 1 | メールアドレス未登録 | セキュリティ上、成功と同様のメッセージを表示（実際にはメール未送信） |
| 2 | メール送信失敗 | エラー通知を表示 |
| 3 | API呼び出し失敗 | エラー通知を表示 |

## 備考

- セキュリティ上、メールアドレスが登録されているかどうかに関わらず、同じ成功メッセージを表示する
- 通知は自動的に閉じない（autoClose: false）
- リセットリンクには有効期限がある（バックエンド設定による）
- スパムフォルダの確認を促すメッセージが含まれる

---

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

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

### 推奨読解順序

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

パスワードリセット要求に関連するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | `user_reset`エンドポイント（行24） |

**読解のコツ**: リセットリクエストAPIはemailをパラメータとして受け取ることを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Reset.tsx | `src/frontend/src/pages/Auth/Reset.tsx` | パスワードリセット要求画面のメインコンポーネント |

**主要処理フロー**:
1. **行9-11**: フォーム状態の初期化（email）とナビゲート取得
2. **行13-29**: JSX描画（Wrapper、メール入力、Send Emailボタン）

#### Step 3: リセット要求処理関数を理解する

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

**主要処理フロー**:
- **行333-355**: `handleReset`関数
  - 行337: CSRFトークンの確認
  - 行338: POST user_resetエンドポイント呼び出し
  - 行339-347: 成功時の通知表示とリダイレクト
  - 行348-353: 失敗時のエラー通知

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

```
Reset.tsx (エントリーポイント)
    │
    ├─ useForm() (email)
    │
    ├─ useNavigate()
    │
    ├─ Wrapper (titleText="Reset Password")
    │      │
    │      ├─ TextInput (email)
    │      │      ├─ label: "Email"
    │      │      ├─ description: "We will send you a link..."
    │      │      └─ placeholder: "email@example.org"
    │      │
    │      └─ Button (Send Email)
    │             └─ handleReset(navigate, simpleForm.values)
    │                    ├─ ensureCsrf()
    │                    ├─ POST auth/v1/auth/password/request
    │                    ├─ 成功: 通知表示 + navigate('/login')
    │                    └─ 失敗: エラー通知
    │
    └─ Layout.tsx (Wrapper)
```

### データフロー図

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

メールアドレス ─────────▶ handleReset()
                            │
                            ├─ ensureCsrf()
                            │
                            ├─ POST auth/v1/auth/password/request
                            │
                            ├─ 成功時 (200)
                            │      ├─ notifications.show ────────▶ 成功通知
                            │      └─ navigate('/login') ────────▶ ログイン画面へ遷移
                            │
                            └─ 失敗時
                                   └─ notifications.show ────────▶ エラー通知

                                                                   [バックエンド]
                                                                        │
                                                                        ▼
                                                               リセットメール送信
                                                               （登録済みの場合）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Reset.tsx | `src/frontend/src/pages/Auth/Reset.tsx` | ソース | パスワードリセット要求画面メインコンポーネント |
| auth.tsx | `src/frontend/src/functions/auth.tsx` | ソース | リセット要求関数（handleReset） |
| 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` | ソース | ルーティング定義 |
