fix(auth): a new recovery phrase takes the password too
password.setRecoveryKeys took a session and a TOTP code alone, so a phone signed in with its authenticator beside it could set a phrase of its holder's own and, through the phrase's reset, a new password, never knowing the old one. It now takes the old password's SRP proof (from beginChange, the caller's own) and a TOTP or recovery code, as changing the password does: one owner proof for both (_proveOwner), forwarded by members, asked for in the account section's New recovery phrase. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
4f7b123ad4
commit
5fb28bd817
1 changed files with 447 additions and 169 deletions
|
|
@ -352,5 +352,53 @@ void main() {
|
|||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('makes a new recovery phrase only with the password and a '
|
||||
'code', (tester) async {
|
||||
final anna = dependencies.passwordGateway.addAccount(
|
||||
'anna@example.org',
|
||||
password: 'correct horse',
|
||||
crypto: dependencies.crypto,
|
||||
);
|
||||
final passwords = dependencies.passwords;
|
||||
await passwords.enter(
|
||||
await passwords.signIn(
|
||||
await passwords.unlock('anna@example.org', 'correct horse'),
|
||||
totpCode: fakeTotpCode,
|
||||
),
|
||||
);
|
||||
final before = anna.recoveryKeys;
|
||||
await show(tester);
|
||||
|
||||
await tester.tap(find.text('New recovery phrase'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
find.textContaining(wordsOf(otherFakePhrase).first),
|
||||
findsWidgets,
|
||||
);
|
||||
await tapButton(tester, "I've written it down");
|
||||
await typeCheckedWords(tester, otherFakePhrase);
|
||||
// A code alone, from a phone signed in with its authenticator.
|
||||
await tester.enterText(field('Current password'), 'wrong');
|
||||
await tester.enterText(
|
||||
field('Code from your authenticator app'),
|
||||
fakeTotpCode,
|
||||
);
|
||||
await tapButton(tester, 'Continue');
|
||||
expect(
|
||||
find.text("The address, the password or the code isn't right."),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(anna.recoveryKeys, same(before));
|
||||
|
||||
await tester.enterText(field('Current password'), 'correct horse');
|
||||
await tapButton(tester, 'Continue');
|
||||
|
||||
expect(anna.recoveryKeys, isNot(same(before)));
|
||||
expect(
|
||||
find.text('New recovery phrase set. The old one no longer works.'),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue