- update_public_link sets the role, custom password and expiry of a node's
public link and keeps its URL (TS updateSharedLink). Create and update
share the sealing of the share key and SRP verifier.
- list_bookmarks decrypts the bookmarked item's name with the share key the
stored password unlocks, and returns the custom password in the new
Bookmark::custom_password. The URL fragment is now only the generated
password.
- ProtonDrivePublicLinkClient::enumerate_subtree walks a shared folder
breadth first, several folders of a level at a time.
- Add CHANGELOG.md, update the README feature table for this and the
previous unreleased commits, and record the TS ports in UPSTREAM_SYNC.
A wrong mailbox password surfaced as InvalidOperation("no active user key could
be unlocked"), which a caller could only recognise by its text. It is now
ProtonError::KeysLocked, and AccountClient::unlock() checks a secret with a
single core/v4/users request instead of loading every address.
Derived passphrases, the mailbox password and the cache encryption key were
plain Vec<u8>s, cloned freely and never wiped. They are Zeroizing now, and the
passphrase map is KeyPassphrases: wiped on drop, redacted in Debug, with
derive_secret() for a client that wants a key only an unlocked account can
reproduce. with_key_passphrases takes it.
Breaking: ProtonError gains a variant, key_passphrases() and
with_key_passphrases() change type, and derive_key_passphrase returns
Zeroizing<Vec<u8>>.
Ports upstream C# e0e198e2 (SavePhotosToTimelineAsync, itself the JS
saveToTimeline). Photos already on our photos volume are moved into the
timeline root via PUT photos/volumes/{vid}/links/transfer-multiple,
batched so no request carries more than ten links and a photo is never
split from its related photos; photos on another volume — from an album
shared with us — are copied via POST volumes/{vid}/links/{lid}/copy, one
request each. That closes the cross-volume copy hole (TS copyPhoto).
The re-encryption is what add_photos_to_album already did, so it moves
into a shared photo_target_payload: name re-encrypted to the target key
and signed by the photos membership address, name/content hashes under
the target hash key, node passphrase rewrapped so the original
NodePassphraseSignature survives.
A photo the server reports an incomplete group for is re-queued once
with the related photos it named; only its second answer becomes an
outcome, so outcomes arrive in completion order, not input order.
Also adds ProtonPhotosClient::enumerate_events (c8d03244's only
non-interop hunk) and bumps the upstream pin to c8d03244. Upstream
29e58378 (upload telemetry) and 0537d906 (NodeProvider refactor) are
deliberately not ported — see UPSTREAM_SYNC.md.