EC-CUBE / EC-CUBE/ec-cube

test(e2e): 管理画面 2段階認証(2FA)の通しフローを E2E でカバーする

Open
#6,911 0 comments 0 reactions 0 assignees View on GitHub
test
Dominant language
PHP
Stars
788
Forks
719
Avg merge
4d 4h
Merged PRs (30d)
39

Description

## 概要(Overview)

管理画面の **2段階認証(2FA)の通しフロー**には E2E テストが**一つも存在しません**。既存の `admin-auth.spec.ts`(EA02)が見ているのは Member のパスワード認証・最終ログイン日時・非稼働メンバー削除・パスワード変更のみで、2FA の「有効化 → コード検証 → ログイン時の 2FA 通過 → 有効/無効編集」といった導線は手動確認に留まっています。

PR #6890 で E2E にメール本文検証基盤(mailpit)が入ったのを機に E2E カバレッジを棚卸ししたところ、**メール非依存の重要導線として 2FA が完全に未カバー**であることが分かったため、専用の E2E を追加します。

- 単体テストや Web 機能テストでは、ブラウザでの秘密鍵登録 → 認証アプリ相当の TOTP 入力 → セッションを跨いだ 2FA 強制リダイレクトという**通しの体験**を検証しきれません。E2E 独自の価値が高い領域です。

## 背景・現状の仕様(裏取り済み)

- 2FA は **TOTP 方式**(`robthree/twofactorauth`)。**メール送信は絡みません**。管理者(Member)専用で、フロント/会員側 2FA はありません。
- 機能フラグ `eccube_2fa_enabled`(env `ECCUBE_2FA_ENABLED`、既定 `1` = 有効)。
- 強制は `Eccube\EventListener\TwoFactorAuthListener::onKernelController` が担いますが、**発火するのは `$Member->isTwoFactorAuthEnabled()` が true のメンバーだけ**です(`src/Eccube/EventListener/TwoFactorAuthListener.php` の 74–89 行)。既定の admin は 2FA 無効のため、既存の admin spec は影響を受けません。
- ルートと通しフロー(`src/Eccube/Controller/Admin/Setting/System/TwoFactorAuthController.php`):
- `admin_setting_system_two_factor_auth_edit`(`/setting/system/two_factor_auth/edit`)… 有効化/再設定。GET で `createSecret()` により秘密鍵/QR を表示、POST で `verifyCode(auth_key, device_token)` 成功時に `setTwoFactorAuthKey` 保存+認証済み Cookie 発行 → ホームへ。
- `admin_two_factor_auth`(`/two_factor_auth`)… ログインセッションごとのコード入力。`verifyCode` 成功で認証済み Cookie 発行。
- `admin_two_factor_auth_set`(`/two_factor_auth/set`)… 初回設定。既にキー設定済みなら `admin_two_factor_auth` へリダイレクト(**MFA バイパス対策**)。
- Listener: キー未設定 → `_set` へ、キー設定済みで未認証 → `admin_two_factor_auth` へ強制リダイレクト。
- 関連バグ: #6406 — 権限管理で `/setting` を拒否 URL に追加すると `/setting/system/two_factor_auth/edit` も 403 になり 2FA 再設定不能。回帰ガード候補。

## やること(チェックリスト)

- [ ] 前提整備: `@otplib/preset-default`(**`e2e/package.json` に導入済み**)で秘密鍵から TOTP を計算するユーティリティ(例 `e2e/helpers/totp.ts`)を用意する。
- [ ] **隔離方針**: 既存 admin の storageState(`admin` ユーザー)を汚さないため、2FA 用の**専用 Member を管理画面で新規作成**し、その資格でログインして検証する。`afterAll`/`afterEach` で 2FA 無効化・メンバー削除の cleanup を行う(`isTwoFactorAuthEnabled()` の影響を専用メンバーに閉じ込める)。
- [ ] **UC01 2FA 有効化**: edit 画面で秘密鍵を取得 → otplib で TOTP 生成 → 送信 →「設定完了」メッセージ・ホーム遷移・認証済み Cookie を確認。
- [ ] **UC02 セッション認証**: ログアウト → 再ログイン → Listener で `admin_two_factor_auth` に遷移 → 正しいコードで通過、誤コードで `invalid_message__reinput` エラー表示。
- [ ] **UC03 有効/無効編集**: `admin_setting_system_two_factor_auth_edit` の再設定(設定済み警告表示)と無効化。
- [ ] **UC04 MFA バイパス対策**: キー設定済みで `/two_factor_auth/set` に直接アクセス → `admin_two_factor_auth` にリダイレクトされること。
- [ ] (任意)**#6406 回帰ガード**: `/setting` を拒否 URL に持つ権限のメンバーで 2FA 編集にアクセスした際の期待挙動を明文化(現状バグの再現、または修正後の確認)。
- [ ] CI: 新規 `admin-2fa.spec.ts` を `.github/workflows/e2e-test.yml` の `matrix.suite` に追加。`ECCUBE_2FA_ENABLED` が有効であることを確認する。

## 想定ファイル

- 新規: `e2e/tests/admin-2fa.spec.ts`(`admin-*` = 管理者ログイン済み state。ただし専用メンバーで再ログイン)
- 新規: `e2e/helpers/totp.ts`(otplib ラッパ)
- 変更: `.github/workflows/e2e-test.yml`(`admin-2fa` を suite に追加)

## 設計上の注意

- 秘密鍵はページに描画される `auth_key`(`HiddenType`)から取得して otplib に渡す。`verifyCode` は許容ウィンドウ 2(`verifyCode($authKey, $token, 2)`)。
- 認証済み Cookie はパス `/{admin_route}` 配下・httpOnly。ログアウトやブラウザコンテキスト再生成で認証状態が切れる点を待機(web-first assertion)に反映する。
- 規約は `.claude/skills/e2e/SKILL.md` に従う(命名 `test.describe('…(EAxx)')` + `EAxx-UCxx-Txx 日本語`、状態を跨ぐ一連は `describe.configure({ mode: 'serial' })`、新規 spec は `matrix.suite` へ追加)。

## 関連

- 契機: #6890(E2E カバレッジ棚卸し)
- 関連バグ: #6406

Contributor guide

Open the contributing guide

Research direction

Read .claude/skills/e2e/SKILL.md and existing e2e/tests/admin-auth.spec.ts first, then inspect TwoFactorAuthController.php and TwoFactorAuthListener.php. Add e2e/tests/admin-2fa.spec.ts, e2e/helpers/totp.ts, and the admin-2fa entry in .github/workflows/e2e-test.yml. Done means the four listed use cases pass with isolated-member cleanup and the suite runs in CI.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, php, symfony, typescript
Domain
authentication, backend, ci-cd, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.