-
Notifications
You must be signed in to change notification settings - Fork 1
Fix error on login page on prod. domain. #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,15 +3,21 @@ require('dotenv').config({ path: '../.env' }); | |||||||||||||||||||||||||||||||||||||
| const { getEnv } = require('./utils/env'); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| function createAposConfig() { | ||||||||||||||||||||||||||||||||||||||
| const isProduction = process.env.NODE_ENV === 'production'; | ||||||||||||||||||||||||||||||||||||||
| const baseUrl = getEnv('BASE_URL') || (isProduction ? 'https://speedandfunction.com' : 'http://localhost:3000'); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||
| shortName: 'apostrophe-site', | ||||||||||||||||||||||||||||||||||||||
| baseUrl: getEnv('BASE_URL'), | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| baseUrl: baseUrl, | ||||||||||||||||||||||||||||||||||||||
| // Session configuration | ||||||||||||||||||||||||||||||||||||||
| modules: { | ||||||||||||||||||||||||||||||||||||||
| // Core modules configuration | ||||||||||||||||||||||||||||||||||||||
| '@apostrophecms/express': { | ||||||||||||||||||||||||||||||||||||||
| options: { | ||||||||||||||||||||||||||||||||||||||
| // Trust proxy for Railway deployment | ||||||||||||||||||||||||||||||||||||||
| trustProxy: true, | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| session: { | ||||||||||||||||||||||||||||||||||||||
| // If using Redis (recommended for production) | ||||||||||||||||||||||||||||||||||||||
| secret: getEnv('SESSION_SECRET'), | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -21,20 +27,70 @@ function createAposConfig() { | |||||||||||||||||||||||||||||||||||||
| url: getEnv('REDIS_URI'), | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| cookie: { | ||||||||||||||||||||||||||||||||||||||
| // Set domain for production to work with custom domain | ||||||||||||||||||||||||||||||||||||||
| domain: isProduction ? '.speedandfunction.com' : undefined, | ||||||||||||||||||||||||||||||||||||||
| secure: isProduction, | ||||||||||||||||||||||||||||||||||||||
| sameSite: 'lax', | ||||||||||||||||||||||||||||||||||||||
| httpOnly: true, | ||||||||||||||||||||||||||||||||||||||
| maxAge: 24 * 60 * 60 * 1000, // 24 hours | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| csrf: { | ||||||||||||||||||||||||||||||||||||||
| cookie: { | ||||||||||||||||||||||||||||||||||||||
| key: '_csrf', | ||||||||||||||||||||||||||||||||||||||
| path: '/', | ||||||||||||||||||||||||||||||||||||||
| httpOnly: true, | ||||||||||||||||||||||||||||||||||||||
| secure: process.env.NODE_ENV === 'production', | ||||||||||||||||||||||||||||||||||||||
| secure: isProduction, | ||||||||||||||||||||||||||||||||||||||
| sameSite: 'lax', | ||||||||||||||||||||||||||||||||||||||
| maxAge: 3600, | ||||||||||||||||||||||||||||||||||||||
| // CRITICAL: Set domain for CSRF cookie to work with custom domain | ||||||||||||||||||||||||||||||||||||||
| domain: isProduction ? '.speedandfunction.com' : undefined, | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| // Additional CSRF options for better security | ||||||||||||||||||||||||||||||||||||||
| ignoreMethods: ['GET', 'HEAD', 'OPTIONS'], | ||||||||||||||||||||||||||||||||||||||
| value: (req) => { | ||||||||||||||||||||||||||||||||||||||
| return req.body && req.body._csrf || | ||||||||||||||||||||||||||||||||||||||
| req.query && req.query._csrf || | ||||||||||||||||||||||||||||||||||||||
| req.headers['x-csrf-token'] || | ||||||||||||||||||||||||||||||||||||||
| req.headers['x-xsrf-token'] || | ||||||||||||||||||||||||||||||||||||||
| req.headers['csrf-token']; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| // Add middleware to handle domain-specific headers | ||||||||||||||||||||||||||||||||||||||
| middleware: [ | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| before: '@apostrophecms/csrf', | ||||||||||||||||||||||||||||||||||||||
| middleware: (req, res, next) => { | ||||||||||||||||||||||||||||||||||||||
| // Ensure proper headers for custom domain | ||||||||||||||||||||||||||||||||||||||
| if (req.hostname === 'speedandfunction.com' || req.get('host') === 'speedandfunction.com') { | ||||||||||||||||||||||||||||||||||||||
| req.headers['x-forwarded-host'] = 'speedandfunction.com'; | ||||||||||||||||||||||||||||||||||||||
| req.headers['x-forwarded-proto'] = 'https'; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| // Set CORS headers for API requests | ||||||||||||||||||||||||||||||||||||||
| const allowedOrigins = [ | ||||||||||||||||||||||||||||||||||||||
| 'https://speedandfunction.com', | ||||||||||||||||||||||||||||||||||||||
| 'https://apostrophe-cms-production.up.railway.app' | ||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
| if (req.hostname === 'speedandfunction.com' || req.get('host') === 'speedandfunction.com') { | |
| req.headers['x-forwarded-host'] = 'speedandfunction.com'; | |
| req.headers['x-forwarded-proto'] = 'https'; | |
| } | |
| // Set CORS headers for API requests | |
| const allowedOrigins = [ | |
| 'https://speedandfunction.com', | |
| 'https://apostrophe-cms-production.up.railway.app' | |
| ]; | |
| const customDomain = process.env.CUSTOM_DOMAIN || 'speedandfunction.com'; | |
| if (req.hostname === customDomain || req.get('host') === customDomain) { | |
| req.headers['x-forwarded-host'] = customDomain; | |
| req.headers['x-forwarded-proto'] = 'https'; | |
| } | |
| // Set CORS headers for API requests | |
| const allowedOrigins = (process.env.ALLOWED_ORIGINS || 'https://speedandfunction.com,https://apostrophe-cms-production.up.railway.app').split(','); |
🤖 Prompt for AI Agents
In website/app.js around lines 68 to 77, the domain and CORS allowed origins are
hardcoded, which reduces maintainability. Refactor the code to read these values
from environment variables instead of hardcoding them. Update the hostname
checks and the allowedOrigins array to use environment variables, providing
sensible defaults if needed, so the domains can be easily changed without
modifying the source code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Consider fail-fast approach for BASE_URL environment variable
The current implementation uses
getEnv('BASE_URL') || ...which provides a fallback, but this contradicts the project's fail-fast approach for required environment variables (as mentioned in the learnings). IfBASE_URLis a required configuration, consider:Or if
BASE_URLshould be optional:Let me verify the
getEnvfunction signature to understand if it supports default values:🏁 Script executed:
Length of output: 295
Fix unreachable fallback due to getEnv signature
The helper
getEnv(name)only accepts a single argument and throws if the variable is undefined, sowill never fall back. To provide a default you must use
process.envfor optional variables or split logic:• If
BASE_URLis optional (with a built-in fallback for all environments):• If you want to fail-fast in production but allow a dev fallback:
Please update lines 6–7 in
website/app.jsaccordingly so fallbacks behave as intended.🤖 Prompt for AI Agents