diff --git a/block_types.go b/block_types.go index ad41611..f634e52 100644 --- a/block_types.go +++ b/block_types.go @@ -28,6 +28,19 @@ type BlockUploadInfo struct { Size int64 EncSignature string Hash string + Verifier BlockUploadVerifier `json:",omitempty"` +} + +// BlockUploadVerifier holds the per-block verification token required by the +// Proton storage backend to authenticate that the block was correctly encrypted. +type BlockUploadVerifier struct { + Token string `json:",omitempty"` +} + +// RevisionVerification is the response from the block upload verification endpoint. +type RevisionVerification struct { + VerificationCode string // Base64-encoded verification code XOR'd with each block + ContentKeyPacket string // Encrypted content session key (for client-side integrity check) } type BlockUploadLink struct { diff --git a/link_file.go b/link_file.go index 173d9b8..d05dd70 100644 --- a/link_file.go +++ b/link_file.go @@ -8,6 +8,29 @@ import ( "github.com/go-resty/resty/v2" ) +// GetRevisionVerification fetches the verification code for a draft revision from the +// v2 volume-based API. The VerificationCode is XOR'd with each block's encrypted bytes +// to produce a per-block Verifier.Token that the storage backend requires. +func (c *Client) GetRevisionVerification(ctx context.Context, volumeID, linkID, revisionID string) (RevisionVerification, error) { + var res struct { + VerificationCode string + ContentKeyPacket string + } + + if err := c.do(ctx, func(r *resty.Request) (*resty.Response, error) { + return r.SetResult(&res).Get( + "/drive/v2/volumes/" + volumeID + "/links/" + linkID + "/revisions/" + revisionID + "/verification", + ) + }); err != nil { + return RevisionVerification{}, err + } + + return RevisionVerification{ + VerificationCode: res.VerificationCode, + ContentKeyPacket: res.ContentKeyPacket, + }, nil +} + func (c *Client) ListRevisions(ctx context.Context, shareID, linkID string) ([]RevisionMetadata, error) { var res struct { Revisions []RevisionMetadata