Fix production signup API URL and harden CORS origin config#25
Conversation
Reviewer's GuideThis pull request switches the frontend from a hardcoded localhost signup URL to a configurable API base URL with production-safe behavior and adds diagnostics around signup failures, while on the backend it replaces a single-origin CORS setting with a stricter, multi-origin configuration that fails fast when misconfigured in production. Sequence diagram for signup request with API_BASE_URL and CORS validationsequenceDiagram
actor User
participant FrontendApp
participant BackendServer
participant CorsMiddleware
User->>FrontendApp: Submit signup form
FrontendApp->>FrontendApp: Compute API_BASE_URL from VITE_API_URL or localhost
FrontendApp->>BackendServer: fetch(API_BASE_URL + "/api/register")
BackendServer->>CorsMiddleware: origin(origin, callback)
alt origin allowed
CorsMiddleware-->>BackendServer: callback(null, true)
BackendServer-->>FrontendApp: Response (status, body)
FrontendApp->>FrontendApp: Log status, error body on failure
else origin blocked
CorsMiddleware-->>BackendServer: callback(Error("CORS blocked for origin"))
BackendServer-->>FrontendApp: Network/CORS error
FrontendApp->>FrontendApp: console.error("Register request network/CORS error")
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The additional console logging around signup/login is useful for diagnostics but may be noisy in production; consider gating these logs behind an environment flag or removing them once the issue is resolved.
- In the AuthScreen handler, you already compute
requestUrl; using that variable in the signup debug log instead of re-constructing the URL would keep the logging consistent and reduce the chance of the log diverging from the actual request target. - The CORS origin callback currently throws an error for disallowed origins, which will surface as a generic server error; if you want clearer behavior for clients, consider returning a controlled 403-style response or a specific error body for blocked origins.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The additional console logging around signup/login is useful for diagnostics but may be noisy in production; consider gating these logs behind an environment flag or removing them once the issue is resolved.
- In the AuthScreen handler, you already compute `requestUrl`; using that variable in the signup debug log instead of re-constructing the URL would keep the logging consistent and reduce the chance of the log diverging from the actual request target.
- The CORS origin callback currently throws an error for disallowed origins, which will surface as a generic server error; if you want clearer behavior for clients, consider returning a controlled 403-style response or a specific error body for blocked origins.
## Individual Comments
### Comment 1
<location path="server.js" line_range="152-156" />
<code_context>
+ process.exit(1);
+}
+
app.use(cors({
- origin: ALLOWED_ORIGIN,
+ origin(origin, callback) {
+ if (!origin) return callback(null, true);
+ if (allowedOrigins.has(origin)) return callback(null, true);
+ return callback(new Error(`CORS blocked for origin: ${origin}`));
+ },
methods: ['GET', 'POST'],
</code_context>
<issue_to_address>
**issue (bug_risk):** Returning an Error from the CORS origin callback will surface as a generic 500 instead of a clean CORS rejection.
Using `callback(new Error(...))` here makes CORS failures look like internal server errors (500) rather than a normal CORS rejection. Instead, return `callback(null, false)` for disallowed origins so the middleware cleanly denies the request. If you want observability, log the blocked origin separately but keep the callback as `callback(null, false)` to avoid misleading 500s for clients.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| app.use(cors({ | ||
| origin: ALLOWED_ORIGIN, | ||
| origin(origin, callback) { | ||
| if (!origin) return callback(null, true); | ||
| if (allowedOrigins.has(origin)) return callback(null, true); | ||
| return callback(new Error(`CORS blocked for origin: ${origin}`)); |
There was a problem hiding this comment.
issue (bug_risk): Returning an Error from the CORS origin callback will surface as a generic 500 instead of a clean CORS rejection.
Using callback(new Error(...)) here makes CORS failures look like internal server errors (500) rather than a normal CORS rejection. Instead, return callback(null, false) for disallowed origins so the middleware cleanly denies the request. If you want observability, log the blocked origin separately but keep the callback as callback(null, false) to avoid misleading 500s for clients.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c27c388486
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const ALLOWED_ORIGINS = (process.env.ALLOWED_ORIGINS || '') | ||
| .split(',') | ||
| .map(origin => origin.trim()) | ||
| .filter(Boolean); |
There was a problem hiding this comment.
Keep legacy ALLOWED_ORIGIN as CORS fallback
This change only reads ALLOWED_ORIGINS/FRONTEND_URL, so environments that were valid in the previous release with only ALLOWED_ORIGIN configured now produce an empty allowedOrigins set and immediately hit the production process.exit(1) path during startup. That creates a deploy-time outage for existing installations unless they also happened to set the new variables, so the old variable should be supported as a compatibility fallback (or migrated explicitly before enforcing the new keys).
Useful? React with 👍 / 👎.
| // ───────────────────────────────────────────────────────────────────────────── | ||
| const IS_PROD = process.env.NODE_ENV === 'production'; | ||
| const FRONTEND_URL = process.env.FRONTEND_URL || 'http://localhost:5173'; | ||
| const FRONTEND_URL = process.env.FRONTEND_URL || ''; |
There was a problem hiding this comment.
Validate FRONTEND_URL before checkout URL construction
By changing FRONTEND_URL to default to an empty string, the server can now start in production when only ALLOWED_ORIGINS is set, but checkout still builds Stripe success_url/cancel_url from FRONTEND_URL; in that configuration those URLs become relative (e.g. ?checkout=success...) and Stripe session creation fails, breaking paid upgrades. Add a production guard that requires a non-empty absolute FRONTEND_URL whenever checkout is enabled, or derive the redirect base from a validated configured origin.
Useful? React with 👍 / 👎.
Motivation
http://localhost:3001/api/registerinstead of the deployed backend, causing production signup to fail.Description
API_BASE_URLusingimport.meta.env.VITE_API_URL || (import.meta.env.DEV ? 'http://localhost:3001' : '')and throwing when missing in production, and updated all client fetches to useAPI_BASE_URL. (file:app.tsx)app.tsx)ALLOWED_ORIGINS(comma-separated) andFRONTEND_URL, include common localhost origins in non-production, and fail fast in production if no allowed origin is configured; CORS now uses a function to validate incoming origins. (file:server.js)app.tsxandserver.js(frontend base URL + request diagnostics, backend origin configuration).Testing
localhost:3001,127.0.0.1,/api/register,register,Create Free Account,fetch(, andaxiosto locate the affected code paths; the client auth handler and multiplefetchcalls were updated. (search ran successfully)npm run build; the build failed due to pre-existing TypeScript/dependency issues in this environment (missingreact/type declarations andimport.meta.envtyping), not due to the URL/CORS changes.Notes / Deployment instructions: set the following Render environment variables in your Render dashboard: for the frontend
VITE_API_URL=https://YOUR_BACKEND_RENDER_SERVICE.onrender.com, and for the backendFRONTEND_URL=https://YOUR_FRONTEND_RENDER_SERVICE.onrender.comorALLOWED_ORIGINS=https://YOUR_FRONTEND_RENDER_SERVICE.onrender.com,https://www.yourcustomdomain.com(keep localhost origins allowed for development).Codex Task
Summary by Sourcery
Configure the frontend to use an environment-based API base URL and harden backend CORS origin handling to work correctly in production.
New Features:
Bug Fixes:
Enhancements: