fix(auth): a reset forgets the codes refused before it

Neither the account's reset nor the authenticators' reset, carried out,
cleared the account's refused codes (the re-review's sixth finding): after
the owner's way out, the new authenticator's codes could still meet a wait
of up to a day, and the doubling went on. Both now delete them with the
authenticators they were tried against.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-20 23:09:39 +02:00
commit 56d7aac9a8
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 53 additions and 1 deletions

View file

@ -275,6 +275,14 @@ Future<AccountSessionsEnded> completeAccountReset(
where: (t) => t.authUserId.equals(account),
transaction: transaction,
);
// The codes refused before go with the authenticators they were tried
// against (the re-review's sixth finding).
// DELETE FROM "second_factor_failures" WHERE "authUserId" = $1
await SecondFactorFailures.db.deleteWhere(
session,
where: (t) => t.authUserId.equals(account),
transaction: transaction,
);
// DELETE FROM "account_reset" WHERE "authUserId" = $1
await AccountReset.db.deleteWhere(
session,

View file

@ -1065,7 +1065,8 @@ Future<bool> _useRecoveryCode(
}
/// Carries out the reset of [account]'s authenticators that took effect:
/// they and the recovery codes go. The reset's row stays until an
/// they, the recovery codes and the codes refused before go. The reset's
/// row stays until an
/// authenticator is confirmed: until then the password alone signs in.
Future<void> _carryOutAuthenticatorReset(
Session session,
@ -1083,6 +1084,14 @@ Future<void> _carryOutAuthenticatorReset(
where: (t) => t.authUserId.equals(account),
transaction: transaction,
);
// The codes refused before go with the authenticators they were tried
// against (the re-review's sixth finding).
// DELETE FROM "second_factor_failures" WHERE "authUserId" = $1
await SecondFactorFailures.db.deleteWhere(
session,
where: (t) => t.authUserId.equals(account),
transaction: transaction,
);
});
/// Calls off the reset of [account] that a code by mail asked for: its