From 27a10598b8f6b68a82c18e6708598f67548e503e Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Thu, 16 Jul 2026 01:20:17 +0200 Subject: [PATCH] sharing fix --- crates/proton-drive-rs/src/client.rs | 44 ++++++++++++++++++++++++++-- crates/proton-drive-rs/src/dtos.rs | 24 +++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/crates/proton-drive-rs/src/client.rs b/crates/proton-drive-rs/src/client.rs index a8c1abf..b1dda3f 100644 --- a/crates/proton-drive-rs/src/client.rs +++ b/crates/proton-drive-rs/src/client.rs @@ -55,9 +55,10 @@ use crate::dtos::{ RenameLinkRequest, RevisionCreationRequest, RevisionCreationResponse, RevisionDto, RevisionResponse, RevisionUpdateRequest, ShareInvitationDto, ShareInvitationsResponse, ShareMembersResponse, ShareResponse, ShareTargetType, ShareUrlDto, ShareUrlsResponse, - SharedWithMeResponse, ThumbnailBlockListRequest, ThumbnailBlockListResponse, - ThumbnailCreationRequest, ThumbnailDto, TimelinePhotoListResponse, UpdatePermissionsRequest, - VolumeCreationRequest, VolumeEventDto, VolumeEventListResponse, VolumeTrashResponse, + SharedByMeResponse, SharedWithMeResponse, ThumbnailBlockListRequest, + ThumbnailBlockListResponse, ThumbnailCreationRequest, ThumbnailDto, TimelinePhotoListResponse, + UpdatePermissionsRequest, VolumeCreationRequest, VolumeEventDto, VolumeEventListResponse, + VolumeTrashResponse, }; use crate::events::{DriveEvent, DriveEventScopeId}; use crate::node::{FileThumbnail, Node, NodeKind, RevisionState, Thumbnail, ThumbnailType}; @@ -1618,6 +1619,43 @@ impl ProtonDriveClient { Ok(uids) } + /// The nodes I have shared with others, as [`NodeUid`]s. + /// + /// Ported from the TypeScript SDK's `iterateSharedNodeUids`: page + /// `GET drive/v2/volumes/{vid}/shares` on its `AnchorID` cursor (the `drive/` + /// prefix comes from the client's base route). The endpoint lists only + /// collaborative shares that are still live — those with members, pending + /// invitations or a public URL — so an unshared or abandoned node never + /// appears. Materialize the uids with [`enumerate_nodes`](Self::enumerate_nodes). + pub async fn enumerate_shared_by_me_node_uids(&self) -> Result> { + let mut timer = self.telemetry.start("enumerate_shared_by_me_node_uids"); + let volume_id = self.main_volume_id().await?; + let mut uids = Vec::new(); + let mut anchor: Option = None; + + loop { + let path = match &anchor { + Some(anchor_id) => { + format!("v2/volumes/{volume_id}/shares?AnchorID={anchor_id}") + } + None => format!("v2/volumes/{volume_id}/shares"), + }; + let page: SharedByMeResponse = self.http.get(&path).await?; + + for link in &page.links { + uids.push(NodeUid::new(volume_id.clone(), link.link_id.clone())); + } + + anchor = page.anchor_id.filter(|id| !id.is_empty()); + if !page.more || anchor.is_none() { + break; + } + } + + timer.success(); + Ok(uids) + } + /// Leave a node someone shared with us, giving up access to it. /// /// Mirrors C# `SharingOperations.LeaveSharedNodeAsync`: read the node's link diff --git a/crates/proton-drive-rs/src/dtos.rs b/crates/proton-drive-rs/src/dtos.rs index 667723b..7c96c66 100644 --- a/crates/proton-drive-rs/src/dtos.rs +++ b/crates/proton-drive-rs/src/dtos.rs @@ -939,6 +939,30 @@ pub struct SharedWithMeLinkDto { pub share_target_type: i32, } +/// `GET drive/v2/volumes/{volumeID}/shares` — one page of the collaborative +/// shares I own that are still live (have members, invitations or a public URL). +/// TS SDK `SharedByMeResponseDto`. +#[derive(Debug, Deserialize)] +pub struct SharedByMeResponse { + #[serde(rename = "Links", default)] + pub links: Vec, + /// Cursor for the next page. + #[serde(rename = "AnchorID", default)] + pub anchor_id: Option, + #[serde(rename = "More", default)] + pub more: bool, +} + +/// One shared-by-me item. TS SDK `LinkSharedByMeResponseDto`. The volume is the +/// one queried, so only the link (and its share) come back per entry. +#[derive(Debug, Deserialize)] +pub struct SharedByMeLinkDto { + #[serde(rename = "ShareID")] + pub share_id: ShareId, + #[serde(rename = "LinkID")] + pub link_id: LinkId, +} + /// The kind of item a share points at. C# `ShareTargetType`. /// /// The Drive client exposes folders, files and vendor items; albums and photos