Commit Graph
20 Commits
Author SHA1 Message Date
nvrl 781301a77b feat(sharing,public-link): update public links, name bookmarks, walk shared trees
- 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.
2026-10-25 21:27:05 +01:00
nvrl 3da18b9309 feat(photos): port the C# album capabilities
Ports upstream a36cc423. add_photos_to_album now uses the timeline
transfer driver, generalised over a PhotoTransferTarget. A photo on
another volume, from an album shared with us, is copied into the album
instead of failing. A photo whose group the server reports incomplete
is sent once more with the related photos it named. Outcomes stay in
input order.

New set_album_cover, and delete_album_saving_photos, which saves the
photos that exist only in the album (code 200302, now
AlbumContainsPhotosNotInTimeline) before deleting it.
remove_photos_from_album fails a photo on another volume without
sending it. AlbumUpdateRequest leaves out a missing cover or name, as
C# does.

Pins upstream to b68d64bd. The search commit e861ef99 is not ported:
its engine source is not public.
2026-10-25 20:48:22 +01:00
nvrl c30b107382 feat(drive): copy a node on the server
ProtonDriveClient::copy_node copies a file with its content, or a folder
with its subtree, under a new parent without downloading it, ported from
the TS SDK's copyNode (POST volumes/{vid}/links/{lid}/copy). The crypto
is the move's: the passphrase is rewrapped to the new parent, so the
node and content keys stay the same, and the name is encrypted and
signed to it. An optional name renames the copy.

The new parent may be on another volume, and the returned uid takes the
target's volume, where TS uses the source's. CopyPhotoResponse is now
the shared CopyLinkResponse.

UPSTREAM_SYNC.md logs this, get_folder_size and the read retries.
2026-10-25 20:37:51 +01:00
nvrl 1b8abf70f8 feat(drive): port upstream C# SDK up to 8ffae007
Port af391cbb (require node type for getting an available name);
c6b45188 (file-backed transfer buffers) is C# memory plumbing and a
no-op here.

- get_available_name takes an AvailableNameTarget. A file keeps its
  extension last (name (1).ext); a folder appends to the whole name
  (name (1)), so a folder named v1.2 no longer resolves to v1 (1).2.
- Split alternate_names into alternate_file_names and
  alternate_folder_names, mirroring AlternateFileNameGenerator.

Breaking: get_available_name gains a parameter.
2026-10-15 19:50:17 +02:00
nvrl 32014b1f07 feat(drive,photos): report recently accessed nodes
Port upstream 0aabea59: report_recently_accessed on ProtonDriveClient and
ProtonPhotosClient, batches of 50. Also read the ThirdParty/Sdk flags from
f257c20e on link and revision DTOs. Pin bumped to df3a717b.
2026-10-06 23:49:58 +02:00
nvrl 917bad2ef4 chore(sync): bump upstream pin to f28a93ce 2026-09-27 12:12:48 +02:00
nvrl 1ca28c5848 feat(drive,sdk): port upstream C# SDK up to 6cbf2f44
Port 6cbf2f44 (stop retrying permanent API errors on block transfers)
and 20822176 (small file upload interop); 6ce47922 is a no-op here.

- Add ProtonApiError::is_retriable / ProtonError::is_retriable mirroring
  C# RetryPolicy.IsRetriable: 4xx is permanent except 404, 408 and 429,
  with envelope codes able to override the HTTP status.
- Gate upload_one_block's retry loop on it so a permanent rejection of a
  revision fails immediately instead of being replayed three times.
- Extract BlockTargets from RevisionReader so the whole-file download
  path, the public link download and the reader all re-mint expired
  block URLs through one generation-deduplicated refresh.
- Fall back from the small upload to the block path on AlreadyExists
  only; the small upload is not idempotent, so everything else keeps
  propagating.
- Bound a server-supplied Retry-After by RetryPolicy::max_retry_after
  (default 120 s) so a long rate-limit answer cannot look like a hang.
2026-09-19 14:05:19 +02:00
nvrl d72065418b feat(drive,sdk): port upstream C# SDK up to ce000edd
- Moves go through `move-multiple` in batches of 150, with an optional
  target name per node (`move_nodes_streaming` / `NodeMoveItem`), a single
  `InvalidRequirements` retry against the server's current name hash, and
  passphrase signing for anonymously created nodes. A batch rejected as a
  whole keeps its API error code on every node.
- Share memberships carry invite time and inviter email, and the inviter's
  `drive.share-member.inviter` signature is verified as non-fatal metadata
  (`verify_detached_with_context`).
- `Node` gains `direct_role` and `share_id`.
- Trashed detection reads `TrashTime` as well as the legacy `Trashed`.

Breaking: new public struct fields on `Node` and `ShareMembership`.
2026-09-15 13:54:04 +02:00
nvrl aa17b52692 feat(photos): save photos to the timeline
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.
2026-08-27 15:58:06 +02:00
nvrl 61117fd7dc feature(photos) implemented dups, import from takeout 2026-08-18 01:30:45 +02:00
nvrl 9ec0582efe added chain with salts 2026-08-10 15:19:18 +02:00
nvrl e378db6ec8 implemented enumeration for drive 2026-08-10 14:10:43 +02:00
nvrl 4fe7f02ebb version 0.4.0 2026-08-03 00:18:39 +02:00
nvrl 3616f15cfc validate_node_name, albums, photo tags 2026-07-31 19:32:59 +02:00
nvrl 9dd535b374 improved performance, concurrent upload, version 0.2.0 2026-07-24 20:29:15 +02:00
nvrl 8c786bcf3a Photo duplicate detection, Atomic small uploads support buffered new files and revisions, Small uploads are disabled by default and enabled with .with_small_file_upload(true), Added authenticated multipart HTTP support with retry and token refresh 2026-07-22 03:03:25 +02:00
nvrl 7c9d16b405 added device support + sharing 2026-07-14 15:03:06 +02:00
nvrl 0d07fdb084 added device support 2026-07-10 15:59:56 +02:00
nvrl e15f2d3111 enumeration returns NodeUids (enumerate_folder_children_node_uids / enumerate_trash_node_uids), caller materializes via enumerate_nodes. noise dropped: BOM/deps/kt-enum-order/cs-account-refactor 2026-06-26 14:15:54 +02:00
nvrl 5685923034 upstream changelog for port 2026-06-26 14:06:50 +02:00