Repository navigation
Serve video and poster previews for invite links - #9306
Conversation
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez <klopez4212@gmail.com>
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🔐 Codex Security Review
Review SummaryOverall Risk: NONE
FindingsNo concrete security, correctness, or reliability findings were identified. Notes
Generated by Codex Security Review | |
TheSentinel454
left a comment
There was a problem hiding this comment.
🤖 Small, well-contained change that never inspects or redeems the invite. One recommended blocker (media origin source) and two optional notes inline.
| { | ||
| name: "invite-preview-media", | ||
| generateBundle() { | ||
| for (const [source, output] of [ | ||
| ["buzz-invite-loop.mp4", "buzz-invite-loop-v1.mp4"], | ||
| ["buzz-invite-poster.png", "buzz-invite-poster-v1.png"], | ||
| ]) { | ||
| this.emitFile({ | ||
| type: "asset", | ||
| fileName: `assets/invite-preview/${output}`, | ||
| source: readFileSync( | ||
| new URL(`../previews/invite-video/${source}`, import.meta.url), | ||
| ), | ||
| }); | ||
| } | ||
| }, | ||
| }, |
There was a problem hiding this comment.
🤖 Optional simplification: moving the two approved files to web/public/assets/invite-preview/ (Vite copies public/ verbatim into dist/) would remove this plugin, the readFileSync, and the Dockerfile COPY line, since web/ is already copied. The render script would write there instead.
| for (name, mime) in [ | ||
| ("buzz-invite-loop-v1.mp4", "video/mp4"), | ||
| ("buzz-invite-poster-v1.png", "image/png"), | ||
| ] { | ||
| let path = format!("/assets/invite-preview/{name}"); | ||
| for method in ["GET", "HEAD"] { | ||
| let response = build_router(state.clone()) | ||
| .oneshot( | ||
| Request::builder() | ||
| .method(method) | ||
| .uri(&path) | ||
| .header("host", "public.example") | ||
| .body(Body::empty()) | ||
| .unwrap(), | ||
| ) | ||
| .await | ||
| .unwrap(); | ||
| assert_eq!(response.status(), StatusCode::OK); | ||
| assert_eq!(response.headers()["content-type"], mime); | ||
| assert!( | ||
| response.headers()["content-length"] | ||
| .to_str() | ||
| .unwrap() | ||
| .parse::<usize>() | ||
| .unwrap() | ||
| > 1000 | ||
| ); | ||
| } | ||
| let response = build_router(state.clone()) | ||
| .oneshot( | ||
| Request::get(&path) | ||
| .header("host", "public.example") | ||
| .header("range", "bytes=0-31") | ||
| .body(Body::empty()) | ||
| .unwrap(), | ||
| ) | ||
| .await | ||
| .unwrap(); | ||
| assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT); | ||
| let bytes = axum::body::to_bytes(response.into_body(), usize::MAX) | ||
| .await | ||
| .unwrap(); | ||
| assert_eq!(bytes.len(), 32); | ||
| } |
There was a problem hiding this comment.
🤖 Optional: this half of the test (GET/HEAD/range on the media files, plus the real-TCP range fetch above) mostly exercises tower-http's ServeDir, not this PR's code, and include_bytes! pulls the real 1.4 MB MP4 into the test binary. Small synthetic bytes would cover the routing assertions; the metadata/host/admin-isolation assertions are the valuable part.
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez <klopez4212@gmail.com>
TheSentinel454
left a comment
There was a problem hiding this comment.
🤖 Approving at eac46e2: media origin now binds to the resolved community host and fails closed. Thanks for the quick fix.
…e-mode * origin/main: ci(docker): skip relay image publishes for main pushes outside the build context (#9310) Add manual-only relay image publishing (#9303) fix(mobile): bump Flutter to 3.47.9 for Android TLS fix (#9309) Serve video and poster previews for invite links (#9306) docs: point the README to Buzz 1.0 in block/buzz-app (#9296) fix(db): give the replica-fence probe its own pool and instrument it (#9297) fix(relay): never close connections when cross-node fan-out falls behind (#9302) test: fix timing-dependent unit tests in buzz-cli, buzz-agent and buzz-admin (#9273) fix(ci): classify hermit retry timeouts by watchdog kill, not whole seconds (#9274) test(ios): wait for a key, foreground-active window before presenting in RunnerTests (#9275) test(desktop): wait on real readiness signals in audience and community-rail specs (#9277) Signed-off-by: Will Pfleger <wpfleger@block.xyz>
* origin/main: Add swipeable photo stacks and native iOS gallery preview (#9259) ci(docker): skip relay image publishes for main pushes outside the build context (#9310) Add manual-only relay image publishing (#9303) fix(mobile): bump Flutter to 3.47.9 for Android TLS fix (#9309) Serve video and poster previews for invite links (#9306) docs: point the README to Buzz 1.0 in block/buzz-app (#9296) Signed-off-by: Philip Azar <pazar@squareup.com>
**Context:** #9306 (merged) added link-preview tags to the invite page. To build the media URLs, the relay looks up the community for the request host. This fixes a problem found in our review of #9306. **Problem:** The invite page waits for that lookup with no time limit. When the database is slow, the lookup can take as long as the pool acquire timeout (3 s) plus the statement timeout (120 s by default). During that time, a person who opens an invite link gets no page. Before #9306, this page did not use the database. **Fix:** The lookup gets 250 ms. If it does not finish, the relay sends the page without the preview tags. A healthy indexed host lookup finishes well inside that, so crawlers still get the tags, and nothing else changes: the media route, the router and the build are untouched. ### Validation - Added test: a host whose lookup never finishes gets the plain page. Without the timeout, this test hangs (confirmed locally; it was killed after 30 s). - The existing `invite_preview` and router invite tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Tom Brow <tomb@squareup.com> Co-authored-by: Tom Brow <tomb@squareup.com> Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
Invite links currently return HTML without preview metadata. Add server-rendered
og:videoandog:imagetags for/invite/<code>, and bundle the approved MP4 and wordmark-only poster from #9282 into the relay image. Media URLs use the request’s resolved community host, with only TLS posture fromRELAY_URL. Unknown hosts and lookup failures receive no metadata; previews stay generic and never redeem invites.Validation: production web build, workspace Clippy, 52 router tests (including real HTTP and MP4 range requests), metadata tests, and independent agent review pass.
just cistops at unrelated mobile dependency/format checks. The full relay suite was attempted but stopped during database-dependent tests without local infrastructure. Broad local Rust/desktop hooks were stopped for disk pressure; desktop/mobile hooks also lack dependencies and were skipped to publish this draft. Full-stack and native Messages playback remain unverified. The new preview regressions run in both CI test-runner paths.Rollout: merge and deploy the resulting relay image with its web bundle, verify the invite HTML and both public media URLs, then share a fresh invite in Messages. Full-stack and human validation remain outstanding.