Commit graph

2 commits

Author SHA1 Message Date
Johannes Rauh
238ce10e6b Make TwoFactorHook::first() throw and migrate its only caller
`TwoFactorController` used `TwoFactorHook::first() === null` as a presence
check. This is replaced with `TwoFactorHook::all() === []` so the intent is
explicit and the call is no longer dependent on `first()`'s nullable return.

`first()` itself is updated to throw `RuntimeException` when no method is
registered rather than returning null. Callers that reach `first()` expect
at least one method to be available. A missing registration indicates a
misconfiguration rather than a recoverable condition. This matches the
behavior of `fromName()`.
2026-05-27 10:47:21 +02:00
Johannes Rauh
1b90b6c14f Add enrollment UI and two-factor tab to account navigation
`TwoFactorController::configAction()` renders `TwoFactorEnrollmentForm`, which
shows a method-selector dropdown (autosubmit), the method-specific fieldset
contributed by `assembleEnrollmentFormElements()`, and either an "Enroll" or
"Unenroll" submit button depending on current enrollment state.

`AccountController`, `MyDevicesController`, and `NavigationController` each gain
a "Two-Factor Auth" tab.
2026-05-27 10:47:21 +02:00