feat(account,drive): report which keys open and which key each token is for

AccountClient::key_report walks the user and address keys like the
unlock path, but records each step instead of skipping what fails:
whether each user key opens (inactive ones included), and the
recipients of each address key token. ProtonDriveClient::
my_files_share_recipients names the keys the My Files share passphrase
is encrypted to without decrypting anything. Together they trace a
"missing key" to the key it was meant for (proton-drive-linux#40).

crypto::recipients and crypto::key_ids read OpenPGP identifiers from
messages and keys, so a recipient can be matched to a key.
This commit is contained in:
nvrl committed 2026-10-17 12:13:27 +02:00
1 parent 155bf23615
commit bd27f7862b
6 files changed
+326 -4

No files matched your search

+12
View File
@@ -555,6 +555,18 @@ impl ProtonDriveClient {
&self.account
}
/// The address the My Files share belongs to, and the keys its passphrase
/// is encrypted to (see [`proton_sdk::crypto::recipients`]). Decrypts
/// nothing and creates nothing, so it answers even when the share key does
/// not open: matched against
/// [`AccountClient::key_report`](proton_sdk::account::AccountClient::key_report),
/// it names the address key My Files needs.
pub async fn my_files_share_recipients(&self) -> Result<(AddressId, Vec<Option<String>>)> {
let response: MyFilesShareResponse = self.http.get("v2/shares/my-files").await?;
let recipients = proton_sdk::crypto::recipients(&response.share.passphrase)?;
Ok((response.share.address_id, recipients))
}
/// Total account storage usage (`MaxSpace`/`UsedSpace`), account-wide across
/// all Proton products. Convenience passthrough to
/// [`AccountClient::quota`](proton_sdk::account::AccountClient::quota).