# 画面設計書 6-パスワード変更画面

## 概要

本ドキュメントはInvenTreeシステムのパスワード変更画面の設計仕様を記載する。ログイン済みユーザーがパスワードを変更するための画面である。

### 本画面の処理概要

パスワード変更画面は、認証済みユーザーが自身のパスワードを変更するための画面である。現在のパスワードを確認した上で、新しいパスワードを設定する。セキュリティ上の理由から、パスワード変更後は自動的にログアウトされ、新しいパスワードでの再ログインが必要となる。

**業務上の目的・背景**：ユーザーが定期的なパスワード変更や、セキュリティ上の懸念がある場合にパスワードを変更できる機能を提供する。現在のパスワードを入力させることで、認証済みセッションが不正に利用された場合のパスワード変更を防止する。

**画面へのアクセス方法**：ブラウザで `/change-password` URLに直接アクセスする。通常はユーザー設定画面のセキュリティセクションからリンクされる。

**主要な操作・処理内容**：
1. 現在のパスワードの入力
2. 新しいパスワードの入力
3. 新しいパスワードの確認入力
4. 「Confirm」ボタン押下によるパスワード変更の実行
5. パスワード変更後の自動ログアウトと再ログイン

**画面遷移**：
- 遷移元：ユーザー設定画面、URLの直接入力
- 遷移先：ログイン画面（パスワード変更成功後）

**権限による表示制御**：
- ログイン済みユーザーのみアクセス可能
- 現在ログイン中のユーザー名が画面上に表示される

## 関連機能

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

## 画面種別

設定画面

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/change-password` | パスワード変更画面 |

## 入出力項目

### 入力項目

| No | 項目名 | 項目ID | 必須 | 型 | 最大長 | 説明 |
|----|--------|--------|------|-----|--------|------|
| 1 | 現在のパスワード | current_password | Yes | パスワード | - | 現在使用中のパスワード |
| 2 | 新しいパスワード | new_password1 | Yes | パスワード | - | 設定する新しいパスワード |
| 3 | 新しいパスワード（確認） | new_password2 | Yes | パスワード | - | 新しいパスワードの確認入力 |

### 出力項目

| No | 項目名 | 説明 |
|----|--------|------|
| 1 | ユーザー名 | 現在ログイン中のユーザー名 |

## 表示項目

| No | 項目名 | 表示条件 | 説明 |
|----|--------|----------|------|
| 1 | 画面タイトル | 常時 | "Reset Password" |
| 2 | ユーザー名表示 | ユーザー名存在時 | "User: {ユーザー名}" |
| 3 | 現在のパスワード入力欄 | 常時 | パスワード入力フィールド |
| 4 | 新しいパスワード入力欄 | 常時 | パスワード入力フィールド |
| 5 | 新しいパスワード確認入力欄 | 常時 | パスワード入力フィールド |
| 6 | Confirmボタン | 常時（ただし入力不足時は無効化） | パスワード変更実行ボタン |

## イベント仕様

### 1-Confirmボタン押下

パスワード変更処理を実行する。

**処理フロー**：
1. `handleChangePassword`関数を呼び出し
2. 新しいパスワード（new_password1）と確認（new_password2）が一致するか検証
3. 不一致の場合：「The two password fields didn't match」エラーを表示して処理中断
4. 一致の場合：`POST /api/auth/v1/account/password/change` APIを呼び出し
5. 成功時（401レスポンス）：
   - 「Password Changed / The password was set successfully...」通知を表示
   - ユーザー状態をクリア
   - CSRFクッキーを削除
   - ログイン画面へ遷移
6. 失敗時：
   - エラー内容を通知として表示
   - 各フィールドのエラーを個別に表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| パスワード変更成功 | auth_user | UPDATE | パスワードハッシュの更新 |
| パスワード変更成功 | auth_session | DELETE | 既存セッションの無効化 |

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

#### auth_user

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | password | 新しいパスワードのハッシュ値 | Djangoハッシュ化 |
| UPDATE | password_changed_at | 現在日時 | 変更日時の記録（存在する場合） |

## メッセージ仕様

| No | メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|-------------|---------------|---------------|----------|
| 1 | password-changed | 成功 | Password Changed / The password was set successfully. You can now login with your new password | パスワード変更成功時 |
| 2 | password-mismatch | エラー | Error / The two password fields didn't match | パスワード不一致時 |
| 3 | password-error | エラー | Error / {エラー詳細} | バリデーションエラー時 |
| 4 | password-generic-error | エラー | Password could not be changed | 不明なエラー時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|----------|----------|
| 1 | パスワード不一致 | 「The two password fields didn't match」エラーを表示 |
| 2 | 現在のパスワードが不正 | current_passwordフィールドにエラーを表示 |
| 3 | 新しいパスワードがポリシー違反 | new_password1/new_password2フィールドにエラーを表示 |
| 4 | 401レスポンス | 成功として扱い、ログアウト処理を実行 |

## 備考

- 401レスポンスはパスワード変更成功を示す（セッションが無効化されるため）
- Confirmボタンは現在のパスワードと新しいパスワードの両方が入力されていないと無効化
- パスワード変更後は必ず再ログインが必要
- 画面タイトルは「Reset Password」となっているが、機能としては「Change Password」

---

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

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

### 推奨読解順序

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

パスワード変更に関連するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | `auth_pwd_change`エンドポイント（行26） |
| 1-2 | UserState.tsx | `src/frontend/src/states/UserState.tsx` | `username()`, `clearUserState()`関数 |

**読解のコツ**: パスワード変更後にユーザー状態がクリアされ、再ログインが必要になることを理解する。

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

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

**主要処理フロー**:
1. **行19-26**: フォーム状態の初期化（current_password, new_password1, new_password2）
2. **行28-29**: ユーザー状態とナビゲートの取得
3. **行31-83**: JSX描画（ユーザー名表示、入力フィールド、Confirmボタン）

#### Step 3: パスワード変更処理関数を理解する

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

**主要処理フロー**:
- **行663-732**: `handleChangePassword`関数
  - 行669-691: `passwordError`ヘルパー関数（エラー通知表示）
  - 行694-698: パスワード一致検証
  - 行700-731: パスワード変更API呼び出しと結果処理

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

```
ChangePassword.tsx (エントリーポイント)
    │
    ├─ useForm() (current_password, new_password1, new_password2)
    │
    ├─ useUserState() (username)
    │
    ├─ useNavigate()
    │
    ├─ Wrapper (titleText="Reset Password")
    │      │
    │      ├─ Paper (ユーザー名表示)
    │      │      └─ user.username()
    │      │
    │      ├─ PasswordInput (current_password)
    │      │
    │      ├─ PasswordInput (new_password1)
    │      │
    │      ├─ PasswordInput (new_password2)
    │      │
    │      └─ Button (Confirm)
    │             └─ handleChangePassword()
    │                    ├─ パスワード一致検証
    │                    ├─ POST auth/v1/account/password/change
    │                    ├─ clearUserState() [成功時]
    │                    ├─ clearCsrfCookie() [成功時]
    │                    └─ navigate('/login') [成功時]
    │
    └─ Layout.tsx (Wrapper)
```

### データフロー図

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

current_password ───────▶ handleChangePassword()
new_password1 ──────────▶      │
new_password2 ──────────▶      │
                               ├─ パスワード一致検証
                               │      └─ 不一致 ─────────────────▶ エラー通知
                               │
                               ├─ POST auth/v1/account/password/change
                               │
                               ├─ 成功時 (401)
                               │      ├─ showNotification ───────▶ 成功通知
                               │      ├─ clearUserState() ───────▶ ユーザー状態クリア
                               │      ├─ clearCsrfCookie() ──────▶ クッキー削除
                               │      └─ navigate('/login') ─────▶ ログイン画面へ遷移
                               │
                               └─ 失敗時
                                      └─ showNotification ───────▶ エラー通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ChangePassword.tsx | `src/frontend/src/pages/Auth/ChangePassword.tsx` | ソース | パスワード変更画面メインコンポーネント |
| auth.tsx | `src/frontend/src/functions/auth.tsx` | ソース | パスワード変更関数（handleChangePassword） |
| Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | ソース | 認証画面レイアウト |
| UserState.tsx | `src/frontend/src/states/UserState.tsx` | ソース | ユーザー状態管理 |
| ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | ソース | APIエンドポイント定義 |
| router.tsx | `src/frontend/src/router.tsx` | ソース | ルーティング定義 |
