# 画面設計書 1-ログイン画面

## 概要

本ドキュメントはInvenTreeシステムのログイン画面の設計仕様を記載する。ユーザー認証の入口となる重要な画面である。

### 本画面の処理概要

ログイン画面は、ユーザーがInvenTreeシステムにアクセスするための認証入口となる画面である。ユーザー名とパスワードによる標準的なログイン、SSO（シングルサインオン）による外部認証プロバイダーを使用したログイン、およびメールリンクによる簡易ログインの3つの認証方式をサポートする。

**業務上の目的・背景**：在庫管理システムへのアクセスを認証されたユーザーのみに制限し、セキュリティを確保する。複数の認証方式を提供することで、企業の既存の認証インフラストラクチャとの統合や、ユーザーの利便性向上を実現する。MFA（多要素認証）が有効な場合は、追加の認証ステップへ遷移させることでセキュリティを強化する。

**画面へのアクセス方法**：ブラウザで `/login` URLに直接アクセスするか、未認証状態でシステムにアクセスした際に自動的にリダイレクトされる。ログアウト後も本画面に遷移する。

**主要な操作・処理内容**：
1. ホスト選択：複数のInvenTreeサーバーから接続先を選択
2. ユーザー名・パスワード入力とログインボタン押下による認証
3. SSOプロバイダー選択によるシングルサインオン認証
4. メールアドレス入力によるマジックリンク認証
5. パスワードリセット画面への遷移
6. 新規ユーザー登録画面への遷移

**画面遷移**：
- 遷移元：ログアウト画面、パスワード再設定完了時、メール確認完了時、未認証状態でのアクセス時
- 遷移先：ホーム画面（認証成功時）、MFA認証画面（MFA必要時）、MFA設定画面（MFA登録必要時）、新規登録画面、パスワードリセット要求画面

**権限による表示制御**：
- サーバー設定によりSSO認証ボタンの表示/非表示が制御される
- サーバー設定により新規登録リンクの表示/非表示が制御される
- サーバー設定によりパスワードリセットリンクの表示/非表示が制御される
- サーバーのカスタムログインメッセージが設定されている場合は表示される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | 認証・ログイン | 主機能 | ユーザー名・パスワード入力、ログイン実行、SSOログインの主処理 |
| 32 | ユーザーアカウント管理 | API連携 | ホスト選択、セッション管理のAPI呼び出し |

## 画面種別

認証画面

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/login` | ログイン画面 |

## 入出力項目

### 入力項目

| No | 項目名 | 項目ID | 必須 | 型 | 最大長 | 説明 |
|----|--------|--------|------|-----|--------|------|
| 1 | ユーザー名 | username | Yes | テキスト | - | ログイン用ユーザー名 |
| 2 | パスワード | password | Yes | パスワード | - | ログイン用パスワード |
| 3 | TOTPコード | code | No | テキスト | - | 自動入力用MFAコード（非表示） |
| 4 | メールアドレス | email | Yes（簡易ログイン時） | メール | - | マジックリンク送信先 |

### 出力項目

| No | 項目名 | 説明 |
|----|--------|------|
| 1 | ログインメッセージ | サーバー設定のカスタムログインメッセージ（HTML形式） |
| 2 | ホスト名 | 現在選択中のサーバーホスト名 |

## 表示項目

| No | 項目名 | 表示条件 | 説明 |
|----|--------|----------|------|
| 1 | 画面タイトル | 常時 | "Login" |
| 2 | SSOプロバイダーボタン | SSO有効時 | 各プロバイダーのログインボタン |
| 3 | ユーザー名入力欄 | 標準ログインモード時 | テキスト入力フィールド |
| 4 | パスワード入力欄 | 標準ログインモード時 | パスワード入力フィールド |
| 5 | メール入力欄 | 簡易ログインモード時 | メールアドレス入力フィールド |
| 6 | ログインモード切替リンク | 常時 | 標準/簡易モードの切り替え |
| 7 | パスワードリセットリンク | パスワードリセット有効時 | Reset password リンク |
| 8 | 新規登録リンク | 新規登録有効時 | Register リンク |
| 9 | ログインボタン | 常時 | Log In / Send Email ボタン |
| 10 | ホスト設定オプション | 常時 | ホスト選択・編集エリア |
| 11 | ローディングインジケーター | ログイン処理中 | スピナー表示 |

## イベント仕様

### 1-ログインボタン押下（標準モード）

ユーザー名とパスワードを使用してログイン処理を実行する。

**処理フロー**：
1. ユーザー名とパスワードが入力されているか検証
2. CSRFトークンの確認・取得（`ensureCsrf`）
3. `POST /api/auth/v1/auth/login` APIを呼び出し
4. 認証成功時：ユーザー状態を取得し、ホーム画面へ遷移
5. MFA必要時（401レスポンス）：MFA認証画面へ遷移
6. セッション競合時（409レスポンス）：ログアウト処理を実行
7. 認証失敗時：エラー通知を表示

### 2-ログインボタン押下（簡易モード）

メールアドレスを使用してマジックリンクを送信する。

**処理フロー**：
1. メールアドレスを入力されているか検証
2. `POST /api/email/generate/` APIを呼び出し
3. 成功時：メール送信成功通知を表示
4. 失敗時：エラー通知を表示

### 3-SSOボタン押下

外部認証プロバイダーを使用してログインする。

**処理フロー**：
1. CSRFトークンを取得
2. `POST /api/auth/v1/auth/provider/redirect` へフォームサブミット
3. 外部プロバイダーの認証画面へリダイレクト
4. 認証後、`/logged-in` へコールバック

### 4-パスワードリセットリンク押下

パスワードリセット要求画面へ遷移する。

**処理フロー**：
1. `/reset-password` へナビゲート

### 5-新規登録リンク押下

新規ユーザー登録画面へ遷移する。

**処理フロー**：
1. `/register` へナビゲート

### 6-ホスト設定ボタン押下

ホスト選択・編集画面を表示する。

**処理フロー**：
1. `InstanceOptions` コンポーネントを表示
2. ホスト選択後、APIデフォルトを更新
3. サーバーAPI状態を再取得

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ログイン成功 | auth_session | INSERT/UPDATE | セッション情報の作成・更新 |
| ログイン成功 | user_profile | SELECT | ユーザープロファイル情報の取得 |

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

#### auth_session

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | session_key | 新規セッションキー | Django認証システムにより自動生成 |
| INSERT/UPDATE | user_id | 認証されたユーザーID | 外部キー |
| INSERT/UPDATE | expire_date | セッション有効期限 | サーバー設定に基づく |

## メッセージ仕様

| No | メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|-------------|---------------|---------------|----------|
| 1 | login-success | 成功 | Login successful / Logged in successfully | ログイン成功時 |
| 2 | login-failed | エラー | Login failed / Check your input and try again. | 認証失敗時 |
| 3 | login-failed-no-response | エラー | Login failed / No response from server. | サーバー無応答時 |
| 4 | session-conflict | エラー | Logged Out / There was a conflicting session... | セッション競合時（409） |
| 5 | mail-success | 成功 | Mail delivery successful / Check your inbox... | メールリンク送信成功時 |
| 6 | mail-failed | エラー | Mail delivery failed / Check your input... | メールリンク送信失敗時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|----------|----------|
| 1 | サーバー無応答 | "No response from server" エラー通知を表示 |
| 2 | セッション競合（409） | 既存セッションをログアウトし、エラー通知を表示 |
| 3 | 認証失敗（401、MFA以外） | エラー通知を表示、ユーザー状態をクリア |
| 4 | MFA必要（401、MFA） | MFA認証画面（/mfa）へ遷移 |
| 5 | MFA設定必要 | MFA設定画面（/mfa-setup）へ遷移 |

## 備考

- URLパラメータに `login` と `password` が含まれる場合、自動ログインが試行される
- ログイン成功後、ユーザープロファイルの言語・テーマ設定がローカル設定に反映される
- ホストリストが空の場合、デフォルトホスト（localhost）が自動選択される
- サーバーのカスタムログインメッセージはHTMLとして描画される（dangerouslySetInnerHTML使用）

---

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

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

### 推奨読解順序

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

まず、認証に関連する状態管理とデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | UserState.tsx | `src/frontend/src/states/UserState.tsx` | ユーザー認証状態の管理、`isLoggedIn`, `setAuthenticated`等の状態管理関数 |
| 1-2 | LocalState.tsx | `src/frontend/src/states/LocalState.tsx` | ホスト選択、言語・テーマ等のローカル設定管理 |
| 1-3 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | 認証関連APIエンドポイント定義（auth_login, auth_session等） |

**読解のコツ**: Zustandによる状態管理パターンを理解することが重要。`create`関数で定義されたストアの構造と、各メソッドの役割を把握する。

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

処理の起点となるログイン画面コンポーネントを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Login.tsx | `src/frontend/src/pages/Auth/Login.tsx` | メイン画面コンポーネント、ホスト選択ロジック、自動ログイン処理 |

**主要処理フロー**:
1. **行23-42**: 状態管理フックの初期化（hostKey, server, isLoggingIn等）
2. **行62-67**: `ChangeHost`関数でホスト変更時のAPI再設定
3. **行70-88**: `useEffect`で初期化処理（デフォルトホスト設定、ログイン状態チェック、URLパラメータ自動ログイン）
4. **行90-133**: JSX描画（ホスト編集モード/ログインフォーム切り替え）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AuthenticationForm.tsx | `src/frontend/src/components/forms/AuthenticationForm.tsx` | ログインフォームの入力処理、標準/簡易モード切替 |

**主要処理フロー**:
- **行37-56**: フォーム状態と認証設定の初期化
- **行57-112**: `handleLogin`関数で認証処理を実行（doBasicLogin/doSimpleLogin呼び出し）
- **行114-211**: JSX描画（SSOボタン、入力フィールド、送信ボタン）

#### Step 4: 認証処理関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | auth.tsx | `src/frontend/src/functions/auth.tsx` | 認証API呼び出し、セッション管理、MFA処理 |

**主要処理フロー**:
- **行70-199**: `doBasicLogin`関数 - ユーザー名/パスワード認証の主処理
- **行206-225**: `doLogout`関数 - ログアウト処理
- **行227-245**: `doSimpleLogin`関数 - メールリンク認証
- **行415-463**: `checkLoginState`関数 - ログイン状態の確認とリダイレクト

#### Step 5: レイアウトコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | 認証画面共通レイアウト、Wrapperコンポーネント |

**主要処理フロー**:
- **行17-27**: `LoginLayoutComponent` - SplashScreen内にOutletを配置
- **行29-66**: `Wrapper` - 認証画面の共通ラッパー（タイトル、ローダー、ログオフボタン）

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

```
Login.tsx (エントリーポイント)
    │
    ├─ useLocalState (hostKey, setHost, hostList)
    │      └─ LocalState.tsx (Zustand Store)
    │
    ├─ useServerApiState (server, fetchServerApiState)
    │      └─ ServerApiState.tsx
    │
    ├─ checkLoginState()
    │      └─ auth.tsx
    │            ├─ fetchUserState()
    │            │      └─ UserState.tsx
    │            └─ fetchGlobalStates()
    │
    ├─ InstanceOptions (ホスト編集モード)
    │
    ├─ AuthenticationForm
    │      ├─ handleLogin()
    │      │      ├─ doBasicLogin()
    │      │      │      └─ POST /api/auth/v1/auth/login
    │      │      └─ doSimpleLogin()
    │      │             └─ POST /api/email/generate/
    │      │
    │      └─ SsoButton
    │             └─ ProviderLogin()
    │                    └─ POST /api/auth/v1/auth/provider/redirect
    │
    └─ AuthFormOptions (ホスト名表示、設定トグル)
```

### データフロー図

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

ユーザー名/パスワード ───▶ doBasicLogin() ───▶ セッション確立
                              │                     │
                              ├─ POST auth/login ───┤
                              │                     │
                              ├─ MFA必要時 ─────────▶ /mfa へ遷移
                              │                     │
                              └─ 成功時 ────────────▶ /home へ遷移

メールアドレス ─────────▶ doSimpleLogin() ───▶ メール送信
                              │
                              └─ POST email/generate

ホスト選択 ─────────────▶ setHost() ─────────▶ API設定更新
                              │
                              └─ fetchServerApiState()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Login.tsx | `src/frontend/src/pages/Auth/Login.tsx` | ソース | ログイン画面メインコンポーネント |
| AuthenticationForm.tsx | `src/frontend/src/components/forms/AuthenticationForm.tsx` | ソース | ログインフォームコンポーネント |
| auth.tsx | `src/frontend/src/functions/auth.tsx` | ソース | 認証処理関数群 |
| Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | ソース | 認証画面レイアウト |
| UserState.tsx | `src/frontend/src/states/UserState.tsx` | ソース | ユーザー状態管理 |
| LocalState.tsx | `src/frontend/src/states/LocalState.tsx` | ソース | ローカル設定状態管理 |
| ServerApiState.tsx | `src/frontend/src/states/ServerApiState.tsx` | ソース | サーバーAPI状態管理 |
| ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | ソース | APIエンドポイント定義 |
| router.tsx | `src/frontend/src/router.tsx` | ソース | ルーティング定義 |
| InstanceOptions.tsx | `src/frontend/src/components/forms/InstanceOptions.tsx` | ソース | ホスト選択コンポーネント |
| SSOButton.tsx | `src/frontend/src/components/buttons/SSOButton.tsx` | ソース | SSOログインボタン |
