removed duplicate reference of allowed_origin in env (bruh moment)
All checks were successful
Deploy Jody's App / build-and-deploy (push) Successful in 33s
All checks were successful
Deploy Jody's App / build-and-deploy (push) Successful in 33s
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
PORT=8787
|
PORT=8787
|
||||||
CONTACT_ALLOWED_ORIGIN=https://jodyholt.com
|
CONTACT_ALLOWED_ORIGIN=https://www.jodyholt.com
|
||||||
TURNSTILE_SECRET_KEY=0x4AAAAAACfQyRwRzwsEMIfVtCSkjz7__Yc
|
TURNSTILE_SECRET_KEY=0x4AAAAAACfQyRwRzwsEMIfVtCSkjz7__Yc
|
||||||
TURNSTILE_EXPECTED_HOSTNAME=jodyholt.com
|
TURNSTILE_EXPECTED_HOSTNAME=jodyholt.com
|
||||||
TURNSTILE_EXPECTED_ACTION=contact_form
|
TURNSTILE_EXPECTED_ACTION=contact_form
|
||||||
@@ -18,4 +18,3 @@ RATE_LIMIT_WINDOW_MS=600000
|
|||||||
RATE_LIMIT_MAX=5
|
RATE_LIMIT_MAX=5
|
||||||
HONEYPOT_FIELD=website
|
HONEYPOT_FIELD=website
|
||||||
MIN_SUBMIT_TIME_MS=3000
|
MIN_SUBMIT_TIME_MS=3000
|
||||||
CONTACT_ALLOWED_ORIGIN=https://www.jodyholt.com
|
|
||||||
@@ -16,6 +16,18 @@ type ApiErrorResponse = {
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.set("trust proxy", 1);
|
app.set("trust proxy", 1);
|
||||||
|
|
||||||
|
const normalizeOrigin = (value: string): string =>
|
||||||
|
value
|
||||||
|
.trim()
|
||||||
|
.replace(/^['"]|['"]$/g, "")
|
||||||
|
.replace(/\/+$/g, "")
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
const allowedOrigins = config.CONTACT_ALLOWED_ORIGIN
|
||||||
|
.split(",")
|
||||||
|
.map(normalizeOrigin)
|
||||||
|
.filter((value, index, all) => value.length > 0 && all.indexOf(value) === index);
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
pinoHttp({
|
pinoHttp({
|
||||||
level: config.NODE_ENV === "production" ? "info" : "debug",
|
level: config.NODE_ENV === "production" ? "info" : "debug",
|
||||||
@@ -30,7 +42,13 @@ app.use(helmet());
|
|||||||
app.use(
|
app.use(
|
||||||
cors({
|
cors({
|
||||||
origin(origin, callback) {
|
origin(origin, callback) {
|
||||||
if (!origin || origin === config.CONTACT_ALLOWED_ORIGIN) {
|
if (!origin) {
|
||||||
|
callback(null, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedOrigin = normalizeOrigin(origin);
|
||||||
|
if (allowedOrigins.includes(normalizedOrigin)) {
|
||||||
callback(null, true);
|
callback(null, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,18 @@ type TurnstileVerifyResponse = {
|
|||||||
"error-codes"?: string[];
|
"error-codes"?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const normalizeHostname = (value: string): string =>
|
||||||
|
value
|
||||||
|
.trim()
|
||||||
|
.replace(/^['"]|['"]$/g, "")
|
||||||
|
.replace(/\.+$/g, "")
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
const expectedHostnames = config.TURNSTILE_EXPECTED_HOSTNAME
|
||||||
|
.split(",")
|
||||||
|
.map(normalizeHostname)
|
||||||
|
.filter((value, index, all) => value.length > 0 && all.indexOf(value) === index);
|
||||||
|
|
||||||
export async function verifyTurnstileToken(
|
export async function verifyTurnstileToken(
|
||||||
token: string,
|
token: string,
|
||||||
remoteIp?: string,
|
remoteIp?: string,
|
||||||
@@ -36,7 +48,7 @@ export async function verifyTurnstileToken(
|
|||||||
return { ok: false, reason: codes };
|
return { ok: false, reason: codes };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.hostname !== config.TURNSTILE_EXPECTED_HOSTNAME) {
|
if (!result.hostname || !expectedHostnames.includes(normalizeHostname(result.hostname))) {
|
||||||
return { ok: false, reason: "hostname_mismatch" };
|
return { ok: false, reason: "hostname_mismatch" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user