feat: login gates and the login event
Register publishes a *classes.LoginGates registry. POST /login consults it through controllers.CheckLoginGates after the password, activation and throttle checks and the bcrypt rehash, and before the restore of a deactivated account, last_seen and the mint: a gate result replaces the token response, a gate error answers the opaque 500. The restore and its reactivate mail now run after the gates, so a password alone cannot reactivate an account a second factor protects. Without a gate /login answers as before; refresh never consults the gates. classes.LoginEvent (golem15.user.login) fires after every password login that minted a token; controllers.FireLoginEvent lets other plugins fire it.
This commit is contained in:
@@ -25,6 +25,10 @@ const BackendUnlinkedEventName = "user.BackendUnlinked"
|
||||
// AccessRevokedEventName is the festival name of AccessRevokedEvent.
|
||||
const AccessRevokedEventName = "user.AccessRevoked"
|
||||
|
||||
// LoginEventName is the festival name of LoginEvent, the PHP plugin's
|
||||
// golem15.user.login.
|
||||
const LoginEventName = "golem15.user.login"
|
||||
|
||||
// GetApiArrayEvent is the fire-and-collect payload other plugins extend.
|
||||
type GetApiArrayEvent struct {
|
||||
User *models.User
|
||||
@@ -111,3 +115,14 @@ type AccessRevokedEvent struct {
|
||||
Reason string
|
||||
Tx *gorm.DB
|
||||
}
|
||||
|
||||
// LoginEvent fires after a sign-in issued a session token: a password login,
|
||||
// a sign-in completed by a second factor, a passkey sign-in or a device
|
||||
// hand-over (Source is one of the LoginSource constants). It does not fire
|
||||
// on refresh, on /register or for a sign-in a login gate held back. It fires
|
||||
// after the token was minted and outside any transaction; a listener error
|
||||
// is logged and never fails the sign-in (PHP's golem15.user.login).
|
||||
type LoginEvent struct {
|
||||
User *models.User
|
||||
Source string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user