Skip to content

[SLOP(gpt-5)] fix(frontend): serve engine UI assets under ui base#5235

Open
NathanFlurry wants to merge 1 commit into
mainfrom
stack/slop-gpt-5-fix-frontend-serve-engine-ui-assets-under-ui-base-tryzpuly
Open

[SLOP(gpt-5)] fix(frontend): serve engine UI assets under ui base#5235
NathanFlurry wants to merge 1 commit into
mainfrom
stack/slop-gpt-5-fix-frontend-serve-engine-ui-assets-under-ui-base-tryzpuly

Conversation

@NathanFlurry

Copy link
Copy Markdown
Member

No description provided.

@NathanFlurry

Copy link
Copy Markdown
Member Author

Stack for rivet-dev/rivet

Get stack: forklift get 5235
Push local edits: forklift submit
Merge when ready: forklift merge 5235

@railway-app

railway-app Bot commented Jun 12, 2026

Copy link
Copy Markdown

🚅 Deployed to the rivet-pr-5235 environment in rivet-frontend

Service Status Web Updated (UTC)
website 😴 Sleeping (View Logs) Web Jun 12, 2026 at 7:14 pm
kitchen-sink ❌ Build Failed (View Logs) Web Jun 12, 2026 at 7:10 pm
frontend-inspector ❌ Build Failed (View Logs) Web Jun 12, 2026 at 7:05 pm
mcp-hub ✅ Success (View Logs) Web Jun 12, 2026 at 7:02 pm
ladle ❌ Build Failed (View Logs) Web Jun 12, 2026 at 7:02 pm
frontend-cloud ❌ Build Failed (View Logs) Web Jun 12, 2026 at 7:02 pm

@claude

claude Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review

This PR fixes a real issue with Vite-built frontends: the build output places JS/CSS under assets/, which generates absolute-path references like /assets/index.js. Without a top-level /assets/ route, those requests 404. The fix is correct and the refactor into serve_file is clean.

A few things to address:

Path traversal (minor)

serve_asset constructs the lookup key via string concatenation:

let file_path = format!("assets/{}", path.trim_start_matches('/'));

A crafted request like /assets/../index.html would produce "assets/../index.html" as the lookup key. Since include_dir is an embedded, read-only, compile-time filesystem the blast radius is limited to files already bundled, but it is still unintended access. Add a guard:

if path.contains("../") || path.contains("..%2F") {
    return StatusCode::BAD_REQUEST.into_response();
}

Auth bypass scope

The middleware exempts all paths starting with /assets/ unconditionally. That's fine for public static UI assets, but it is a permanent open door at the router level. A short comment explaining the intent would help future readers avoid widening it further.

Inconsistent tracing instrumentation

serve_asset is decorated with #[tracing::instrument(skip_all)] but serve_ui is not, even though both are request handlers in the same file. Either add the attribute to serve_ui as well or remove it from serve_asset for consistency.

Missing MIME types

The content-type table is missing a few types that modern Vite builds produce:

  • .wasmapplication/wasm
  • .map (source maps) → application/json or application/octet-stream
  • .webpimage/webp

These will fall through to application/octet-stream, which browsers will refuse to execute for JS/WASM. Source maps would still work, but wasm modules would not load without the correct MIME type.

Nit

serve_file is purely synchronous but both call sites are async fn. That is fine as-is. Just confirming this is intentional and not a sign that future blocking I/O will sneak in.

Overall the approach is correct and the duplication removal is welcome. Addressing the WASM MIME type and path traversal guard before merge would be the highest-priority items.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant