# 画面設計書 8-パスワード再設定画面

## 概要

本ドキュメントはInvenTreeシステムのパスワード再設定画面の設計仕様を記載する。リセットメールのリンクから新しいパスワードを設定するための画面である。

### 本画面の処理概要

パスワード再設定画面は、パスワードリセットメールに含まれるリンクからアクセスし、新しいパスワードを設定するための画面である。メール内のリンクに含まれるリセットキーを使用して認証し、新しいパスワードを入力して設定を完了する。

**業務上の目的・背景**：パスワードリセット要求後、ユーザーが実際に新しいパスワードを設定するための画面を提供する。リセットキーによる認証により、メールアドレスの所有権を確認した上でパスワード変更を許可する。

**画面へのアクセス方法**：パスワードリセットメールに含まれるリンク（`/set-password?key=...`）をクリックしてアクセスする。直接URLにアクセスする場合はkeyパラメータが必要。

**主要な操作・処理内容**：
1. 新しいパスワードの入力
2. 「Send Password」ボタン押下によるパスワード設定
3. 設定完了後、ログイン画面へ遷移

**画面遷移**：
- 遷移元：パスワードリセットメール内のリンク
- 遷移先：ログイン画面（パスワード設定成功後）

**権限による表示制御**：
- 有効なリセットキーが必要
- キーが無効または未指定の場合はエラー通知を表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | 認証・ログイン | 主機能 | 新パスワードの設定・確認処理 |

## 画面種別

設定画面

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/set-password` | パスワード再設定画面 |

### URLパラメータ

| パラメータ名 | 必須 | 説明 |
|-------------|------|------|
| key | Yes | パスワードリセットトークン |

## 入出力項目

### 入力項目

| No | 項目名 | 項目ID | 必須 | 型 | 最大長 | 説明 |
|----|--------|--------|------|-----|--------|------|
| 1 | 新しいパスワード | password | Yes | パスワード | - | 設定する新しいパスワード |

### 出力項目

なし

## 表示項目

| No | 項目名 | 表示条件 | 説明 |
|----|--------|----------|------|
| 1 | 画面タイトル | 常時 | "Set new password" |
| 2 | パスワード入力欄 | 常時 | パスワード入力フィールド |
| 3 | 説明文 | 常時 | "The desired new password" |
| 4 | Send Passwordボタン | 常時 | パスワード設定ボタン |
| 5 | エラー通知 | キー無効時 | キーが無効であることを示すエラー |

## イベント仕様

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

リセットキーの存在を確認する。

**処理フロー**：
1. URLSearchParamsからkeyパラメータを取得
2. keyが存在しない場合：
   - 「Key invalid / You need to provide a valid key...」エラー通知を表示（autoClose: false）

### 2-Send Passwordボタン押下

新しいパスワードを設定する。

**処理フロー**：
1. `handlePasswordReset`関数を呼び出し
2. `POST /api/auth/v1/auth/password/reset` APIを呼び出し（key, passwordパラメータ付き）
3. 成功時（200または401レスポンス）：
   - 「Password set / The password was set successfully...」通知を表示
   - ログイン画面へ遷移
4. 失敗時（400エラー）：
   - 「Reset failed / {エラー詳細}」エラー通知を表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| パスワード設定成功 | auth_user | UPDATE | パスワードハッシュの更新 |
| パスワード設定成功 | password_reset_tokens | DELETE | 使用済みトークンの削除 |

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

#### auth_user

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | password | 新しいパスワードのハッシュ値 | Djangoハッシュ化 |

#### password_reset_tokens

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | token = 使用されたリセットキー | 1回限りの使用 |

## メッセージ仕様

| No | メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|-------------|---------------|---------------|----------|
| 1 | key-invalid | エラー | Key invalid / You need to provide a valid key to set a new password. Check your inbox for a reset link. | キー未指定時 |
| 2 | password-set | 成功 | Password set / The password was set successfully. You can now login with your new password | パスワード設定成功時 |
| 3 | reset-failed | エラー | Reset failed / {エラー詳細} | パスワード設定失敗時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|----------|----------|
| 1 | キー未指定 | エラー通知を表示（autoClose: false） |
| 2 | キー期限切れ/無効 | エラー通知を表示 |
| 3 | パスワードポリシー違反（400） | エラー詳細を通知として表示 |
| 4 | 401レスポンス | 成功として扱い、ログイン画面へ遷移 |

## 備考

- 401レスポンスはパスワード設定成功を示す（セッションが作成されないため）
- リセットキーは1回限りの使用
- 通知は自動的に閉じない（autoClose: false）
- Authorizationヘッダーを空に設定してAPIを呼び出す

---

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

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

### 推奨読解順序

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

パスワード再設定に関連するデータ構造を理解する。

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

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

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

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

**主要処理フロー**:
1. **行12-16**: フォーム状態、URLパラメータ、ナビゲートの初期化
2. **行18-28**: キー存在確認（useEffect）
3. **行30-47**: JSX描画（Wrapper、パスワード入力、Send Passwordボタン）

#### Step 3: パスワード再設定処理関数を理解する

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

**主要処理フロー**:
- **行596-645**: `handlePasswordReset`関数
  - 行601-608: `success`ヘルパー関数（成功通知とリダイレクト）
  - 行611-617: `passwordError`ヘルパー関数（エラー通知）
  - 行619-644: パスワード設定API呼び出しと結果処理

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

```
ResetPassword.tsx (エントリーポイント)
    │
    ├─ useForm() (password)
    │
    ├─ useSearchParams() → key取得
    │
    ├─ useNavigate()
    │
    ├─ useEffect() [キー確認]
    │      └─ keyがない場合: notifications.show (エラー)
    │
    ├─ Wrapper (titleText="Set new password")
    │      │
    │      ├─ PasswordInput (password)
    │      │      └─ description: "The desired new password"
    │      │
    │      └─ Button (Send Password)
    │             └─ handlePasswordReset(key, password, navigate)
    │                    ├─ POST auth/v1/auth/password/reset
    │                    │      └─ headers: { Authorization: '' }
    │                    │
    │                    ├─ 成功 (200): success()
    │                    │      ├─ notifications.show
    │                    │      └─ navigate('/login')
    │                    │
    │                    ├─ 400: passwordError()
    │                    │      └─ notifications.show (エラー)
    │                    │
    │                    └─ 401: success() [成功として扱う]
    │
    └─ Layout.tsx (Wrapper)
```

### データフロー図

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

URLパラメータ (key) ────▶ useEffect()
                            │
                            └─ keyがない場合 ─────────────────▶ エラー通知

password ───────────────▶ handlePasswordReset()
key ────────────────────▶      │
                               ├─ POST auth/v1/auth/password/reset
                               │      └─ { key, password }
                               │
                               ├─ 成功時 (200, 401)
                               │      ├─ notifications.show ────▶ 成功通知
                               │      └─ navigate('/login') ────▶ ログイン画面へ遷移
                               │
                               └─ 失敗時 (400)
                                      └─ notifications.show ────▶ エラー通知

                                                                 [バックエンド]
                                                                      │
                                                                      ▼
                                                              パスワード更新
                                                              トークン無効化
```

### 関連ファイル一覧

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