fix(auth): every call with a code after the password takes the address

Whoever guessed codes decided whether the owner was mailed (the re-review's
fourth finding): the address a sign-in sent was optional, so a guesser left
it out and no mail went, and a wait begun without a mail used up the one
mail there was. Every call carrying a code after the password or the phrase
proved (signing in, the phrase's reset, a change of password, a new phrase,
deletion) now takes the account's address and the language of its mails,
and is refused (wrongCredentials, as anything wrong after the password)
before any code is checked when the address isn't the account's; every
wait mails the owner, not only the first. The app sends the address the
person typed, or for changes while signed in the one this device signed in
with, and says so where it doesn't know it (addressUnknown).

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-20 23:08:25 +02:00
commit 2a21672b43
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -564,6 +564,8 @@ void main() {
clientProof: answer.clientProof,
totpCode: codeOf(enrolment, at: now),
host: testHost,
address: 'anna@example.org',
language: 'en',
);
expect(proof.account, annaOnTodo);
expect(answer.verifiesServer(proof.serverProof), isTrue);
@ -582,6 +584,8 @@ void main() {
clientProof: againAnswer.clientProof,
totpCode: codeOf(enrolment, at: now),
host: testHost,
address: 'anna@example.org',
language: 'en',
),
refused(PasswordRefusal.wrongCredentials),
);
@ -618,6 +622,8 @@ void main() {
password: newPassword,
totpCode: codeOf(enrolment, at: now),
host: testHost,
address: 'anna@example.org',
language: 'en',
),
(account: annaOnTodo, endedBefore: now),
);
@ -744,6 +750,8 @@ void main() {
password: device.newPassword(),
keepSession: annasPhone,
host: testHost,
address: 'anna@example.org',
language: 'en',
);
expect(members.sessionsTold.single, (
_todo,
@ -775,6 +783,8 @@ void main() {
device.recoveryProofKey,
),
host: testHost,
address: 'anna@example.org',
language: 'en',
);
}
@ -880,6 +890,8 @@ void main() {
request: await code(),
code: mailbox.codeFor('carla@example.org'),
host: testHost,
address: 'carla@example.org',
language: 'en',
);
expect(proof.account, carla);
expect(proof.needsAuthenticator, isTrue);