fix(app): every change of how an account is secured asks for the password

The app's side of the owner's proof (OwnerProof, the third reading): adding
an authenticator once one is confirmed, removing a confirmed one and new
recovery codes now ask for the current password beside the code, as
changing the password, a new phrase and deleting already did; one
challenge and one answer per sheet (OwnerAnswer). A wrong password or code
reads as the one refusal the instance gives.

Deleting chooses a code by mail from what the instance says
(secondFactorWorks), no longer from whether an authenticator was ever
confirmed: with the authenticators' reset taken effect but not carried
out, the app offered a code field the instance refused (the fourth
finding). Signed-in calls take no address any more, so a device that
doesn't know it changes the password as any other; deleting by mail asks
for the address only where the device doesn't know it, as the code goes
there (the fifth finding).

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 10:42:55 +02:00
commit a0ae08f975
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
5 changed files with 468 additions and 315 deletions

View file

@ -117,6 +117,7 @@
"passwordAuthenticatorOpen": "In deiner Authenticator-App öffnen",
"passwordAuthenticatorNoApp": "Keine App auf diesem Gerät öffnet ihn. Scanne den Code oder tippe den Schlüssel ein.",
"passwordAuthenticatorCodeIntro": "Gib dann den Code ein, den sie zeigt.",
"passwordAuthenticatorOwnerIntro": "Bestätige zum Hinzufügen, dass du es bist: mit deinem Passwort und einem Code von einem bisherigen Authenticator.",
"passwordExistingCode": "Code von einem bisherigen Authenticator",
"passwordRecoveryCodesTitle": "Wiederherstellungscodes",
"passwordRecoveryCodesIntro": "Jeder meldet dich einmal anstelle eines Codes aus deinem Authenticator an, falls du ihn verlierst. Bewahre sie auf, wo nur du sie findest: Sie werden nur jetzt angezeigt.",
@ -161,7 +162,7 @@
"passwordSectionKeysMissing": "Melde dich auf diesem Gerät mit deinem Passwort an, um das zu ändern.",
"passwordSectionNotConfirmed": "Noch nicht eingerichtet",
"passwordSectionRemove": "{name} entfernen?",
"passwordSectionRemoveIntro": "Gib zur Bestätigung einen Code aus einem deiner Authenticators ein.",
"passwordSectionRemoveIntro": "Gib zur Bestätigung dein Passwort und einen Code aus einem deiner Authenticators ein.",
"passwordSectionRemoveAction": "Entfernen",
"passwordSectionAddAuthenticator": "Authenticator hinzufügen",
"passwordSectionRecoveryCodes": "Neue Wiederherstellungscodes",
@ -172,7 +173,7 @@
"passwordChangeIntro": "Deine anderen Geräte werden abgemeldet. Deine Schlüssel bleiben: Nichts geht verloren.",
"passwordChangeAction": "Passwort ändern",
"passwordChanged": "Passwort geändert. Deine anderen Geräte sind abgemeldet.",
"passwordNewCodesIntro": "Gib einen Code aus deiner Authenticator-App ein. Deine alten Wiederherstellungscodes gelten dann nicht mehr.",
"passwordNewCodesIntro": "Gib dein Passwort und einen Code aus deiner Authenticator-App ein. Deine alten Wiederherstellungscodes gelten dann nicht mehr.",
"passwordNewPhraseIntro": "Deine neue Wiederherstellungsphrase. Schreib die 24 Wörter der Reihe nach auf: Sobald du sie bestätigst, öffnet deine alte Phrase nichts mehr.",
"passwordPhraseKept": "Neue Wiederherstellungsphrase gesetzt. Die alte gilt nicht mehr.",
"passwordWrongCredentials": "Die Adresse, das Passwort oder der Code stimmt nicht.",
@ -186,7 +187,6 @@
"passwordNoAddress": "Dein Konto hat noch keine E-Mail-Adresse.",
"passwordNoPassword": "Dieses Konto hat kein Passwort.",
"passwordWrongCode": "Dieser Code stimmt nicht. Gib den ein, den deine App gerade zeigt.",
"passwordWrongExistingCode": "Der Code von deinem anderen Authenticator stimmt nicht.",
"passwordLastAuthenticator": "Dein letzter Authenticator kann nicht weg: Jede Anmeldung braucht einen.",
"passwordTooManyAuthenticators": "Dein Konto hat so viele Authenticators, wie es darf. Entferne zuerst einen.",
"passwordUnknownAuthenticator": "Dieser Authenticator ist weg.",
@ -212,8 +212,8 @@
"passwordCodesWait": "Zu viele falsche Codes hintereinander: Bis {date} wird kein Code angenommen. Waren es nicht deine, kennt jemand dein Passwort: Ändere es dann.",
"passwordDeleteIntro": "Dein Konto wird mit allem darin gelöscht, in jedem Dienst dieser Instanz. Gib zur Bestätigung dein Passwort und einen Code deiner Authenticator-App ein.",
"passwordSessionEnded": "Zu viele falsche Codes hintereinander von diesem Gerät: Es wurde abgemeldet. Melde dich wieder mit deinem Passwort und einem Code an.",
"passwordAddressUnknown": "Dieses Gerät kennt die Adresse deines Kontos nicht, die das braucht. Melde dich ab und wieder mit deiner Adresse und deinem Passwort an.",
"passwordDeleteIntroByMail": "Dein Konto wird mit allem darin gelöscht, in jedem Dienst dieser Instanz. Seine Authenticator-App ist nicht eingerichtet, daher bestätigt es ein Code per E-Mail: Gib dein Passwort ein, dann den Code, den wir an deine Adresse schicken.",
"passwordAddressUnknown": "Gib die E-Mail-Adresse deines Kontos ein: Dorthin geht der Code.",
"passwordDeleteIntroByMail": "Dein Konto wird mit allem darin gelöscht, in jedem Dienst dieser Instanz. Keiner seiner Authenticators funktioniert gerade, daher bestätigt es ein Code per E-Mail: Gib dein Passwort ein, dann den Code, den wir an deine Adresse schicken.",
"passwordDeleteSendCode": "Code per E-Mail schicken",
"passwordChangedSignInAgain": "Dein Passwort wurde geändert, aber dieser Dienst konnte dich gerade noch nicht anmelden. Melde dich wieder mit dem neuen Passwort an."
}

View file

@ -301,6 +301,7 @@
"passwordAuthenticatorOpen": "Open in your authenticator app",
"passwordAuthenticatorNoApp": "No app on this device opens it. Scan the code or type in the key.",
"passwordAuthenticatorCodeIntro": "Then enter the code it shows.",
"passwordAuthenticatorOwnerIntro": "To add it, confirm it is you: your password and a code from an authenticator you added before.",
"passwordExistingCode": "Code from an authenticator you added before",
"passwordRecoveryCodesTitle": "Recovery codes",
"passwordRecoveryCodesIntro": "Each signs in once in place of a code from your authenticator, should you lose it. Keep them where only you find them: they're shown only now.",
@ -380,7 +381,7 @@
}
}
},
"passwordSectionRemoveIntro": "Enter a code from one of your authenticators to confirm.",
"passwordSectionRemoveIntro": "Enter your password and a code from one of your authenticators to confirm.",
"passwordSectionRemoveAction": "Remove",
"passwordSectionAddAuthenticator": "Add an authenticator",
"passwordSectionRecoveryCodes": "New recovery codes",
@ -391,7 +392,7 @@
"passwordChangeIntro": "Your other devices are signed out. Your keys stay: nothing is lost.",
"passwordChangeAction": "Change password",
"passwordChanged": "Password changed. Your other devices are signed out.",
"passwordNewCodesIntro": "Enter a code from your authenticator app. Your old recovery codes stop working.",
"passwordNewCodesIntro": "Enter your password and a code from your authenticator app. Your old recovery codes stop working.",
"passwordNewPhraseIntro": "Your new recovery phrase. Write the 24 words down in order: once you confirm it, your old phrase opens nothing any more.",
"passwordPhraseKept": "New recovery phrase set. The old one no longer works.",
"passwordWrongCredentials": "The address, the password or the code isn't right.",
@ -412,7 +413,6 @@
"passwordNoAddress": "Your account has no email address yet.",
"passwordNoPassword": "This account has no password.",
"passwordWrongCode": "This code isn't right. Enter the one your app shows now.",
"passwordWrongExistingCode": "The code from your other authenticator isn't right.",
"passwordLastAuthenticator": "Your last authenticator can't go: every sign-in needs one.",
"passwordTooManyAuthenticators": "Your account has as many authenticators as it may. Remove one first.",
"passwordUnknownAuthenticator": "This authenticator is gone.",
@ -459,8 +459,8 @@
},
"passwordDeleteIntro": "Your account goes with everything in it, in every service of this instance. To confirm, type your password and a code from your authenticator app.",
"passwordSessionEnded": "Too many wrong codes in a row from this device: it was signed out. Sign in again with your password and a code.",
"passwordAddressUnknown": "This device doesn't know your account's address, which this takes. Sign out, then sign in again with your address and password.",
"passwordDeleteIntroByMail": "Your account goes with everything in it, in every service of this instance. Its authenticator isn't set up, so a code by mail confirms it: type your password, then the code we email to your address.",
"passwordAddressUnknown": "Enter your account's email address: the code goes there.",
"passwordDeleteIntroByMail": "Your account goes with everything in it, in every service of this instance. None of its authenticators works now, so a code by mail confirms it: type your password, then the code we email to your address.",
"passwordDeleteSendCode": "Email me a code",
"passwordChangedSignInAgain": "Your password was changed, but this service couldn't sign you in just yet. Sign in again with the new password."
}

View file

@ -805,6 +805,12 @@ abstract class HalkyonAppLocalizations {
/// **'Then enter the code it shows.'**
String get passwordAuthenticatorCodeIntro;
/// No description provided for @passwordAuthenticatorOwnerIntro.
///
/// In en, this message translates to:
/// **'To add it, confirm it is you: your password and a code from an authenticator you added before.'**
String get passwordAuthenticatorOwnerIntro;
/// No description provided for @passwordExistingCode.
///
/// In en, this message translates to:
@ -1072,7 +1078,7 @@ abstract class HalkyonAppLocalizations {
/// No description provided for @passwordSectionRemoveIntro.
///
/// In en, this message translates to:
/// **'Enter a code from one of your authenticators to confirm.'**
/// **'Enter your password and a code from one of your authenticators to confirm.'**
String get passwordSectionRemoveIntro;
/// No description provided for @passwordSectionRemoveAction.
@ -1138,7 +1144,7 @@ abstract class HalkyonAppLocalizations {
/// No description provided for @passwordNewCodesIntro.
///
/// In en, this message translates to:
/// **'Enter a code from your authenticator app. Your old recovery codes stop working.'**
/// **'Enter your password and a code from your authenticator app. Your old recovery codes stop working.'**
String get passwordNewCodesIntro;
/// No description provided for @passwordNewPhraseIntro.
@ -1219,12 +1225,6 @@ abstract class HalkyonAppLocalizations {
/// **'This code isn\'t right. Enter the one your app shows now.'**
String get passwordWrongCode;
/// No description provided for @passwordWrongExistingCode.
///
/// In en, this message translates to:
/// **'The code from your other authenticator isn\'t right.'**
String get passwordWrongExistingCode;
/// No description provided for @passwordLastAuthenticator.
///
/// In en, this message translates to:
@ -1378,13 +1378,13 @@ abstract class HalkyonAppLocalizations {
/// No description provided for @passwordAddressUnknown.
///
/// In en, this message translates to:
/// **'This device doesn\'t know your account\'s address, which this takes. Sign out, then sign in again with your address and password.'**
/// **'Enter your account\'s email address: the code goes there.'**
String get passwordAddressUnknown;
/// No description provided for @passwordDeleteIntroByMail.
///
/// In en, this message translates to:
/// **'Your account goes with everything in it, in every service of this instance. Its authenticator isn\'t set up, so a code by mail confirms it: type your password, then the code we email to your address.'**
/// **'Your account goes with everything in it, in every service of this instance. None of its authenticators works now, so a code by mail confirms it: type your password, then the code we email to your address.'**
String get passwordDeleteIntroByMail;
/// No description provided for @passwordDeleteSendCode.

View file

@ -438,6 +438,10 @@ class HalkyonAppLocalizationsDe extends HalkyonAppLocalizations {
String get passwordAuthenticatorCodeIntro =>
'Gib dann den Code ein, den sie zeigt.';
@override
String get passwordAuthenticatorOwnerIntro =>
'Bestätige zum Hinzufügen, dass du es bist: mit deinem Passwort und einem Code von einem bisherigen Authenticator.';
@override
String get passwordExistingCode => 'Code von einem bisherigen Authenticator';
@ -604,7 +608,7 @@ class HalkyonAppLocalizationsDe extends HalkyonAppLocalizations {
@override
String get passwordSectionRemoveIntro =>
'Gib zur Bestätigung einen Code aus einem deiner Authenticators ein.';
'Gib zur Bestätigung dein Passwort und einen Code aus einem deiner Authenticators ein.';
@override
String get passwordSectionRemoveAction => 'Entfernen';
@ -642,7 +646,7 @@ class HalkyonAppLocalizationsDe extends HalkyonAppLocalizations {
@override
String get passwordNewCodesIntro =>
'Gib einen Code aus deiner Authenticator-App ein. Deine alten Wiederherstellungscodes gelten dann nicht mehr.';
'Gib dein Passwort und einen Code aus deiner Authenticator-App ein. Deine alten Wiederherstellungscodes gelten dann nicht mehr.';
@override
String get passwordNewPhraseIntro =>
@ -693,10 +697,6 @@ class HalkyonAppLocalizationsDe extends HalkyonAppLocalizations {
String get passwordWrongCode =>
'Dieser Code stimmt nicht. Gib den ein, den deine App gerade zeigt.';
@override
String get passwordWrongExistingCode =>
'Der Code von deinem anderen Authenticator stimmt nicht.';
@override
String get passwordLastAuthenticator =>
'Dein letzter Authenticator kann nicht weg: Jede Anmeldung braucht einen.';
@ -799,11 +799,11 @@ class HalkyonAppLocalizationsDe extends HalkyonAppLocalizations {
@override
String get passwordAddressUnknown =>
'Dieses Gerät kennt die Adresse deines Kontos nicht, die das braucht. Melde dich ab und wieder mit deiner Adresse und deinem Passwort an.';
'Gib die E-Mail-Adresse deines Kontos ein: Dorthin geht der Code.';
@override
String get passwordDeleteIntroByMail =>
'Dein Konto wird mit allem darin gelöscht, in jedem Dienst dieser Instanz. Seine Authenticator-App ist nicht eingerichtet, daher bestätigt es ein Code per E-Mail: Gib dein Passwort ein, dann den Code, den wir an deine Adresse schicken.';
'Dein Konto wird mit allem darin gelöscht, in jedem Dienst dieser Instanz. Keiner seiner Authenticators funktioniert gerade, daher bestätigt es ein Code per E-Mail: Gib dein Passwort ein, dann den Code, den wir an deine Adresse schicken.';
@override
String get passwordDeleteSendCode => 'Code per E-Mail schicken';

View file

@ -428,6 +428,10 @@ class HalkyonAppLocalizationsEn extends HalkyonAppLocalizations {
@override
String get passwordAuthenticatorCodeIntro => 'Then enter the code it shows.';
@override
String get passwordAuthenticatorOwnerIntro =>
'To add it, confirm it is you: your password and a code from an authenticator you added before.';
@override
String get passwordExistingCode =>
'Code from an authenticator you added before';
@ -592,7 +596,7 @@ class HalkyonAppLocalizationsEn extends HalkyonAppLocalizations {
@override
String get passwordSectionRemoveIntro =>
'Enter a code from one of your authenticators to confirm.';
'Enter your password and a code from one of your authenticators to confirm.';
@override
String get passwordSectionRemoveAction => 'Remove';
@ -628,7 +632,7 @@ class HalkyonAppLocalizationsEn extends HalkyonAppLocalizations {
@override
String get passwordNewCodesIntro =>
'Enter a code from your authenticator app. Your old recovery codes stop working.';
'Enter your password and a code from your authenticator app. Your old recovery codes stop working.';
@override
String get passwordNewPhraseIntro =>
@ -678,10 +682,6 @@ class HalkyonAppLocalizationsEn extends HalkyonAppLocalizations {
String get passwordWrongCode =>
'This code isn\'t right. Enter the one your app shows now.';
@override
String get passwordWrongExistingCode =>
'The code from your other authenticator isn\'t right.';
@override
String get passwordLastAuthenticator =>
'Your last authenticator can\'t go: every sign-in needs one.';
@ -782,11 +782,11 @@ class HalkyonAppLocalizationsEn extends HalkyonAppLocalizations {
@override
String get passwordAddressUnknown =>
'This device doesn\'t know your account\'s address, which this takes. Sign out, then sign in again with your address and password.';
'Enter your account\'s email address: the code goes there.';
@override
String get passwordDeleteIntroByMail =>
'Your account goes with everything in it, in every service of this instance. Its authenticator isn\'t set up, so a code by mail confirms it: type your password, then the code we email to your address.';
'Your account goes with everything in it, in every service of this instance. None of its authenticators works now, so a code by mail confirms it: type your password, then the code we email to your address.';
@override
String get passwordDeleteSendCode => 'Email me a code';