fix: activate-by-code asks the login gates before it signs in
After the mailed code verifies, ActivateByCode consults the login gates with source password, as Login does. A gate answer (for example a second-factor challenge) replaces the token response and sets no session cookie; a gate error answers the opaque 500. The account is activated either way. Without a gate, or when every gate allows, the answer is unchanged. With require_activation off an account can enable a second factor before it activates, so the mailed code no longer stands in for it.
This commit is contained in:
@@ -12,7 +12,9 @@ import (
|
||||
// Login sources name the first factor a LoginAttempt or a LoginEvent comes
|
||||
// from.
|
||||
const (
|
||||
// LoginSourcePassword is POST /_user/api/v1/login (email and password).
|
||||
// LoginSourcePassword is POST /_user/api/v1/login (email and password)
|
||||
// and POST /_user/api/v1/activate-by-code (the mailed activation code,
|
||||
// the first factor of that sign-in).
|
||||
LoginSourcePassword = "password"
|
||||
// LoginSourceSocial is a social sign-in completed by a social-login
|
||||
// plugin.
|
||||
@@ -42,7 +44,7 @@ type LoginAttempt struct {
|
||||
// request body again, it is consumed). It carries keys a gate needs,
|
||||
// such as trusted_device_token. It is nil on a social sign-in. Treat it
|
||||
// as read-only, untrusted input; it holds the password on a password
|
||||
// login.
|
||||
// login and the activation code on an activation.
|
||||
Fields map[string]any
|
||||
// Request is the sign-in request, for the client address and the user
|
||||
// agent.
|
||||
@@ -78,8 +80,9 @@ type LoginGate interface {
|
||||
// looks it up with app.Lookup[*classes.LoginGates]() and adds its gate in
|
||||
// its Boot: every Register runs before every Boot. Password Login consults
|
||||
// it after the password, activation and throttle checks and before it
|
||||
// restores a deactivated account and mints the token; JWT refresh never
|
||||
// consults it. It is safe for concurrent use.
|
||||
// restores a deactivated account and mints the token; activate-by-code
|
||||
// consults it after the code verified and before it mints the token; JWT
|
||||
// refresh never consults it. It is safe for concurrent use.
|
||||
type LoginGates struct {
|
||||
mu sync.RWMutex
|
||||
gates []LoginGate
|
||||
|
||||
Reference in New Issue
Block a user