135 lines
4.1 KiB
Markdown
135 lines
4.1 KiB
Markdown
# File Drop Integration Contract
|
|
|
|
Version: `filedrop.v1`
|
|
|
|
The File Drop service is backend/API-first. UI code is only an integration example. Host systems discover an active dropbox, encrypt locally to the advertised recipient key, then commit ciphertext and the E2EE envelope to the intake endpoint.
|
|
|
|
## Discovery
|
|
|
|
`GET /api/dropbox/current`
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"contractVersion": "filedrop.v1",
|
|
"dropboxId": "default",
|
|
"fingerprint": "recipient-key-fingerprint",
|
|
"key": {
|
|
"fingerprint": "recipient-key-fingerprint",
|
|
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
|
|
"source": "configured",
|
|
"status": "active"
|
|
},
|
|
"label": "Interling secure intake",
|
|
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
|
|
"source": "configured",
|
|
"status": "active",
|
|
"recipientKeys": [
|
|
{
|
|
"fingerprint": "recipient-key-fingerprint",
|
|
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
|
|
"source": "configured",
|
|
"status": "active"
|
|
},
|
|
{
|
|
"fingerprint": "master-recovery-fingerprint",
|
|
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
|
|
"source": "configured",
|
|
"status": "active"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Integrations must show or otherwise pin the recipient `fingerprint` where key authenticity matters.
|
|
|
|
The `key.status` value is one of `active`, `rotating`, or `revoked`. Upload UIs must not accept new files for revoked keys.
|
|
|
|
## Upload Commit
|
|
|
|
`POST /api/uploads/intake`
|
|
|
|
Content type: `multipart/form-data`
|
|
|
|
Fields:
|
|
|
|
- `ciphertext`: encrypted file bytes.
|
|
- `envelope`: JSON E2EE envelope from `@addideas/sefidrop/e2ee`.
|
|
- `contactName`: sender name.
|
|
- `contactEmail`: sender email.
|
|
- `dropboxId`: discovery response id.
|
|
- `routingLabel`: operational routing label.
|
|
- `serviceType`: optional operational service type.
|
|
- `languagePair`: optional operational language pair.
|
|
- `requestedDeadline`: optional operational date.
|
|
- `projectPublicId`: optional existing order id for project-specific drop links.
|
|
|
|
The original filename, note, MIME type, and other sensitive sender metadata stay in the encrypted E2EE metadata envelope.
|
|
New integrations should encrypt to every active `recipientKeys[]` entry and submit an envelope with `recipients[]`. The legacy `recipient` field remains required and mirrors the first recipient wrap for older consumers.
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"id": "upload-id",
|
|
"orderId": "INTAKE-20260710-XXXXXXXX",
|
|
"storageKey": "upload-id.enc",
|
|
"status": "ciphertext_received"
|
|
}
|
|
```
|
|
|
|
## Event
|
|
|
|
Each accepted upload emits a `filedrop.upload.received` event. Interling records that event in `project_events`, links the ciphertext row to an order, and exposes it in the portal timeline.
|
|
|
|
The event payload is intentionally host-neutral:
|
|
|
|
```json
|
|
{
|
|
"contractVersion": "filedrop.v1",
|
|
"eventType": "filedrop.upload.received",
|
|
"occurredAt": "2026-07-10T17:32:07.000Z",
|
|
"sender": { "contactEmail": "client@example.com" },
|
|
"routing": {
|
|
"dropboxId": "default",
|
|
"serviceType": "translation",
|
|
"languagePair": "DE -> EN"
|
|
},
|
|
"storage": {
|
|
"driver": "local",
|
|
"key": "upload-id.enc",
|
|
"manifestKey": "upload-id.json"
|
|
},
|
|
"upload": {
|
|
"id": "upload-id",
|
|
"ciphertextByteLength": 12345,
|
|
"ciphertextSha256": "base64url-sha256",
|
|
"recipientKeyFingerprint": "recipient-key-fingerprint",
|
|
"recipientKeyFingerprints": ["recipient-key-fingerprint", "master-recovery-fingerprint"]
|
|
}
|
|
}
|
|
```
|
|
|
|
## Webhook Signature
|
|
|
|
Future standalone deployments can deliver the same event via webhook instead of direct DB integration.
|
|
|
|
Signed webhook deliveries use these headers:
|
|
|
|
- `x-filedrop-webhook-id`: stable id for idempotency.
|
|
- `x-filedrop-timestamp`: Unix timestamp in seconds.
|
|
- `x-filedrop-signature`: HMAC-SHA256 signature, formatted as `v1=<hex>`.
|
|
|
|
The signature input is:
|
|
|
|
```txt
|
|
<timestamp>.<raw request body>
|
|
```
|
|
|
|
Receivers should reject old timestamps and verify the signature with a shared webhook secret.
|
|
|
|
## Storage Boundary
|
|
|
|
The package exposes a `FileDropStorage` interface. The current Interling host uses the local filesystem adapter; a standalone service can provide S3-compatible storage without changing the upload commit contract.
|