# 画面設計書 6-管理者ログイン画面

## 概要

本ドキュメントは、Etherpad Liteの管理者ログイン画面の設計内容を記述するものである。この画面は、管理画面（/admin）へアクセスするための認証画面であり、ユーザー名とパスワードによるBasic認証を行う。

### 本画面の処理概要

**業務上の目的・背景**：Etherpadの管理機能（プラグイン管理、設定編集、パッド管理等）は、システム管理者のみがアクセスすべき機能である。本画面は不正アクセスを防止し、正当な管理者のみが管理機能を利用できるようにするゲートキーパーとして機能する。settings.jsonで設定された管理者認証情報と照合することで認証を行う。

**画面へのアクセス方法**：ブラウザで `/admin` または `/admin/login` にアクセスすると本画面が表示される。認証情報がない場合や認証が必要な場合にリダイレクトされる。

**主要な操作・処理内容**：
1. ユーザー名（Username）の入力
2. パスワード（Password）の入力
3. パスワードの表示/非表示切り替え（目のアイコン）
4. ログインボタン押下による認証リクエスト送信
5. 認証成功時はプラグイン管理画面へリダイレクト
6. 認証失敗時はトースト通知でエラー表示

**画面遷移**：
- 遷移元: 直接URL入力、未認証状態での管理画面アクセス
- 遷移先: プラグイン管理画面（/admin/plugins）

**権限による表示制御**：本画面自体は認証前に表示されるため、権限による表示制御は行われない。認証成功後のみ管理画面へのアクセスが許可される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | ログイン認証 | 主機能 | 管理者のユーザー名とパスワードでBasic認証を実行 |

## 画面種別

認証 / ログイン

## URL/ルーティング

- **URL**: `/admin/login`
- **HTTPメソッド**: GET（画面表示）
- **認証エンドポイント**: POST `/admin-auth/`
- **コンポーネント**: `admin/src/pages/LoginScreen.tsx`

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|----------|---------|------|--------|------|
| ユーザー名 | username | 入力 | テキスト | 必須 | - | 管理者ユーザー名 |
| パスワード | password | 入力 | パスワード | 必須 | - | 管理者パスワード |

## 表示項目

| 項目名 | 項目ID | 説明 |
|--------|--------|------|
| ログインタイトル | login-title | 「Etherpad」固定 |
| ユーザー名ラベル | - | 「Username」 |
| ユーザー名入力欄 | - | react-hook-formで管理 |
| パスワードラベル | - | 「Password」 |
| パスワード入力欄 | - | react-hook-formで管理 |
| パスワード表示アイコン | - | Eye/EyeOffアイコン切り替え |
| ログインボタン | - | 「Login」ボタン |

## イベント仕様

### 1-ログインボタン押下

ユーザー名とパスワードを入力し、ログインボタンを押下すると、react-hook-formによるフォームバリデーション後、`/admin-auth/` エンドポイントへBasic認証ヘッダー付きでPOSTリクエストが送信される。

- **リクエストヘッダー**: `Authorization: Basic {base64(username:password)}`
- **認証成功時（200）**: `navigate('/')` により管理画面トップ（プラグイン管理画面）へリダイレクト
- **認証失敗時**: トースト通知で「Login failed」エラーを表示

### 2-パスワード表示切り替え

パスワード入力欄の右側にあるアイコン（Eye/EyeOff）をクリックすると、パスワードの表示/非表示が切り替わる。Lucide Reactアイコンを使用。

### 3-フォームバリデーション

react-hook-formにより、ユーザー名とパスワードの両フィールドに`required: true`が設定されており、空欄での送信は防止される。

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

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

本画面はセッションベースの認証を行うが、Etherpadのメインデータベースへの永続化は行わない。認証情報はsettings.jsonから読み込まれる。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ログイン成功 | - | - | セッションに認証状態を記録（メモリ/Cookie） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| - | タイトル | Etherpad | ログインフォームタイトル |
| - | ラベル | Username | ユーザー名ラベル |
| - | ラベル | Password | パスワードラベル |
| - | ボタン | Login | ログインボタン |
| - | エラー | Login failed | 認証失敗時（トースト通知） |

## 例外処理

| 例外状態 | 対応処理 | 表示内容 |
|---------|---------|---------|
| ユーザー名未入力 | フォーム送信阻止 | react-hook-formのバリデーションエラー |
| パスワード未入力 | フォーム送信阻止 | react-hook-formのバリデーションエラー |
| 認証失敗（401） | トースト通知 | 「Login failed」エラーメッセージ |
| ネットワークエラー | コンソールエラー | console.error出力 |

## 備考

- 管理画面はReact + TypeScriptで実装されたSPA（Single Page Application）
- Zustandによる状態管理を使用
- React Routerによるクライアントサイドルーティング
- 認証情報はsettings.jsonの`users`セクションで定義（`is_admin: true`のユーザー）
- Basic認証を使用するため、HTTPS環境での運用が推奨される
- Lucide Reactアイコンライブラリを使用

---

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

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

### 推奨読解順序

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

管理画面の認証では、Zustandストアで認証状態とトースト通知を管理する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | store.ts | `admin/src/store/store.ts` | StoreState型定義、toastState管理 |

**読解のコツ**: `setToastState`関数でトースト通知の表示/非表示、メッセージ内容を制御している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LoginScreen.tsx | `admin/src/pages/LoginScreen.tsx` | ログイン画面コンポーネント全体 |

**主要処理フロー**:
1. **7-10行目**: フォーム入力の型定義（Inputs）
2. **12行目**: LoginScreenコンポーネント定義
3. **16-18行目**: react-hook-formのセットアップ
4. **20-38行目**: ログイン処理（login関数）
5. **21行目**: `/admin-auth/` へのPOSTリクエスト
6. **23-24行目**: Basic認証ヘッダー生成
7. **27-31行目**: 認証失敗時のトースト通知
8. **33行目**: 認証成功時のリダイレクト
9. **41-58行目**: フォームUIのレンダリング
10. **54-55行目**: パスワード表示切り替えアイコン

#### Step 3: 認証エンドポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | webaccess.ts | `src/node/hooks/express/webaccess.ts` | Basic認証の実装 |

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

```
[ブラウザ] GET /admin/login
    │
    ├─ express.Router (admin.ts)
    │      │
    │      └─ React SPA配信
    │              │
    │              └─ LoginScreen.tsx レンダリング
    │
    └─ [ユーザー操作] ログインボタン押下
           │
           ├─ react-hook-form バリデーション
           │
           └─ fetch('/admin-auth/', {
           │      method: 'POST',
           │      headers: { Authorization: 'Basic ...' }
           │  })
           │      │
           │      └─ [サーバー] webaccess.ts
           │              │
           │              ├─ 認証成功 (200)
           │              │      │
           │              │      └─ navigate('/') → プラグイン管理画面
           │              │
           │              └─ 認証失敗 (401)
           │                     │
           │                     └─ setToastState({ title: 'Login failed', ... })
           │
           └─ [クライアント] パスワード表示切り替え
                  │
                  └─ passwordVisible state 切り替え
                         │
                         └─ input type="password" ⇔ type="text"
```

### データフロー図

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

ユーザー名入力 ──────▶ react-hook-form ────────▶ フォーム状態
パスワード入力              register                │
                                                       ▼
ログインボタン ─────▶ handleSubmit(login) ────▶ fetch('/admin-auth/')
押下                                                   │
                                                       ▼
                                               [サーバー]
                                                       │
                                               Basic認証検証
                                                       │
                              ┌───────────────────┴───────────────────┐
                              ▼                                       ▼
                        認証成功 (200)                          認証失敗 (401)
                              │                                       │
                              ▼                                       ▼
                        navigate('/')                           setToastState()
                              │                                       │
                              ▼                                       ▼
                        プラグイン管理画面                      トースト通知表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LoginScreen.tsx | `admin/src/pages/LoginScreen.tsx` | ソース | ログイン画面コンポーネント |
| store.ts | `admin/src/store/store.ts` | ソース | Zustand状態管理ストア |
| webaccess.ts | `src/node/hooks/express/webaccess.ts` | ソース | Basic認証処理 |
| admin.ts | `src/node/hooks/express/admin.ts` | ソース | 管理画面ルーティング |
| App.tsx | `admin/src/App.tsx` | ソース | React Routerルート定義 |
| index.css | `admin/src/index.css` | スタイル | 管理画面グローバルCSS |
