fix: reset-password and the admin password set stamp tokens_valid_after in whole seconds, so a token minted in the same second is accepted

JWT iat is whole seconds and every cutoff check is iat before tokens_valid_after, so a sub-second cutoff refused the login that followed a reset within the same second. POST /reset-password and the admin Users password set now truncate the cutoff to the second, like RevokeUserAccess; email_verified_at keeps full precision. Change-password and bouncer's comparison are unchanged.
This commit is contained in:
Jakub Zych
2026-10-22 22:56:38 +02:00
parent b6f8055c56
commit a484d0e9a2
3 changed files with 123 additions and 4 deletions

View File

@@ -241,8 +241,10 @@ func (c usersAdminController) FormBeforeUpdate(ctx context.Context, model any) e
}
if changed {
// An admin password reset ends every session of the user, as the
// user's own change-password does.
now := time.Now()
// user's own change-password does. The cutoff is truncated to whole
// seconds, as in RevokeUserAccess, because JWT iat has whole-second
// precision, so the user's next login in that second is not refused.
now := time.Now().Truncate(time.Second)
user.TokensValidAfter = &now
}
return nil