### Install Project Dependencies Source: https://github.com/xixu-me/xdrop/blob/main/CONTRIBUTING.md Installs the necessary frontend and utility dependencies using the Bun package manager. The --frozen-lockfile flag ensures consistent dependency versions across environments. ```bash bun install --frozen-lockfile ``` -------------------------------- ### Run Development Servers Source: https://github.com/xixu-me/xdrop/blob/main/CONTRIBUTING.md Starts the frontend development server or the Go API server independently. Use these commands for iterative development of specific components. ```bash # Run frontend bun run dev:web # Run API cd apps/api go run ./cmd/api ``` -------------------------------- ### Install Xdrop Agent Skill Source: https://github.com/xixu-me/xdrop/blob/main/README.md Installs the Xdrop skill for use with agents. This command-line tool allows for file uploads and downloads directly from the terminal, enabling automated handoff workflows. ```bash bunx skills add xixu-me/xdrop ``` -------------------------------- ### Deploy Xdrop with Docker Compose Source: https://context7.com/xixu-me/xdrop/llms.txt Configures the Xdrop service with PostgreSQL and Redis dependencies. Includes instructions for starting the container stack. ```yaml services: xdrop: image: ghcr.io/xixu-me/xdrop:latest restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: API_ADDR: ':8080' DATABASE_URL: postgres://xdrop:xdrop@postgres:5432/xdrop?sslmode=disable REDIS_ADDR: redis:6379 S3_ENDPOINT: http://minio:9000 S3_PUBLIC_ENDPOINT: https://xdrop.example.com S3_BUCKET: xdrop S3_ACCESS_KEY: minioadmin S3_SECRET_KEY: minioadmin ALLOWED_ORIGINS: https://xdrop.example.com PRESIGN_TTL_SECONDS: 300 DEFAULT_EXPIRY_SECONDS: 3600 ports: - '127.0.0.1:8080:80' ``` ```bash docker compose up -d XDROP_IMAGE=ghcr.io/your-org/xdrop:v1.0 docker compose up -d ``` -------------------------------- ### Start Development Services Source: https://github.com/xixu-me/xdrop/blob/main/CONTRIBUTING.md Orchestrates the full stack including Xdrop, Postgres, Redis, and MinIO using Docker Compose. It builds the containers and runs them in detached mode. ```bash docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build ``` -------------------------------- ### GET /api/v1/healthz Source: https://context7.com/xixu-me/xdrop/llms.txt Checks the health status of the API server. ```APIDOC ## GET /api/v1/healthz ### Description Returns the API server status for monitoring and load balancer health checks. ### Method GET ### Endpoint /api/v1/healthz ### Response #### Success Response (200) - **status** (string) - The current health status of the server. #### Response Example { "status": "ok" } ``` -------------------------------- ### Get Public Transfer API Source: https://context7.com/xixu-me/xdrop/llms.txt Retrieves the public transfer descriptor, which can be accessed by recipients without authentication. ```APIDOC ## GET /api/v1/public/transfers/{transferId} ### Description Returns the public transfer descriptor for recipients without requiring authentication. ### Method GET ### Endpoint /api/v1/public/transfers/{transferId} ### Parameters #### Path Parameters - **transferId** (string) - Required - The ID of the transfer to retrieve. #### Query Parameters None #### Request Body None ### Request Example ```bash curl -X GET http://localhost:8080/api/v1/public/transfers/{transferId} ``` ### Response #### Success Response (200) - **id** (string) - The unique identifier for the transfer. - **status** (string) - The current status of the transfer (e.g., "ready"). - **expiresAt** (string) - The ISO 8601 timestamp indicating when the transfer expires. - **wrappedRootKey** (string) - The encrypted root key, typically in JSON format. - **manifestUrl** (string) - A presigned URL to download the transfer manifest. - **manifestCiphertextSize** (integer) - The size of the manifest ciphertext in bytes. - **downloadConfig** (object) - Configuration for downloading the transfer. - **presignTtlSeconds** (integer) - The time-to-live for presigned download URLs in seconds. #### Response Example ```json { "id": "abc123xyz789", "status": "ready", "expiresAt": "2024-01-15T12:00:00Z", "wrappedRootKey": "{\"version\":1,\"iv\":\"...\",\"ciphertext\":\"...\"}", "manifestUrl": "https://storage.example.com/presigned-manifest-url...", "manifestCiphertextSize": 1024, "downloadConfig": { "presignTtlSeconds": 300 } } ``` ``` -------------------------------- ### Get Public Transfer Descriptor Source: https://context7.com/xixu-me/xdrop/llms.txt Retrieves the public descriptor for a transfer, which includes information necessary for recipients to initiate a download without authentication. This requires the transfer ID. ```bash curl -X GET http://localhost:8080/api/v1/public/transfers/{transferId} ``` -------------------------------- ### Get Transfer Status API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Retrieves the current state and upload progress of a transfer for the owner. It includes information on uploaded chunk indexes to facilitate resume functionality. ```bash curl -X GET http://localhost:8080/api/v1/transfers/{transferId} \ -H "Authorization: Bearer {manageToken}" # Response: # { "id": "abc123xyz789", "status": "ready", "expiresAt": "2024-01-15T12:00:00Z", "createdAt": "2024-01-15T11:00:00Z", "updatedAt": "2024-01-15T11:05:00Z", "finalizedAt": "2024-01-15T11:05:00Z" } ``` -------------------------------- ### Server Environment Configuration Source: https://context7.com/xixu-me/xdrop/llms.txt Reference for environment variables used to configure the Go API server, including database, S3 storage, and rate limiting settings. ```bash API_ADDR=:8080 DATABASE_URL=postgres://xdrop:xdrop@localhost:5432/xdrop?sslmode=disable REDIS_ADDR=localhost:6379 S3_ENDPOINT=http://localhost:9000 S3_PUBLIC_ENDPOINT=https://xdrop.example.com S3_BUCKET=xdrop S3_ACCESS_KEY=minioadmin S3_SECRET_KEY=minioadmin PRESIGN_TTL_SECONDS=300 DEFAULT_EXPIRY_SECONDS=3600 RATE_LIMIT_CREATE=20 ALLOWED_ORIGINS=https://xdrop.example.com ``` -------------------------------- ### POST /api/v1/transfers Source: https://context7.com/xixu-me/xdrop/llms.txt Initializes a new encrypted file transfer. ```APIDOC ## POST /api/v1/transfers ### Description Creates a new transfer and returns the transfer ID, manage token, and upload configuration limits. ### Method POST ### Endpoint /api/v1/transfers ### Request Body - **expiresInSeconds** (integer) - Required - Duration in seconds until the transfer link expires. ### Response #### Success Response (200) - **transferId** (string) - Unique identifier for the transfer. - **manageToken** (string) - Token required for subsequent upload operations. - **uploadConfig** (object) - Configuration details for chunked uploads. - **expiresAt** (string) - ISO timestamp of expiration. #### Response Example { "transferId": "abc123xyz789", "manageToken": "secret-manage-token-here", "uploadConfig": { "chunkSize": 8388608, "maxParallel": 6, "maxFileCount": 100, "maxTransferBytes": 268435456 }, "expiresAt": "2024-01-15T12:00:00Z" } ``` -------------------------------- ### Execute Project Tests and Quality Checks Source: https://github.com/xixu-me/xdrop/blob/main/CONTRIBUTING.md Runs linting, type checking, unit tests, and coverage reports for both frontend and backend components. These commands should be executed before submitting a pull request. ```bash # Frontend checks bun run lint:web bun run typecheck:web bun run test:web # Backend tests cd apps/api go test ./... -coverprofile=coverage.out -covermode=atomic # E2E and Formatting bun run test:e2e bun run format:check ``` -------------------------------- ### Create Download URLs API Source: https://context7.com/xixu-me/xdrop/llms.txt Requests presigned download URLs for specific chunks of a transfer, used by recipients to download encrypted data. ```APIDOC ## POST /api/v1/public/transfers/{transferId}/download-urls ### Description Requests presigned download URLs for specific chunks. Used by recipients to download encrypted chunks. ### Method POST ### Endpoint /api/v1/public/transfers/{transferId}/download-urls ### Parameters #### Path Parameters - **transferId** (string) - Required - The ID of the transfer for which to generate download URLs. #### Query Parameters None #### Request Body - **chunks** (array) - Required - An array of objects, each specifying a fileId and chunkIndex for which to request a download URL. - **fileId** (string) - Required - The ID of the file. - **chunkIndex** (integer) - Required - The index of the chunk within the file. ### Request Example ```json { "chunks": [ {"fileId": "file-uuid-1", "chunkIndex": 0}, {"fileId": "file-uuid-1", "chunkIndex": 1} ] } ``` ### Response #### Success Response (200) - **items** (array) - An array of objects, each containing a fileId, chunkIndex, and the presigned download URL. - **fileId** (string) - The ID of the file. - **chunkIndex** (integer) - The index of the chunk. - **url** (string) - The presigned URL for downloading the chunk. #### Response Example ```json { "items": [ {"fileId": "file-uuid-1", "chunkIndex": 0, "url": "https://..."}, {"fileId": "file-uuid-1", "chunkIndex": 1, "url": "https://..."} ] } ``` ``` -------------------------------- ### Upload files via Xdrop CLI Source: https://context7.com/xixu-me/xdrop/llms.txt Uploads local files or directories to an Xdrop server. Supports custom expiry times, JSON output for automation, and quiet mode for scripting. ```bash bun skills/xdrop/scripts/upload.mjs --server https://xdrop.example.com ./report.pdf bun skills/xdrop/scripts/upload.mjs --server https://xdrop.example.com --expires-in 600 ./data.csv bun skills/xdrop/scripts/upload.mjs --server https://xdrop.example.com --json ./dist/ bun skills/xdrop/scripts/upload.mjs --server https://xdrop.example.com --quiet --json ./archive.zip ``` -------------------------------- ### Download files via Xdrop CLI Source: https://context7.com/xixu-me/xdrop/llms.txt Downloads and decrypts files from an Xdrop share link. Requires the full URL including the decryption fragment. ```bash bun skills/xdrop/scripts/download.mjs "https://xdrop.example.com/t/abc123xyz789#k=base64UrlKey" bun skills/xdrop/scripts/download.mjs --output ./downloads "https://xdrop.example.com/t/abc123xyz789#k=base64UrlKey" bun skills/xdrop/scripts/download.mjs --quiet --json --output ./downloads "https://xdrop.example.com/t/abc123xyz789#k=base64UrlKey" ``` -------------------------------- ### Request Download URLs for Chunks Source: https://context7.com/xixu-me/xdrop/llms.txt Generates presigned URLs for specific chunks of a transfer, allowing recipients to download encrypted data. This POST request requires the transfer ID and a JSON payload listing the desired chunks. ```bash curl -X POST http://localhost:8080/api/v1/public/transfers/{transferId}/download-urls \ -H "Content-Type: application/json" \ -d '{ "chunks": [ {"fileId": "file-uuid-1", "chunkIndex": 0}, {"fileId": "file-uuid-1", "chunkIndex": 1} ] }' ``` -------------------------------- ### Implement Secure File Download and Decryption in TypeScript Source: https://context7.com/xixu-me/xdrop/llms.txt This snippet shows how to retrieve a transfer using a share URL, unwrap the root key, fetch the encrypted manifest, and decrypt individual file chunks into blobs. It handles progress tracking and error states for transfer availability. ```typescript import { apiClient } from '@/lib/api/client' import { unwrapRootKey, decryptManifest } from '@/lib/crypto/envelope' import { parseLinkKey } from '@/lib/crypto/urlKey' import { decryptFileToBlob } from '@/lib/download/decrypt' async function downloadTransfer(shareUrl: string) { const url = new URL(shareUrl) const transferId = url.pathname.split('/').pop()! const linkKey = parseLinkKey(url.hash) if (!linkKey) throw new Error('Missing decryption key in URL') const transfer = await apiClient.getPublicTransfer(transferId) if (transfer.status !== 'ready') throw new Error(`Transfer is ${transfer.status}`) const rootKey = await unwrapRootKey(transfer.wrappedRootKey!, linkKey) const manifestResponse = await fetch(transfer.manifestUrl!) const manifestBytes = new Uint8Array(await manifestResponse.arrayBuffer()) const manifest = await decryptManifest(rootKey, manifestBytes) const files: Array<{ name: string; blob: Blob }> = [] for (const file of manifest.files) { const blob = await decryptFileToBlob({ transferId, file, rootKey, onProgress: (completed, total) => { console.log(`${file.name}: ${Math.round(completed / total * 100)}%`) } }) files.push({ name: file.relativePath, blob }) } return { manifest, files } } ``` -------------------------------- ### Implement Secure File Upload Workflow in TypeScript Source: https://context7.com/xixu-me/xdrop/llms.txt This workflow demonstrates how to securely upload files by generating cryptographic keys, chunking data, encrypting chunks with AES-GCM, and finalizing the transfer with an encrypted manifest. It requires the xdrop API client and internal cryptographic utilities. ```typescript import { APIClient } from '@/lib/api/client' import { generateSecret, encryptManifest, encryptChunk, wrapRootKey } from '@/lib/crypto/envelope' import { serializeLinkKey } from '@/lib/crypto/urlKey' import { toBase64 } from '@/lib/crypto/base64' const api = new APIClient('/api/v1') async function uploadFile(file: File) { const rootKey = await generateSecret(32) const linkKey = await generateSecret(32) const transfer = await api.createTransfer(3600) const { transferId, manageToken, uploadConfig } = transfer const fileId = crypto.randomUUID() const noncePrefix = await generateSecret(8) const totalChunks = Math.ceil(file.size / uploadConfig.chunkSize) const ciphertextOverhead = 16 const ciphertextBytes = file.size + (totalChunks * ciphertextOverhead) await api.registerFiles(transferId, manageToken, [{ fileId, totalChunks, ciphertextBytes, plaintextBytes: file.size, chunkSize: uploadConfig.chunkSize }]) const ciphertextSizes: number[] = [] for (let i = 0; i < totalChunks; i++) { const start = i * uploadConfig.chunkSize const end = Math.min(start + uploadConfig.chunkSize, file.size) const plaintext = new Uint8Array(await file.slice(start, end).arrayBuffer()) const [urlItem] = await api.createUploadUrls(transferId, manageToken, [{ fileId, chunkIndex: i }]) const { ciphertext, checksumHex } = await encryptChunk({ rootKey, transferId, fileId, chunkIndex: i, noncePrefix, plaintextChunkSize: uploadConfig.chunkSize, plaintext }) ciphertextSizes.push(ciphertext.byteLength) await fetch(urlItem.url, { method: 'PUT', body: ciphertext }) await api.completeChunks(transferId, manageToken, [{ fileId, chunkIndex: i, ciphertextSize: ciphertext.byteLength, checksumSha256: checksumHex }]) } const manifest = { version: 1, displayName: file.name, createdAt: new Date().toISOString(), chunkSize: uploadConfig.chunkSize, files: [{ fileId, name: file.name, relativePath: file.name, mimeType: file.type || 'application/octet-stream', plaintextSize: file.size, modifiedAt: file.lastModified, chunkSize: uploadConfig.chunkSize, totalChunks, ciphertextSizes, noncePrefix: toBase64Url(noncePrefix), metadataStripped: false }] } const encryptedManifest = await encryptManifest(rootKey, manifest) await api.uploadManifest(transferId, manageToken, toBase64(encryptedManifest)) const wrappedRootKey = await wrapRootKey(rootKey, linkKey) await api.finalizeTransfer(transferId, manageToken, wrappedRootKey, 1, ciphertextBytes) const shareUrl = `${window.location.origin}/t/${transferId}#k=${serializeLinkKey(linkKey)}` return { transferId, shareUrl, manageToken } } ``` -------------------------------- ### Configure Caddy Reverse Proxy Source: https://context7.com/xixu-me/xdrop/llms.txt Sets up a Caddy server block to proxy traffic to the Xdrop container with compression enabled. ```caddyfile xdrop.example.com { encode gzip zstd reverse_proxy 127.0.0.1:8080 } ``` -------------------------------- ### Create Transfer API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Initiates a new file transfer, returning a unique transfer ID, a management token, and upload configuration limits. The management token is crucial for all subsequent operations related to this transfer. ```bash curl -X POST http://localhost:8080/api/v1/transfers \ -H "Content-Type: application/json" \ -d '{ "expiresInSeconds": 3600 }' # Response: # { "transferId": "abc123xyz789", "manageToken": "secret-manage-token-here", "uploadConfig": { "chunkSize": 8388608, "maxParallel": 6, "maxFileCount": 100, "maxTransferBytes": 268435456 }, "expiresAt": "2024-01-15T12:00:00Z" } ``` -------------------------------- ### Create Upload URLs API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Requests presigned S3 upload URLs for specific file chunks. This allows the client to upload encrypted data directly to the object storage. ```bash curl -X POST http://localhost:8080/api/v1/transfers/{transferId}/upload-urls \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {manageToken}" \ -d '{ "chunks": [ {"fileId": "file-uuid-1", "chunkIndex": 0}, {"fileId": "file-uuid-1", "chunkIndex": 1} ] }' # Response: # { "items": [ { "fileId": "file-uuid-1", "chunkIndex": 0, "objectKey": "transfers/abc123/files/file-uuid-1/chunks/00000000.bin", "url": "https://storage.example.com/presigned-upload-url..." } ] } ``` -------------------------------- ### Browser Crypto Library - Wrap Root Key Source: https://context7.com/xixu-me/xdrop/llms.txt Encrypts the transfer root key using a recipient's link key, preparing it for inclusion in a shareable URL. ```APIDOC ## Wrap Root Key (Browser Crypto) ### Description Encrypts the transfer root key with the recipient link key for inclusion in the share URL. ### Method Asynchronous function call ### Endpoint N/A (Client-side library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Code Example (TypeScript) ```typescript import { wrapRootKey, generateSecret } from '@/lib/crypto/envelope' const rootKey = await generateSecret(32) const linkKey = await generateSecret(32) // Wrap the root key for the share URL const wrappedRootKeyJson = await wrapRootKey(rootKey, linkKey) // Result is JSON: {"version":1,"iv":"...","ciphertext":"..."} console.log(wrappedRootKeyJson) ``` ``` -------------------------------- ### Browser Crypto Library - Encrypt Manifest Source: https://context7.com/xixu-me/xdrop/llms.txt Encrypts a JSON manifest containing file metadata before it is uploaded. ```APIDOC ## Encrypt Manifest (Browser Crypto) ### Description Encrypts the JSON manifest containing file metadata for upload. ### Method Asynchronous function call ### Endpoint N/A (Client-side library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Code Example (TypeScript) ```typescript import { encryptManifest, generateSecret } from '@/lib/crypto/envelope' import type { ManifestV1 } from '@/lib/api/types' const rootKey = await generateSecret(32) const manifest: ManifestV1 = { version: 1, displayName: 'My Transfer', createdAt: new Date().toISOString(), chunkSize: 8388608, files: [ { fileId: 'file-uuid-1', name: 'document.pdf', relativePath: 'documents/document.pdf', mimeType: 'application/pdf', plaintextSize: 25000000, modifiedAt: Date.now(), chunkSize: 8388608, totalChunks: 3, ciphertextSizes: [8388624, 8388624, 8388576], noncePrefix: 'base64UrlEncodedNonce', metadataStripped: false } ] } // Returns Uint8Array of encrypted manifest JSON envelope const encryptedManifest = await encryptManifest(rootKey, manifest) const manifestBase64 = btoa(String.fromCharCode(...encryptedManifest)) ``` ``` -------------------------------- ### Upload Manifest API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Uploads the encrypted manifest, which contains file metadata. The manifest is encrypted using a key derived from the transfer's root key. ```bash curl -X POST http://localhost:8080/api/v1/transfers/{transferId}/manifest \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {manageToken}" \ -d '{ "ciphertextBase64": "eyJ2ZXJzaW9uIjoxLCJpdiI6Ii4uLiIsImNpcGhlcnRleHQiOiIuLi4ifQ==" }' # Response: # {"ok": true} ``` -------------------------------- ### Browser Crypto Library - Generate Secret Source: https://context7.com/xixu-me/xdrop/llms.txt Generates cryptographically secure random bytes suitable for keys, initialization vectors (IVs), and nonces. ```APIDOC ## Generate Secret (Browser Crypto) ### Description Generates cryptographically secure random bytes for keys, IVs, and nonces. ### Method Asynchronous function call ### Endpoint N/A (Client-side library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Code Example (TypeScript) ```typescript import { generateSecret } from '@/lib/crypto/envelope' // Generate a 32-byte root key const rootKey = await generateSecret(32) // Generate a 32-byte link key for share URL const linkKey = await generateSecret(32) // Generate a 12-byte IV for AES-GCM const iv = await generateSecret(12) ``` ``` -------------------------------- ### POST /api/v1/transfers/{transferId}/upload-urls Source: https://context7.com/xixu-me/xdrop/llms.txt Requests presigned S3 upload URLs for file chunks. ```APIDOC ## POST /api/v1/transfers/{transferId}/upload-urls ### Description Requests presigned S3 upload URLs for specific file chunks to enable direct client-to-storage uploads. ### Method POST ### Endpoint /api/v1/transfers/{transferId}/upload-urls ### Request Body - **chunks** (array) - Required - List of chunk identifiers to request URLs for. ### Response #### Success Response (200) - **items** (array) - List of objects containing fileId, chunkIndex, and presigned url. #### Response Example { "items": [ { "fileId": "file-uuid-1", "chunkIndex": 0, "objectKey": "transfers/abc123/files/file-uuid-1/chunks/00000000.bin", "url": "https://storage.example.com/presigned-upload-url..." } ] } ``` -------------------------------- ### Register Files API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Registers metadata for encrypted files before the chunk upload process begins. Each file registration requires a unique file ID, the total number of chunks, ciphertext size, and chunk size. ```bash curl -X POST http://localhost:8080/api/v1/transfers/{transferId}/files \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {manageToken}" \ -d '[ { "fileId": "file-uuid-1", "totalChunks": 3, "ciphertextBytes": 25165824, "plaintextBytes": 25000000, "chunkSize": 8388608 } ]' # Response: # {"ok": true} ``` -------------------------------- ### Browser Crypto Library - Unwrap Root Key Source: https://context7.com/xixu-me/xdrop/llms.txt Decrypts the root key envelope using a link key extracted from a URL fragment. ```APIDOC ## Unwrap Root Key (Browser Crypto) ### Description Decrypts the root key envelope using the link key from the URL fragment. ### Method Asynchronous function call ### Endpoint N/A (Client-side library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Code Example (TypeScript) ```typescript import { unwrapRootKey } from '@/lib/crypto/envelope' import { parseLinkKey } from '@/lib/crypto/urlKey' // Extract link key from URL hash fragment const linkKey = parseLinkKey(window.location.hash) // #k=base64urlKey // Unwrap the root key from the transfer descriptor const rootKey = await unwrapRootKey(publicTransfer.wrappedRootKey, linkKey) ``` ``` -------------------------------- ### POST /api/v1/transfers/{transferId}/files Source: https://context7.com/xixu-me/xdrop/llms.txt Registers file metadata for an existing transfer. ```APIDOC ## POST /api/v1/transfers/{transferId}/files ### Description Registers encrypted file metadata before chunk upload begins. ### Method POST ### Endpoint /api/v1/transfers/{transferId}/files ### Parameters #### Path Parameters - **transferId** (string) - Required - The ID of the transfer. ### Request Body - **files** (array) - Required - List of file metadata objects. ### Response #### Success Response (200) - **ok** (boolean) - Confirmation of registration. #### Response Example { "ok": true } ``` -------------------------------- ### Complete Chunks API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Records successfully uploaded chunks along with their checksums. This is essential for supporting resume functionality and ensuring data integrity. ```bash curl -X POST http://localhost:8080/api/v1/transfers/{transferId}/chunks/complete \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {manageToken}" \ -d '[ { "fileId": "file-uuid-1", "chunkIndex": 0, "ciphertextSize": 8388624, "checksumSha256": "a1b2c3d4e5f6..." } ]' # Response: # {"ok": true} ``` -------------------------------- ### Resume Transfer API Source: https://context7.com/xixu-me/xdrop/llms.txt Returns the resume state of a transfer, indicating which chunks have been uploaded. This allows interrupted uploads to be continued. ```APIDOC ## GET /api/v1/transfers/{transferId}/resume ### Description Returns resume state showing which chunks have been uploaded, allowing interrupted uploads to continue. ### Method GET ### Endpoint /api/v1/transfers/{transferId}/resume ### Parameters #### Path Parameters - **transferId** (string) - Required - The ID of the transfer to resume. #### Query Parameters None #### Request Body None ### Request Example ```bash curl -X GET http://localhost:8080/api/v1/transfers/{transferId}/resume \ -H "Authorization: Bearer {manageToken}" ``` ### Response #### Success Response (200) - **manifestCiphertextSize** (integer) - The size of the manifest ciphertext in bytes. - **totalFiles** (integer) - The total number of files in the transfer. - **totalCiphertextBytes** (integer) - The total size of all ciphertext in bytes. - **files** (array) - An array of file objects, each containing details about its chunks and upload status. - **uploadedChunks** (object) - An object mapping file IDs to arrays of uploaded chunk indices. ``` -------------------------------- ### Finalize Transfer API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Marks a transfer as ready for download after all chunks and the manifest have been successfully uploaded. This endpoint also includes the wrapped root key necessary for recipient decryption. ```bash curl -X POST http://localhost:8080/api/v1/transfers/{transferId}/finalize \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {manageToken}" \ -d '{ "wrappedRootKey": "{\"version\":1,\"iv\":\"...\",\"ciphertext\":\"...\"}", "totalFiles": 1, "totalCiphertextBytes": 25165824 }' # Response: # {"ok": true} ``` -------------------------------- ### POST /api/v1/transfers/{transferId}/finalize Source: https://context7.com/xixu-me/xdrop/llms.txt Finalizes the transfer process. ```APIDOC ## POST /api/v1/transfers/{transferId}/finalize ### Description Marks a transfer as ready for download after all chunks and manifest are uploaded. ### Method POST ### Endpoint /api/v1/transfers/{transferId}/finalize ### Request Body - **wrappedRootKey** (string) - Required - The encrypted root key for recipient decryption. - **totalFiles** (integer) - Required - Total number of files in transfer. - **totalCiphertextBytes** (integer) - Required - Total size of encrypted content. ### Response #### Success Response (200) - **ok** (boolean) - Confirmation of finalization. #### Response Example { "ok": true } ``` -------------------------------- ### Wrap Root Key for Share URL (TypeScript) Source: https://context7.com/xixu-me/xdrop/llms.txt Encrypts the transfer's root key using a recipient-specific link key. The resulting ciphertext is included in the shareable URL, allowing secure key exchange. This function requires the root key, link key, and utilizes the `generateSecret` function. ```typescript import { wrapRootKey, generateSecret } from '@/lib/crypto/envelope' const rootKey = await generateSecret(32) const linkKey = await generateSecret(32) // Wrap the root key for the share URL const wrappedRootKeyJson = await wrapRootKey(rootKey, linkKey) // Result is JSON: {"version":1,"iv":"...","ciphertext":"..."} console.log(wrappedRootKeyJson) ``` -------------------------------- ### Encrypt File Chunk Source: https://context7.com/xixu-me/xdrop/llms.txt Encrypts a file chunk with authenticated metadata binding. This process generates necessary secrets, performs the encryption, and reports the resulting checksum to the API. ```typescript import { encryptChunk, generateSecret } from '@/lib/crypto/envelope'; const rootKey = await generateSecret(32); const noncePrefix = await generateSecret(8); const plaintext = new Uint8Array(fileChunkBuffer); const { ciphertext, checksumHex } = await encryptChunk({ rootKey, transferId: 'abc123xyz789', fileId: 'file-uuid-1', chunkIndex: 0, noncePrefix, plaintextChunkSize: 8388608, plaintext }); await fetch(uploadUrl, { method: 'PUT', body: ciphertext, headers: { 'Content-Type': 'application/octet-stream' } }); await apiClient.completeChunks(transferId, manageToken, [{ fileId: 'file-uuid-1', chunkIndex: 0, ciphertextSize: ciphertext.byteLength, checksumSha256: checksumHex }]); ``` -------------------------------- ### Encrypt JSON Manifest (TypeScript) Source: https://context7.com/xixu-me/xdrop/llms.txt Encrypts a JSON manifest containing file metadata using the transfer's root key. The output is an encrypted envelope, typically base64 encoded for transmission. This function requires the root key and a `ManifestV1` object. ```typescript import { encryptManifest, generateSecret } from '@/lib/crypto/envelope' import type { ManifestV1 } from '@/lib/api/types' const rootKey = await generateSecret(32) const manifest: ManifestV1 = { version: 1, displayName: 'My Transfer', createdAt: new Date().toISOString(), chunkSize: 8388608, files: [ { fileId: 'file-uuid-1', name: 'document.pdf', relativePath: 'documents/document.pdf', mimeType: 'application/pdf', plaintextSize: 25000000, modifiedAt: Date.now(), chunkSize: 8388608, totalChunks: 3, ciphertextSizes: [8388624, 8388624, 8388576], noncePrefix: 'base64UrlEncodedNonce', metadataStripped: false } ] } // Returns Uint8Array of encrypted manifest JSON envelope const encryptedManifest = await encryptManifest(rootKey, manifest) const manifestBase64 = btoa(String.fromCharCode(...encryptedManifest)) ``` -------------------------------- ### Unwrap Root Key from URL Fragment (TypeScript) Source: https://context7.com/xixu-me/xdrop/llms.txt Decrypts the encrypted root key envelope using a link key extracted from the URL's hash fragment. This is crucial for recipients to access the transfer's root key after obtaining it via the share URL. ```typescript import { unwrapRootKey } from '@/lib/crypto/envelope' import { parseLinkKey } from '@/lib/crypto/urlKey' // Extract link key from URL hash fragment const linkKey = parseLinkKey(window.location.hash) // #k=base64urlKey // Unwrap the root key from the transfer descriptor const rootKey = await unwrapRootKey(publicTransfer.wrappedRootKey, linkKey) ``` -------------------------------- ### Decrypt Manifest Envelope Source: https://context7.com/xixu-me/xdrop/llms.txt Retrieves and decrypts the manifest envelope to access file metadata. It requires unwrapping the root key using a link key derived from the URL and fetching the encrypted manifest bytes. ```typescript import { decryptManifest, unwrapRootKey } from '@/lib/crypto/envelope'; import { parseLinkKey } from '@/lib/crypto/urlKey'; import { apiClient } from '@/lib/api/client'; const transfer = await apiClient.getPublicTransfer(transferId); const linkKey = parseLinkKey(window.location.hash); const rootKey = await unwrapRootKey(transfer.wrappedRootKey!, linkKey!); const manifestResponse = await fetch(transfer.manifestUrl!); const manifestBytes = new Uint8Array(await manifestResponse.arrayBuffer()); const manifest = await decryptManifest(rootKey, manifestBytes); console.log(manifest.files); ``` -------------------------------- ### Resume Transfer State Source: https://context7.com/xixu-me/xdrop/llms.txt Retrieves the current upload status of chunks for a given transfer, enabling the resumption of interrupted uploads. It requires the transfer ID and an authorization token. ```bash curl -X GET http://localhost:8080/api/v1/transfers/{transferId}/resume \ -H "Authorization: Bearer {manageToken}" ``` -------------------------------- ### Generate Cryptographically Secure Secret (TypeScript) Source: https://context7.com/xixu-me/xdrop/llms.txt Generates a specified number of cryptographically secure random bytes, suitable for creating keys, initialization vectors (IVs), and nonces. This function is essential for secure cryptographic operations. ```typescript import { generateSecret } from '@/lib/crypto/envelope' // Generate a 32-byte root key const rootKey = await generateSecret(32) // Generate a 32-byte link key for share URL const linkKey = await generateSecret(32) // Generate a 12-byte IV for AES-GCM const iv = await generateSecret(12) ``` -------------------------------- ### Decrypt File Chunk Source: https://context7.com/xixu-me/xdrop/llms.txt Decrypts a downloaded encrypted chunk and validates the authenticated metadata. It requires the root key and specific chunk context to ensure data integrity. ```typescript import { decryptChunk } from '@/lib/crypto/envelope'; import { fromBase64Url } from '@/lib/crypto/base64'; const response = await fetch(chunkDownloadUrl); const ciphertext = new Uint8Array(await response.arrayBuffer()); const plaintext = await decryptChunk({ rootKey, transferId: 'abc123xyz789', fileId: 'file-uuid-1', chunkIndex: 0, noncePrefix: fromBase64Url(file.noncePrefix), plaintextChunkSize: Math.min(file.chunkSize, file.plaintextSize), ciphertext }); ``` -------------------------------- ### Health Check API Endpoint Source: https://context7.com/xixu-me/xdrop/llms.txt Checks the status of the API server. This endpoint is typically used for monitoring and load balancer health checks. It returns a JSON object indicating the server's operational status. ```bash curl -X GET http://localhost:8080/api/v1/healthz # Response: # {"status":"ok"} ``` -------------------------------- ### Update Transfer API Source: https://context7.com/xixu-me/xdrop/llms.txt Updates mutable properties of a transfer, such as its expiry time or manifest ciphertext. ```APIDOC ## PATCH /api/v1/transfers/{transferId} ### Description Updates mutable transfer properties like expiry time or manifest ciphertext. ### Method PATCH ### Endpoint /api/v1/transfers/{transferId} ### Parameters #### Path Parameters - **transferId** (string) - Required - The ID of the transfer to update. #### Query Parameters None #### Request Body - **expiresInSeconds** (integer) - Optional - The new expiration time for the transfer in seconds. ### Request Example ```json { "expiresInSeconds": 7200 } ``` ### Response #### Success Response (200) - **ok** (boolean) - Indicates if the update was successful. #### Response Example ```json { "ok": true } ``` ``` -------------------------------- ### Delete Transfer API Source: https://context7.com/xixu-me/xdrop/llms.txt Soft-deletes a transfer and removes its associated encrypted objects from storage. ```APIDOC ## DELETE /api/v1/transfers/{transferId} ### Description Soft-deletes a transfer and removes its encrypted objects from storage. ### Method DELETE ### Endpoint /api/v1/transfers/{transferId} ### Parameters #### Path Parameters - **transferId** (string) - Required - The ID of the transfer to delete. #### Query Parameters None #### Request Body None ### Request Example ```bash curl -X DELETE http://localhost:8080/api/v1/transfers/{transferId} \ -H "Authorization: Bearer {manageToken}" ``` ### Response #### Success Response (204) No Content. ``` -------------------------------- ### Delete Transfer Source: https://context7.com/xixu-me/xdrop/llms.txt Soft-deletes a transfer and removes its associated encrypted objects from storage. This action is irreversible and requires the transfer ID and an authorization token. ```bash curl -X DELETE http://localhost:8080/api/v1/transfers/{transferId} \ -H "Authorization: Bearer {manageToken}" ``` -------------------------------- ### Update Transfer Properties Source: https://context7.com/xixu-me/xdrop/llms.txt Modifies mutable properties of an existing transfer, such as its expiration time. This operation requires the transfer ID, an authorization token, and a JSON payload specifying the properties to update. ```bash curl -X PATCH http://localhost:8080/api/v1/transfers/{transferId} \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {manageToken}" \ -d '{ "expiresInSeconds": 7200 }' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.