fix(core,app,android): keep the password out of storage and refuse key-only 2FA

Moves to proton-sdk / proton-drive-rs 0.7.3.

The stored Proton session now holds, per account key, the passphrase derived
from the mailbox password at sign-in, and resumes through
`ProtonDriveClient::with_key_passphrases`. The mailbox password — on a
single-password account, the login password — and the key salts are no longer
stored. A session in the earlier shape, which only development builds of
1.2.0 wrote, reads as signed out: signing in again replaces it.

An account whose only second factor is a security key is refused at sign-in
with a reason, rather than asked for a code that can only fail as a wrong one.
The code prompts now say plainly that security keys are not supported.
This commit is contained in:
nvrl committed 2026-10-06 15:01:37 +02:00
1 parent d9ca8f8d60
commit da16ab0575
6 files changed
+108 -66

No files matched your search

+5 -3
View File
@@ -105,9 +105,11 @@ an edge case.
- Nothing this app holds can write to the share: a viewer link grants
`MemberRole::Viewer`, and the SDK's public-link write side is unported anyway.
- Signing in to a Proton account is optional (`pstr-core::account`). The
session — tokens, the mailbox password that unlocks the key chain, and the
key salts a refreshed token can no longer fetch — is one blob in the same
credential store, under `proton-account`. Refresh tokens are single-use, so
session — tokens, and per account key the passphrase that unlocks it,
derived at sign-in — is one blob in the same credential store, under
`proton-account`. The mailbox password itself is never stored. Only TOTP
second factors are spoken; an account whose only one is a security key is
refused with a reason before the code prompt. Refresh tokens are single-use, so
every refresh is written back. On the desktop the blob can outgrow one
credential entry — Windows caps one at 1280 UTF-16 units — so
`KeyringSecretStore` splits a long value across `key#0`, `key#1`, … under a