mirror of
https://github.com/narrrl/proton-sdk-rs.git
synced 2026-11-03 16:41:26 +01:00
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.
This commit is contained in:
1 parent
8611989364
commit
c30b107382
4 files changed
+204
-13
No files matched your search
@@ -42,3 +42,4 @@ gitignored, so this file is the only durable record of what we last reviewed.
|
||||
| 2026-09-27 | `6cbf2f44` → `f28a93ce` | — | no behavioral changes. not ported: `0c054f0c` (`DriveClientEnumerateNodes` / `DrivePhotosClientEnumerateNodes` interop messages exposing C# `EnumerateNodesAsync` to the Kotlin bindings — CExports/proto only; `ProtonDriveClient::enumerate_nodes` and `ProtonPhotosClient::enumerate_nodes` already exist). |
|
||||
| 2026-10-06 | `f28a93ce` → `df3a717b` | `0aabea59` | ported: **recently accessed report** (`ProtonDriveClient::report_recently_accessed` → `POST recently-accessed-items`, `ProtonPhotosClient::report_recently_accessed` → `POST photos/recently-accessed-items`; batches of 50, missing `AccessTime` defaults to now, epoch seconds; `RecentlyAccessedReportItem` takes `Option<i64>` rather than `DateTimeOffset`). Also ported the DTO half of `f257c20e`: `LinkDto` / `ActiveRevisionDto` read `ThirdParty` and `Sdk` (default `false`). not ported: rest of `f257c20e` (`DecryptionErrorEvent` / `VerificationErrorEvent` with `Recency` and `CreatedBy` — telemetry plumbing for C#'s interop metric callback, we emit no such events; same reasoning as `29e58378`). Live validation pending: the recently-accessed endpoints. |
|
||||
| 2026-10-15 | `df3a717b` → `8ffae007` | `af391cbb` | ported: **folder-aware available names** (`af391cbb`, breaking upstream and here): `get_available_name` takes an `AvailableNameTarget` (`File` / `Folder`). A file keeps its extension last (`name (1).ext`, as before); a folder appends to the whole name (`name (1)`), so a folder named `v1.2` no longer resolves to `v1 (1).2`. `alternate_names` split into `alternate_file_names` / `alternate_folder_names` (C# `AlternateFileNameGenerator.GetFileNames` / `GetFolderNames`). no-op: `c6b45188` (C# transfer buffers optionally backed by an unlinked `mkstemp` file instead of `RecyclableMemoryStream`, behind a compile-time flag) — memory plumbing only; our blocks are `Vec<u8>` bounded by the client-wide in-flight block semaphore, and the verifier prefix it now reads from the stream is the same `min(prefix, len)` bytes our `verification_token` already zero-pads. **Downstream:** no `get_available_name` caller in `proton-drive-linux` or `proton-stream`. |
|
||||
| 2026-10-25 | — (no C# delta) | — | **not an upstream port of C#** — two ports from the **TypeScript** SDK, plus one change of ours. **Folder size** (TS `getFolderSize`, `243f11f4`): `ProtonDriveClient::get_folder_size` → `GET volumes/{vid}/folders/{lid}/calculate-descendents-size`, returning `FolderSize { size, descendants }`. Live-verified, which settled what the TS docs leave open: folders count as descendants, and the size is encrypted bytes on storage (two single-block files of 301 000 plaintext bytes report 301 112). **Copy** (TS `NodesManagement.copyNode`): `ProtonDriveClient::copy_node(uid, new_parent, name)` → `POST volumes/{vid}/links/{lid}/copy`, a server-side copy of a file with its content or a folder with its subtree. The crypto is the move's (`build_move_parts`: passphrase rewrapped to the new parent, name encrypted and signed by the My Files address, signature fields only for an anonymously signed node); `CopyPhotoResponse` became the shared `CopyLinkResponse`. Diverged deliberately: the returned uid takes the **target** parent's volume, where TS uses the source's, which only holds within one volume; no `copyNodes` batch, which in TS is a sequential loop over `copyNode`. Live-verified: file content, rename-on-copy, folder subtree, and `AlreadyExists` for a taken name. **Ours**: reads are retried after a dropped connection — `send_retrying` reads the body inside its loop and takes a `Replay` mode; a `GET`, a block download and the new `ApiHttpClient::post_query` (link details, thumbnail URLs, photo duplicates, `checkAvailableHashes`) are sent again when the connection drops mid-request or mid-body, while writes keep the old rule. |
|
||||
Reference in new issue
Block a user