feat(api): add CORS headers for browser clients#94
feat(api): add CORS headers for browser clients#94MaudeBot wants to merge 1 commit intoopenclaw:mainfrom
Conversation
- Add convex/lib/cors.ts with shared CORS headers and preflight handler - Update httpApi.ts and httpApiV1.ts json/text helpers to include CORS headers - Update downloads.ts to include CORS headers on all responses - Add single OPTIONS handler for /api/* prefix in http.ts This enables browser-based clients (like Cove WebUI) to fetch skills directly from the ClawHub API without CORS errors. Allows: GET, POST, DELETE, OPTIONS from any origin (*)
|
@MaudeBot is attempting to deploy a commit to the Amantus Machina Team on Vercel. A member of the Team first needs to authorize it. |
| // CORS preflight handler for all API routes | ||
| http.route({ | ||
| pathPrefix: '/api/', | ||
| method: 'OPTIONS', | ||
| handler: corsPreflightHttp, | ||
| }) |
There was a problem hiding this comment.
[P1] OPTIONS preflight only registered for /api/ prefix
This adds an OPTIONS handler only for pathPrefix: '/api/' (convex/http.ts:199-204). However, this router also exposes LegacyApiRoutes.* (still under /api in many setups) and potentially other non-/api/ HTTP routes (e.g., auth routes). If any of those endpoints are called cross-origin and trigger a preflight, they’ll still fail with a missing/404 OPTIONS route even though the GET/POST responses now include CORS headers.
If the intent is “all API endpoints,” consider also covering legacy routes (and/or the auth routes) with an OPTIONS handler that matches their prefixes.
Prompt To Fix With AI
This is a comment left during a code review.
Path: convex/http.ts
Line: 199:204
Comment:
[P1] OPTIONS preflight only registered for `/api/` prefix
This adds an OPTIONS handler only for `pathPrefix: '/api/'` (`convex/http.ts:199-204`). However, this router also exposes `LegacyApiRoutes.*` (still under `/api` in many setups) and potentially other non-`/api/` HTTP routes (e.g., auth routes). If any of those endpoints are called cross-origin and trigger a preflight, they’ll still fail with a missing/404 OPTIONS route even though the GET/POST responses now include CORS headers.
If the intent is “all API endpoints,” consider also covering legacy routes (and/or the auth routes) with an OPTIONS handler that matches their prefixes.
How can I resolve this? If you propose a fix, please make it concise.| export const CORS_HEADERS = { | ||
| 'Access-Control-Allow-Origin': '*', | ||
| 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS', | ||
| 'Access-Control-Allow-Headers': 'Content-Type, Authorization', | ||
| 'Access-Control-Max-Age': '86400', // 24 hours | ||
| } as const |
There was a problem hiding this comment.
[P2] Access-Control-Allow-Headers may be too narrow for real browser clients
CORS_HEADERS hard-codes 'Access-Control-Allow-Headers': 'Content-Type, Authorization' (convex/lib/cors.ts:8-13). In practice, browser requests can include other headers that trigger a preflight (e.g., Accept, If-None-Match, Range, X-Requested-With). If a client sends any additional header, the preflight will be rejected even though the server is otherwise willing to serve the request.
Consider either echoing Access-Control-Request-Headers or broadening this list to the headers your clients actually send.
Prompt To Fix With AI
This is a comment left during a code review.
Path: convex/lib/cors.ts
Line: 8:13
Comment:
[P2] `Access-Control-Allow-Headers` may be too narrow for real browser clients
`CORS_HEADERS` hard-codes `'Access-Control-Allow-Headers': 'Content-Type, Authorization'` (`convex/lib/cors.ts:8-13`). In practice, browser requests can include other headers that trigger a preflight (e.g., `Accept`, `If-None-Match`, `Range`, `X-Requested-With`). If a client sends any additional header, the preflight will be rejected even though the server is otherwise willing to serve the request.
Consider either echoing `Access-Control-Request-Headers` or broadening this list to the headers your clients actually send.
How can I resolve this? If you propose a fix, please make it concise.|
Closing - CORS was addressed in #296. Thanks! |
Summary
Adds CORS headers to all API endpoints, enabling browser-based clients to fetch skills directly from the ClawHub API.
Motivation
Browser-based tools like Cove (OpenClaw WebUI) want to display and install skills from ClawHub. Currently, browsers block these requests due to missing CORS headers.
This is standard practice for public package registries — npm, crates.io, and PyPI all allow cross-origin requests.
Changes
convex/lib/cors.ts— Shared CORS headers and preflight response helperconvex/http.ts— Single OPTIONS handler for all/api/*routesconvex/httpApi.ts— CORS headers in json/text response helpersconvex/httpApiV1.ts— CORS headers in json/text helpers + file content endpointsconvex/downloads.ts— CORS headers on download responsesHeaders Added
Safety
Allow-Credentials, so cookies aren't sentGreptile Overview
Greptile Summary
Adds CORS headers across all API endpoints to enable browser-based clients to fetch skills from ClawHub. The implementation is clean and additive - existing CLI/server clients will ignore these headers, and authentication still requires Bearer tokens for protected endpoints.
Key changes:
convex/lib/cors.tsmodule with standard CORS headers and preflight handlerhttpApi.tsandhttpApiV1.tsdownloads.ts/api/*routes inhttp.tsThe approach follows standard patterns used by public package registries like npm and crates.io. No security concerns since
Access-Control-Allow-Credentialsis not set, so cookies/credentials won't be sent in cross-origin requests.Confidence Score: 4/5
convex/http.ts:199andconvex/lib/cors.ts:8should be addressed to ensure comprehensive CORS coverageLast reviewed commit: 29e8ec2