Opt-in original-quality playback for clients whose player can't send an Authorization header. HLS stays the default.
sequenceDiagram
participant App
participant ImageApi
App->>ImageApi: POST /video/original {path, library} (Bearer)
ImageApi-->>App: {url: /video/original/stream?token=…, expires_at}
App->>ImageApi: GET url (Range: bytes=…) — no auth header
ImageApi-->>App: 206 original bytes
token = HS256 JWT {sub, lib, path, exp = now + 6h}
key = SECRET_KEY + ":video-original" # login JWTs can't be replayed here, or vice versa
stream: verify token → library by id → is_valid_full_path(root, path) → NamedFile (Range, ETag)
generate_video's library fallback moved into resolve_request_path so both handlers share it. CLAUDE.md endpoint list updated (its /video/stream?path= entry was stale).
Evidence
Before: no way to hand a native player the original bytes without exposing the login JWT in a URL. After:
original_video_url_streams_with_range_and_no_auth_header mint → GET with Range: bytes=2-5 → 206 "2345"
original_video_url_rejects_non_video_and_unauthenticated .txt → 400, no Bearer → 401
stream_original_video_rejects_bad_tokens login JWT → 401, "../../etc/passwd" token → 404
original_url: round_trip / tampered / expired / keys_not_interchangeable ok
Full suite DATABASE_URL=":memory:" cargo test: 1,531 passed (one run hung in otel_log_correlation; it passes repeatedly on both master and this branch, so it looks like an existing flake). Clippy + fmt clean.
Merge Danger
Door: two-way
Additive endpoints; nothing calls them until a client opts in.
Blast Radius: small
A minted URL grants unauthenticated read of that one video for 6 hours. Rotating SECRET_KEY revokes all of them (along with login tokens).
## Summary
Opt-in original-quality playback for clients whose player can't send an `Authorization` header. HLS stays the default.
```mermaid
sequenceDiagram
participant App
participant ImageApi
App->>ImageApi: POST /video/original {path, library} (Bearer)
ImageApi-->>App: {url: /video/original/stream?token=…, expires_at}
App->>ImageApi: GET url (Range: bytes=…) — no auth header
ImageApi-->>App: 206 original bytes
```
```text
token = HS256 JWT {sub, lib, path, exp = now + 6h}
key = SECRET_KEY + ":video-original" # login JWTs can't be replayed here, or vice versa
stream: verify token → library by id → is_valid_full_path(root, path) → NamedFile (Range, ETag)
```
`generate_video`'s library fallback moved into `resolve_request_path` so both handlers share it. CLAUDE.md endpoint list updated (its `/video/stream?path=` entry was stale).
## Evidence
- **Before:** no way to hand a native player the original bytes without exposing the login JWT in a URL.
**After:**
```text
original_video_url_streams_with_range_and_no_auth_header mint → GET with Range: bytes=2-5 → 206 "2345"
original_video_url_rejects_non_video_and_unauthenticated .txt → 400, no Bearer → 401
stream_original_video_rejects_bad_tokens login JWT → 401, "../../etc/passwd" token → 404
original_url: round_trip / tampered / expired / keys_not_interchangeable ok
```
Full suite `DATABASE_URL=":memory:" cargo test`: 1,531 passed (one run hung in `otel_log_correlation`; it passes repeatedly on both master and this branch, so it looks like an existing flake). Clippy + fmt clean.
## Merge Danger
**Door:** two-way
Additive endpoints; nothing calls them until a client opts in.
**Blast Radius:** small
A minted URL grants unauthenticated read of that one video for 6 hours. Rotating `SECRET_KEY` revokes all of them (along with login tokens).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
POST /video/original mints a URL for one video's original bytes, signed
with a key derived from SECRET_KEY (distinct from the login-token key)
and valid for 6 hours. GET /video/original/stream?token= serves it via
NamedFile, so Range/seek works, without an Authorization header — native
players can use it directly. HLS stays the default path.
Also extracts generate_video's library fallback into resolve_request_path
and fixes the stale /video/stream entry in CLAUDE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cameron
merged commit 40d9dcdbb6 into master2026-10-14 01:55:34 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Opt-in original-quality playback for clients whose player can't send an
Authorizationheader. HLS stays the default.generate_video's library fallback moved intoresolve_request_pathso both handlers share it. CLAUDE.md endpoint list updated (its/video/stream?path=entry was stale).Evidence
After:
DATABASE_URL=":memory:" cargo test: 1,531 passed (one run hung inotel_log_correlation; it passes repeatedly on both master and this branch, so it looks like an existing flake). Clippy + fmt clean.Merge Danger
Door: two-way
Additive endpoints; nothing calls them until a client opts in.
Blast Radius: small
A minted URL grants unauthenticated read of that one video for 6 hours. Rotating
SECRET_KEYrevokes all of them (along with login tokens).🤖 Generated with Claude Code