---
id: w4/m11/t002
title: Dashboard — settings enroll/unenroll rendering + aal2 login challenge
worker: worker4
status: todo
estimate: 35m
depends_on: [w4/m11/t001]
---

## Objective

Make the dashboard render what Kratos now offers: the Settings page shows TOTP (QR + confirm code), passkey (browser ceremony), and recovery-codes sections; login handles the `aal2` step — a user with a second factor is challenged after password. Ory Elements does most of the rendering; verify, wire, and style per `dashboard/CLAUDE.md`.

## Context

- The settings page already renders Kratos profile+password flows via Ory Elements (w5/m2, w4/m8 t-notes) — the new methods should appear once t001 enables them; the work is verifying each method's UI states, i18n strings (w5/m3 conventions), and the login flow's `aal2` refresh handling (redirect back into the login flow with `aal=aal2`).
- Read `dashboard/CLAUDE.md` before editing.

## Steps

1. Verify/extend the settings route to render totp/webauthn/lookup_secret sections (Ory Elements groups), with i18n.
2. Login route: handle the second-factor step (flow refresh with `aal=aal2`), including the "session has aal1 but aal2 required" redirect case.
3. Style pass consistent with the existing auth pages; screenshots via Playwright MCP (bare filenames → `.playwright-mcp/`).

## Files

- `dashboard/src/` (settings + login routes/components)

## Acceptance criteria

- [ ] Enroll/unenroll TOTP and passkey from Settings in a real browser on the mock stack; recovery codes displayable/regenerable.
- [ ] Login with an enrolled user demands the second factor; without enrollment, unchanged.

## Out of scope

- E2E scripting (t003); forcing MFA for all users (product decision, not taken).
