Repository navigation
feat: report link and staff takedown for Cap Infra videos - #4172
Merged
Merged
Conversation
Stores the flag under a reserved key in developer_videos.metadata, wrapping the developer's own metadata so a restore writes it back exactly. Status is untouched, so storage billing reads the video as before. No migration. A staff-only route and scripts/infra-video-takedown.ts flip it.
Every playback file of a taken down video answers a plain 410 with no-store, and the hosted and embed pages answer a short 410 page from the proxy. The hosted page gets a quiet Report link and the embed one in its top corner, both opening an email to the support address with the playback id.
GET /videos/{id}, /videos/{id}/status and the agent API add takenDown and
null the playback URLs while a video is taken down. The console shows the
video as Taken down rather than failed.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
Sandchest reviewed Sandchest reviews every change for vulnerabilities an attacker could use · 5 credits · Review details |
Member
Author
|
hey @greptileai, please re-review the PR |
Member
Author
|
hey @greptileai, please re-review the PR |
Member
Author
|
hey @greptileai, please re-review the PR |
Member
Author
|
hey @greptileai, please re-review the PR |
# Conflicts: # apps/web/lib/infra-video-upload.ts
Member
Author
|
hey @greptileai, please re-review the PR |
Member
Author
|
hey @greptileai, please re-review the PR |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Viewers of a Cap Infra video had no way to report abuse, and staff had no quick way to switch a single video off. This adds both.
What changes
/dev/{playbackId}) has a small "Report" link beside the title. The embed has one in its top corner that only shows while the pointer is over a player with its controls showing, or on keyboard focus. Both open an email to hello@cap.so with the subjectReport video {playbackId}.410 Gone:/api/developer/playback/{playbackId}/{file}(master and rendition playlists, segments,video.mp4,poster.jpg, anything else) answers a plain410withCache-Control: no-store. OPTIONS is unchanged.noindex. The page itself answers 200, which is fine because nothing on it can play.GET /videos,GET /videos/{id},GET /videos/{id}/statusand the agent API addtakenDown(falsefor every other video). While it istrue,hlsUrl,mp4UrlandposterUrlarenull.status,metadataand every other field read as before. OpenAPI and the REST docs list the field.How it is stored
No migration. The flag lives under a reserved key in
developer_videos.metadata, which onlycreateUploadwrites, and which now drops that key from anything a developer sends. Taking a video down wraps the developer's own metadata inside the marker, and restoring writes it back. Both rewrites run in SQL (JSON_OBJECT/JSON_EXTRACT), so metadata never passes throughJSON.parseand large integers in it come back exactly. I checked the round trip on MySQL 8 with an object holding a 20 digit integer,{}, an array, JSONnulland SQLNULL.statusis never touched, so storage billing (which groups bystatus) and the minimum charges read a taken down video exactly like before: a ready video stays billed as ready. The switch writes only themetadatacolumn, which a test checks.How to take a video down and restore it
The script calls
POST /api/admin/developer-video-takedown, gated by the existingrequireAdmin()staff check. Because the session cookie isSameSite=None, the route only acceptsapplication/jsonwith noOriginor a same-origin one. Playback answers the change on the next request; cached200/302answers from before a takedown expire within the existing 60 second cache.Signed media links a player already loaded before the takedown keep working until they expire, at most 18 hours later, because the stored files are kept so a restore is exact. Revoking those would need a storage-level deny and is not part of this change. When content has to disappear at once, deleting the video purges its files.
Regular playback and share pages
Videos that were never taken down answer exactly as before (same redirects, headers and cache-control), proven by a test that snapshots every file before a takedown and compares after a restore.
proxy.tsis not touched, so no request gains a database read; the page and playback route read the flag from the row they already load. Regular/s/share pages do not share any of this code.Tests
developer-video-takedown-playback.test.ts: 410 for every file, GET and HEAD, ahead of the out of credit pause; restore gives byte-identical responses with and without developer metadata.developer-video-takedown.test.ts: marker, SQL, the switch (by playback id, video id and URLs; idempotent; onlymetadatawritten), the staff route (staff only, JSON only, cross-site refused), the script, the API fields and the console state.developer-video-page.test.ts: the report links, and the unavailable view on both pages with no source URLs, title, size or links, andnoindex.Full web unit suite passes locally except
share-stage-identity.test.ts, which fails on Node 26 (localStorage) on main too and passes in CI.

Confidence Score: 5/5
The PR appears safe to merge; no new blocking issue was found.Summary
Adds report links and a reversible staff takedown for Cap Infra videos.
Reviews (7) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile