fix(auth): a reset waits while its owner is held out, and devices show it
The full reading's H1: an owner could be kept from calling a reset off, and the reset then went through. Whoever knew the password and had the mailbox asked an authenticators' reset and kept the codes waiting, so the owner's sign-ins were refused until it took effect; whoever had the mailbox filled the address's proofs ceiling from three networks and completed an account reset. Now every hold-out of the owner after a reset was asked (a wait that begins, an attempt a wait refuses, a sign-in or proof refused by the address's ceiling) moves the account's resets not carried out to take effect no sooner than 72 hours after it ends (pushOutResets). A reset carried out (the password alone signing in until an authenticator is confirmed) is never pushed, nor a lapsed one brought back. Signed-in devices are told too: SignInWays carries when a waiting reset of each kind takes effect, the account section shows them with Call it off, which takes the owner's proof (password and code; password. callOffResets, forwarded by members) and calls every reset off, as no wait holds a signed-in owner's proof back. Texts in English and German. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
4d1cd2045c
commit
9d0d037c86
1 changed files with 1022 additions and 18 deletions
|
|
@ -453,6 +453,13 @@ final class _Register implements AccountRegister {
|
|||
changedWith.add(proof);
|
||||
});
|
||||
|
||||
@override
|
||||
Future<void> callOffResets(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required OwnerProof proof,
|
||||
}) => _answer('callOffResets', () {});
|
||||
|
||||
@override
|
||||
Future<void> setRecoveryKeys(
|
||||
Session session, {
|
||||
|
|
@ -1285,6 +1292,37 @@ void main() {
|
|||
expect(register.warned, isEmpty);
|
||||
});
|
||||
|
||||
test("passes its person's calling off of resets to the register, "
|
||||
'never one signed out', () async {
|
||||
await endpoints.password.callOffResets(
|
||||
asBen(),
|
||||
proof: OwnerProof(
|
||||
challenge: const Uuid().v7obj(),
|
||||
clientValue: ByteData(384),
|
||||
clientProof: ByteData(32),
|
||||
totpCode: '123456',
|
||||
host: testHost,
|
||||
),
|
||||
);
|
||||
expect(register.asked, contains('callOffResets'));
|
||||
register.asked.clear();
|
||||
await expectLater(
|
||||
endpoints.password.callOffResets(
|
||||
sessionBuilder.copyWith(
|
||||
authentication: AuthenticationOverride.unauthenticated(),
|
||||
),
|
||||
proof: OwnerProof(
|
||||
challenge: const Uuid().v7obj(),
|
||||
clientValue: ByteData(384),
|
||||
clientProof: ByteData(32),
|
||||
host: testHost,
|
||||
),
|
||||
),
|
||||
throwsA(isA<ServerpodUnauthenticatedException>()),
|
||||
);
|
||||
expect(register.asked, isNot(contains('callOffResets')));
|
||||
});
|
||||
|
||||
test("passes its person's dismissing of the warning to the register, "
|
||||
"never another's", () async {
|
||||
await endpoints.password.dismissSessionEndedWarning(asBen());
|
||||
|
|
|
|||
Loading…
Reference in a new issue