feat: password-change hook and the reset-2FA admin slot

The D-07 password-change hook is the existing AccessRevokedEvent, fired
inside the write's transaction by a reset, the user's own change and an
administrator's password; (*AccessRevokedEvent).PasswordChanged reports
those three reasons, and the login rehash fires nothing.

The Users screen declares the record action reset_two_factor (danger)
behind the new permission golem15.users.reset_two_factor, which no role
has by default. It is offered only when a two-factor plugin publishes a
classes.TwoFactorAdmin and the user has a second factor; Run calls the
service's Reset in the action's transaction.
This commit is contained in:
2026-10-26 10:03:59 +01:00
parent 8501f3475a
commit 7900f47ba6
14 changed files with 419 additions and 12 deletions

View File

@@ -119,7 +119,7 @@ func Login(app *backpack.App) http.HandlerFunc {
}
// The rehash runs before the login gates, so a user who is always
// challenged still gets the stronger hash. It is not a password
// change: it fires no PasswordChangedEvent. Unscoped, because a
// change: it fires no AccessRevokedEvent (D-07). Unscoped, because a
// deactivated account is restored only after the gates.
cost := 10
if app.Config != nil && app.Config.Int("golem15.user.password.bcrypt_cost") > 0 {