fix(auth)!: a first password takes a fresh proof of the account's way in
The fourth reading's first finding: password.set took a session alone, so whoever took one made a GitHub-only account, or an address account without a password, theirs for good (their address or password, their authenticator; GitHub then refused the owner). - An account with an address proves it anew: a code mailed to that address for this (EmailCodePurpose.firstPassword, its own mail), never the session alone, a code asked for anything else, or another address. - An account that signs in with GitHub alone does it within 10 minutes of a GitHub sign-in (the session's method and creation time, where the session lives; members tell the register), refused signInAgain before any code is used; the address it adds is proved as before. - Anonymous people still become identified with a code to the address they add. The app mails the code to the person's own address (asking for it where the device doesn't know it), offers a password right after a GitHub sign-in (D2's "at their next sign-in") before the person's app, and asks for a GitHub sign-in anew when the instance refuses an older one, keeping the code typed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
1ada2e27f6
commit
f0413531ff
1 changed files with 762 additions and 66 deletions
|
|
@ -210,6 +210,69 @@ void main() {
|
|||
expect((auth.status as SignedIn).authUserId, person);
|
||||
});
|
||||
|
||||
test('gives a signed-in person with an address their first password only '
|
||||
'with a code mailed to that address for it, never with the session '
|
||||
'alone (the fourth reading)', () async {
|
||||
await auth.signInAnonymously();
|
||||
final person = (auth.status as SignedIn).authUserId;
|
||||
final first = setUpAs(AccountSetupMode.setPassword)
|
||||
..addressEntered('anna@example.org');
|
||||
await first.passwordEntered('correct horse', 'correct horse');
|
||||
first.phraseWrittenDown();
|
||||
await first.phraseChecked(wordsAsked(first.state));
|
||||
await first.mailCodeEntered(gateway.codeFor('anna@example.org'));
|
||||
// An address and no password, as codes by mail left accounts.
|
||||
gateway.accountOf(person)
|
||||
..password = null
|
||||
..authenticators.clear();
|
||||
|
||||
final cubit = setUpAs(
|
||||
AccountSetupMode.setPassword,
|
||||
address: 'anna@example.org',
|
||||
hasAddress: true,
|
||||
);
|
||||
expect(cubit.state, at(AccountSetupStep.password));
|
||||
await cubit.passwordEntered('another horse', 'another horse');
|
||||
cubit.phraseWrittenDown();
|
||||
await cubit.phraseChecked(wordsAsked(cubit.state));
|
||||
|
||||
expect(cubit.state, at(AccountSetupStep.mailCode));
|
||||
expect(gateway.mailed.last.purpose, MailCodePurpose.firstPassword);
|
||||
await cubit.mailCodeEntered(gateway.codeFor('anna@example.org'));
|
||||
expect(cubit.state, at(AccountSetupStep.authenticator));
|
||||
expect(gateway.accountOf(person).password, 'another horse');
|
||||
});
|
||||
|
||||
test('asks for the address a signed-in person has where the device '
|
||||
"doesn't know it", () {
|
||||
final cubit = setUpAs(AccountSetupMode.setPassword, hasAddress: true);
|
||||
expect(cubit.state, at(AccountSetupStep.address));
|
||||
});
|
||||
|
||||
test('asks GitHub people to sign in with GitHub again where theirs is '
|
||||
'too old, keeping the code for after', () async {
|
||||
await auth.switchToGitHub();
|
||||
gateway
|
||||
..gitHubPeople.add('github-person')
|
||||
..staleGitHubSignIns.add('github-person');
|
||||
final cubit = setUpAs(AccountSetupMode.setPassword)
|
||||
..addressEntered('gina@example.org');
|
||||
await cubit.passwordEntered('correct horse', 'correct horse');
|
||||
cubit.phraseWrittenDown();
|
||||
await cubit.phraseChecked(wordsAsked(cubit.state));
|
||||
final code = gateway.codeFor('gina@example.org');
|
||||
|
||||
await cubit.mailCodeEntered(code);
|
||||
expect(
|
||||
cubit.state,
|
||||
at(AccountSetupStep.mailCode, problem: PasswordProblem.signInAgain),
|
||||
);
|
||||
|
||||
gateway.staleGitHubSignIns.clear();
|
||||
await cubit.mailCodeEntered(code);
|
||||
expect(cubit.state, at(AccountSetupStep.authenticator));
|
||||
});
|
||||
|
||||
test("refuses another account's address to a signed-in person, back at "
|
||||
'the address', () async {
|
||||
gateway.addAccount(
|
||||
|
|
|
|||
Loading…
Reference in a new issue