Skip to content

fix(api): let the docs' Try it panel call the REST API - #242

Merged
clbotdev merged 3 commits into
mainfrom
api-docs-cors
Oct 31, 2026
Merged

clbotdev merged 3 commits into
mainfrom
api-docs-cors

Conversation

@clbotdev

@clbotdev clbotdev commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

The API reference at https://medialit.cloud/docs/api has a "Try it" panel that calls api.medialit.cloud from the browser. Only /media/create and resumable uploads sent CORS headers, so every other endpoint failed its preflight, and "Try it" didn't work for most of the API.

One CORS rule in app.ts now covers /health, /media and /settings/media:

Endpoints Allowed origins Why
/media/create, /media/create/resumable* any Browsers upload from customers' own sites with a short-lived signature. Same as before.
Everything else (get, list, count, size, seal, delete, signature, settings, health) https://medialit.cloud only These need an API key, which belongs on a server. Only the docs' "Try it" panel calls them from a browser, so other sites trying it fail straight away instead of quietly putting a key in front-end code.
  • The per-route cors() calls on the upload routes are gone, because the app-level rule now covers them.
  • The cookie-based dashboard API under /api/... stays same-origin. The dashboard and the medialit SDK don't call the restricted endpoints from a browser: the dashboard goes through its own /api/apps/... routes, and the SDK runs on the server.

rest-cors.test.ts runs against the real app and checks that:

  • the docs origin can preflight the API-key endpoints with x-medialit-apikey;
  • another origin can't;
  • any origin can preflight the upload endpoints, including resumable ones and with a query string;
  • /api/apps doesn't allow other origins.

All 149 API tests, typecheck and lint pass.

Separately: bun run swagger:generate on main adds a content-length header parameter to swagger_output.json. That's existing drift that this change doesn't cause, so it's left out of this PR.

s3rot0n1n and others added 2 commits October 31, 2026 22:53
The "Try it" panel at medialit.cloud/docs/api calls api.medialit.cloud
from the browser, but only /media/create and resumable uploads sent CORS
headers, so every other endpoint failed its preflight.

The REST API authenticates with an API key or bearer token, never a
cookie, so allow any origin on /health, /media and /settings/media in
one place instead of per route. The cookie-based dashboard API under
/api stays same-origin.

Co-Authored-By: Claude <noreply@anthropic.com>
Uploads keep accepting any origin, since browsers upload from customers'
own sites with a signature. Every other REST endpoint needs an API key,
which belongs on a server, so only https://medialit.cloud (the docs'
"Try it" panel) may call those from a browser.

Co-Authored-By: Claude <noreply@anthropic.com>
@clbotdev clbotdev changed the title fix(api): allow cross-origin calls to the REST API fix(api): let the docs' Try it panel call the REST API Oct 31, 2026
tus clients such as CourseLit read the uploaded media from the media
response header, which browsers only expose across origins when the
response lists it.

Co-Authored-By: Claude <noreply@anthropic.com>
@clbotdev
clbotdev merged commit bdb2306 into main Oct 31, 2026
4 of 5 checks passed
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.

2 participants