Files
bitvid/docs/storage-r2.md
T
google-labs-jules[bot] d5da4a42d1 Update docs to describe the extensible model
- Create `docs/storage-tab-design.md` covering StorageService architecture
- Update `docs/storage-r2.md` to reflect the new provider pattern
- Expand Kind 22242 details in `docs/nostr-event-schemas.md`
2026-01-16 12:15:25 +00:00

92 lines
4.5 KiB
Markdown

# Cloudflare R2 integration (r2Service)
## Purpose and scope
`js/services/r2Service.js` is the specialized provider handler for Cloudflare R2 uploads. While the new **Storage Tab** (powered by `StorageService`) manages the secure storage of credentials, `r2Service` is responsible for:
- Uploading the selected video/HLS asset via multipart S3 uploads.
- Verifying public access via the configured Public Bucket URL.
- Publishing the resulting public URL into the video note payload.
> **Architecture Note:** For the high-level design of credential storage, encryption, and the provider adapter pattern, please refer to [`docs/storage-tab-design.md`](./storage-tab-design.md).
## Assets stored in R2
R2 is used as the URL-first playback source. The upload path supports a single file per upload, but
file types include:
- Video files (MP4/WebM/MOV/MKV/MPG/MPEG).
- HLS/DASH assets (manifest `.m3u8`/`.mpd` and segment files like `.ts`/`.m4s`).
- Related static media if the operator chooses to upload them separately (images, subtitles such as
`.vtt`/`.srt`), which benefit from cache-friendly headers set in the upload flow.
The object key format is generated by `buildR2Key()` in `js/r2.js` and looks like:
`u/<npub>/<YYYY>/<MM>/<slug>.<ext>`, which keeps uploads scoped by user and month.
## Setup Guide: Getting your Cloudflare Credentials
To enable R2 uploads, you must provide Cloudflare S3-compatible credentials and configure your bucket for public access and CORS.
### Step 1: Create Bucket & Enable Public Access
1. Log in to the **Cloudflare Dashboard**.
2. Navigate to **R2** -> **Create Bucket**.
3. In the bucket settings, enable **Public Access** (R2.dev subdomain) or connect a custom domain.
4. Copy the **Public Bucket URL** (e.g., `https://pub-xxxxxx.r2.dev`).
### Step 2: Configure CORS
Manually add a CORS policy in the bucket settings to allow uploads from your app's origin (or `*`).
(See `content/upload-content.md` for the recommended JSON configuration).
### Step 3: Create S3 Credentials
1. In the R2 dashboard, click **Manage R2 API Tokens**.
2. Click **Create API Token**.
3. Select **Object Read & Write** permissions (Minimal).
4. Copy the **Account ID**, **Access Key ID**, and **Secret Access Key**.
### Step 4: Configure the App
1. Open the **Storage Tab** (in Profile or Upload modal).
2. Add a new connection and select **Cloudflare R2**.
3. Enter the **Account ID**, **Access Key ID**, **Secret Access Key**, and **Public Bucket URL**.
4. Click **Verify & Save**.
The app will attempt to upload a small test file to verify the credentials and public access configuration.
## Upload lifecycle
1. **Credential Retrieval:**
- When an upload starts, `UploadModal` retrieves the decrypted credentials from `StorageService`.
- `StorageService` handles the NIP-44/04 decryption of the Master Key and subsequent decryption of the R2 connection payload.
2. **Upload Execution:**
- `r2Service.multipartUpload()` uses the standard AWS SDK commands (`CreateMultipartUpload`, `UploadPart`, etc.) via the generic `makeR2Client` adapter.
- The adapter automatically constructs the R2 endpoint (`https://<accountId>.r2.cloudflarestorage.com`) using the stored `accountId`.
3. **Publish:**
- On success, `publishVideoNote()` is called with the hosted URL, enabling URL-first playback.
## Configuration keys
R2 credentials are no longer stored in plain `bitvidSettings`. They are encapsulated within the `StorageService` data model.
**R2 Connection Profile (Encrypted):**
- `provider`: `cloudflare_r2`
- `accountId`: Cloudflare account ID.
- `accessKeyId`: S3 access key ID.
- `secretAccessKey`: S3 secret access key.
- `bucket`: The target bucket name.
**Metadata (Plaintext):**
- `baseDomain`: The Public Bucket URL (e.g., `https://pub-xxxx.r2.dev`).
- `defaultForUploads`: Boolean flag indicating if this is the active upload target.
## Environment / global flags
- `globalThis.__BITVID_DISABLE_NETWORK_IMPORTS__`: disables the AWS SDK network import used by the
R2 S3 client loader (`js/storage/r2-s3.js`). When true, uploads will fail with a load error until
the SDK is bundled or otherwise provided.
## Security considerations
- **Encrypted Storage:** All sensitive keys (`accessKeyId`, `secretAccessKey`) are encrypted at rest using the user's Nostr signer.
- **Session Security:** Decrypted keys exist in memory only during the active session.
- **Public Exposure:** The generated playback URLs are public. Ensure your bucket permissions match your intent.
- **Least Privilege:** Always use "Object Read & Write" tokens rather than Admin tokens.