fix(auth): a refusal past an address's ceiling answers before its resets move

The push of a waiting reset runs after the refusal, on a session of its
own, as the members' notices are delivered (the short reading's L1). In
the request, the same statements for every address still differed in
time: an account with a reset waiting wrote it, and a write's commit waits
for the database's log to reach the disk, so how long a refusal took told
whether the address had an account with a reset waiting. Running the same
work for every address would not have closed that; leaving it out of the
request does. Tests wait for it (holdOutsCounted).

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-21 17:41:37 +02:00
commit 372ed60eb5
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -3,7 +3,11 @@ import 'package:halkyon_base_server/base.dart';
import 'package:halkyon_base_server/src/password/account_resets.dart'
show pushOutResets, resetLivesAtMost, resetWaitsAtMost;
import 'package:halkyon_base_server/src/password/passwords.dart'
show beginKeyProof, beginPasswordSignIn, completePasswordSignIn;
show
beginKeyProof,
beginPasswordSignIn,
completePasswordSignIn,
holdOutsCounted;
import 'package:serverpod/serverpod.dart';
import 'package:serverpod_auth_idp_server/core.dart';
import 'package:test/test.dart';
@ -121,28 +125,33 @@ void main() {
return enrolment;
});
/// A sign-in of Anna's from [network], with [totp] or none.
/// A sign-in of Anna's from [network], with [totp] or none; a refusal
/// past the address's ceiling once its push of her resets is done.
Future<PasswordProof> signInFrom(
String network, {
String? totp,
PasswordDevice? with_,
}) => atNow(() async {
final challenge = await beginPasswordSignIn(
session,
address: 'anna@example.org',
network: network,
);
final answer = (with_ ?? device).answer(challenge);
return await completePasswordSignIn(
session,
challenge: challenge.challenge,
clientValue: answer.clientValue,
clientProof: answer.clientProof,
totpCode: totp,
instanceUrl: testInstanceUrl,
address: 'anna@example.org',
language: 'en',
);
try {
final challenge = await beginPasswordSignIn(
session,
address: 'anna@example.org',
network: network,
);
final answer = (with_ ?? device).answer(challenge);
return await completePasswordSignIn(
session,
challenge: challenge.challenge,
clientValue: answer.clientValue,
clientProof: answer.clientProof,
totpCode: totp,
instanceUrl: testInstanceUrl,
address: 'anna@example.org',
language: 'en',
);
} finally {
await holdOutsCounted();
}
});
/// Whoever knows Anna's password and has her mailbox asks a reset of