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:
parent
6dfa989eb3
commit
372ed60eb5
1 changed files with 80 additions and 30 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue