fix: added better origin handling for contact form submission
All checks were successful
Deploy Jody's App / build-and-deploy (push) Successful in 34s

This commit is contained in:
2026-02-18 22:39:03 -06:00
parent 0ae4affe20
commit a7b80c8318
3 changed files with 16 additions and 7 deletions

View File

@@ -1,8 +1,8 @@
NODE_ENV=production
PORT=8787
CONTACT_ALLOWED_ORIGIN=http://localhost:5173,https://jodyholt.com,https://www.jodyholt.com
CONTACT_ALLOWED_ORIGIN=https://jodyholt.com,https://www.jodyholt.com
TURNSTILE_EXPECTED_HOSTNAME=jodyholt.com,www.jodyholt.com
TURNSTILE_SECRET_KEY=0x4AAAAAACfQyRwRzwsEMIfVtCSkjz7__Yc
TURNSTILE_EXPECTED_HOSTNAME=jodyholt.com
TURNSTILE_EXPECTED_ACTION=contact_form
SMTP_HOST=mail.jodyholt.com
SMTP_PORT=587

View File

@@ -10,7 +10,9 @@ const boolFromEnv = z
const envSchema = z.object({
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
PORT: z.coerce.number().int().positive().default(8787),
CONTACT_ALLOWED_ORIGIN: z.string().url(),
// Comma-separated list of allowed browser origins, e.g.
// https://jodyholt.com,https://www.jodyholt.com
CONTACT_ALLOWED_ORIGIN: z.string().min(1),
TURNSTILE_SECRET_KEY: z.string().min(1),
TURNSTILE_EXPECTED_HOSTNAME: z.string().min(1),
TURNSTILE_EXPECTED_ACTION: z.string().min(1).default("contact_form"),

View File

@@ -16,12 +16,19 @@ type ApiErrorResponse = {
const app = express();
app.set("trust proxy", 1);
const normalizeOrigin = (value: string): string =>
value
const normalizeOrigin = (value: string): string => {
const cleaned = value
.trim()
.replace(/^['"]|['"]$/g, "")
.replace(/\/+$/g, "")
.toLowerCase();
.replace(/\/+$/g, "");
// Some clients can emit explicit default ports. URL.origin normalizes them.
try {
return new URL(cleaned).origin.toLowerCase();
} catch {
return cleaned.toLowerCase();
}
};
const allowedOrigins = config.CONTACT_ALLOWED_ORIGIN
.split(",")