R3 two-factor in decePub: an authenticator app set up in Settings, its code asked for at sign-in
Build / Build (push) Successful in 1m3s

Completion program R3, with PrivaPub's TOTP routes of the same release.

- Settings, the login: TotpEditor turns two-factor sign-in on (the password, then the QR code, the secret and the
  otpauth:// link, then the app's first code; the ten recovery codes shown once with Copy), shows how many recovery
  codes are left (warned at three), and turns it off with the password and a code, asked first.
- Turning it on, like a password change, ends every other session: AuthService.ContinueSession takes the new JWT and
  exchanges the persona's token again.
- Sign-in: PrivaPub's 428 keeps the name and password and asks for the six digits (DOtp), or a recovery code instead;
  a wrong code says so; Back returns to the password.
- window.copyText (main.js) through AppStatusService.CopyText.
- 29 keys in both resx files; CLAUDE.md follows.

Verified: dotnet build decePubClient.csproj -c Release (0 errors, no new warnings).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-17 03:33:46 +02:00
1 parent 7d4b35f0d7
commit b731d8c8c0
11 files changed
+692 -25

No files matched your search

+87
View File
@@ -2399,4 +2399,91 @@
<data name="Keep the theme the same on every device signed in to this login" xml:space="preserve">
<value>Keep the theme the same on every device signed in to this login</value>
</data>
<data name="Enter the code from your authenticator app, or a recovery code." xml:space="preserve">
<value>Enter the code from your authenticator app, or a recovery code.</value>
</data>
<data name="Recovery code" xml:space="preserve">
<value>Recovery code</value>
</data>
<data name="Code from the authenticator app" xml:space="preserve">
<value>Code from the authenticator app</value>
</data>
<data name="Use the authenticator app instead" xml:space="preserve">
<value>Use the authenticator app instead</value>
</data>
<data name="Use a recovery code instead" xml:space="preserve">
<value>Use a recovery code instead</value>
</data>
<data name="Two-factor sign-in" xml:space="preserve">
<value>Two-factor sign-in</value>
</data>
<data name="active" xml:space="preserve">
<value>active</value>
</data>
<data name="not active" xml:space="preserve">
<value>not active</value>
</data>
<data name="Two-factor sign-in is on. Every other device signed in to this login was signed out." xml:space="preserve">
<value>Two-factor sign-in is on. Every other device signed in to this login was signed out.</value>
</data>
<data name="Save these recovery codes now: they won't be shown again." xml:space="preserve">
<value>Save these recovery codes now: they won't be shown again.</value>
</data>
<data name="Each one signs you in once in place of the app's code, if you lose your phone." xml:space="preserve">
<value>Each one signs you in once in place of the app's code, if you lose your phone.</value>
</data>
<data name="Copy" xml:space="preserve">
<value>Copy</value>
</data>
<data name="I saved them" xml:space="preserve">
<value>I saved them</value>
</data>
<data name="Signing in takes the password and a code from your authenticator app, or one of your recovery codes." xml:space="preserve">
<value>Signing in takes the password and a code from your authenticator app, or one of your recovery codes.</value>
</data>
<data name="Recovery codes left: {0}" xml:space="preserve">
<value>Recovery codes left: {0}</value>
</data>
<data name="Few recovery codes are left: turn two-factor sign-in off and on again for ten new ones." xml:space="preserve">
<value>Few recovery codes are left: turn two-factor sign-in off and on again for ten new ones.</value>
</data>
<data name="Turn off" xml:space="preserve">
<value>Turn off</value>
</data>
<data name="Signing in takes a code from an authenticator app on your phone as well as the password, so a stolen password isn't enough." xml:space="preserve">
<value>Signing in takes a code from an authenticator app on your phone as well as the password, so a stolen password isn't enough.</value>
</data>
<data name="Scan this QR code with your authenticator app, or type the key into it." xml:space="preserve">
<value>Scan this QR code with your authenticator app, or type the key into it.</value>
</data>
<data name="QR code of the key, for your authenticator app" xml:space="preserve">
<value>QR code of the key, for your authenticator app</value>
</data>
<data name="Key" xml:space="preserve">
<value>Key</value>
</data>
<data name="Open in the authenticator app" xml:space="preserve">
<value>Open in the authenticator app</value>
</data>
<data name="Then enter the 6-digit code the app shows." xml:space="preserve">
<value>Then enter the 6-digit code the app shows.</value>
</data>
<data name="Turn on" xml:space="preserve">
<value>Turn on</value>
</data>
<data name="Turn on two-factor sign-in" xml:space="preserve">
<value>Turn on two-factor sign-in</value>
</data>
<data name="Recovery codes copied." xml:space="preserve">
<value>Recovery codes copied.</value>
</data>
<data name="Turn off two-factor sign-in?" xml:space="preserve">
<value>Turn off two-factor sign-in?</value>
</data>
<data name="Signing in takes only the password again, and the recovery codes stop working." xml:space="preserve">
<value>Signing in takes only the password again, and the recovery codes stop working.</value>
</data>
<data name="Two-factor sign-in is off." xml:space="preserve">
<value>Two-factor sign-in is off.</value>
</data>
</root>