Latest Updated Pages
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 13s
Ping Search Engines / Notify Search Engines (push) Successful in 3s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 1s
E2E Test Suite / Smoke Tests (P0) (push) Failing after 9m36s
E2E Test Suite / Form Interaction Tests (push) Failing after 12m6s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 11m46s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 9m31s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 11m5s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 15m24s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 6s
E2E Test Suite / Mobile Device Tests (push) Failing after 3h12m28s
Uptime Monitor / Health & Response Time (push) Successful in 5s
Uptime Monitor / SSL Certificate (push) Successful in 3s
Uptime Monitor / Send Alerts (push) Has been skipped
Uptime Monitor / Record Uptime Success (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 13s
Ping Search Engines / Notify Search Engines (push) Successful in 3s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 1s
E2E Test Suite / Smoke Tests (P0) (push) Failing after 9m36s
E2E Test Suite / Form Interaction Tests (push) Failing after 12m6s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 11m46s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 9m31s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 11m5s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 15m24s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 6s
E2E Test Suite / Mobile Device Tests (push) Failing after 3h12m28s
Uptime Monitor / Health & Response Time (push) Successful in 5s
Uptime Monitor / SSL Certificate (push) Successful in 3s
Uptime Monitor / Send Alerts (push) Has been skipped
Uptime Monitor / Record Uptime Success (push) Successful in 2s
This commit is contained in:
@@ -190,21 +190,35 @@ function escapeHtml(str: string): string {
|
||||
// ============================================================
|
||||
// CORS headers helper
|
||||
// ============================================================
|
||||
function corsHeaders(): HeadersInit {
|
||||
const origin = import.meta.env.PROD ? 'https://workroot.in' : '*';
|
||||
const ALLOWED_ORIGINS = ['https://workroot.in', 'https://www.workroot.in'];
|
||||
|
||||
function corsHeaders(requestOrigin?: string | null): HeadersInit {
|
||||
if (!import.meta.env.PROD) {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
};
|
||||
}
|
||||
// Reflect the request origin if it is in the allowlist, otherwise default to primary domain
|
||||
const origin = requestOrigin && ALLOWED_ORIGINS.includes(requestOrigin)
|
||||
? requestOrigin
|
||||
: 'https://workroot.in';
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': origin,
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Vary': 'Origin',
|
||||
};
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// OPTIONS preflight handler
|
||||
// ============================================================
|
||||
export const OPTIONS: APIRoute = async () => {
|
||||
return new Response(null, { status: 204, headers: corsHeaders() });
|
||||
export const OPTIONS: APIRoute = async ({ request }) => {
|
||||
return new Response(null, { status: 204, headers: corsHeaders(request.headers.get('origin')) });
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
@@ -213,11 +227,12 @@ export const OPTIONS: APIRoute = async () => {
|
||||
export const POST: APIRoute = async ({ request, clientAddress }) => {
|
||||
const ip = clientAddress ?? 'unknown';
|
||||
const startTime = Date.now();
|
||||
const requestOrigin = request.headers.get('origin');
|
||||
|
||||
// Rate limiting check
|
||||
const rateLimit = checkRateLimit(ip);
|
||||
const rateLimitHeaders = {
|
||||
...corsHeaders(),
|
||||
...corsHeaders(requestOrigin),
|
||||
'X-RateLimit-Limit': String(RATE_LIMIT_MAX_REQUESTS),
|
||||
'X-RateLimit-Remaining': String(rateLimit.remaining),
|
||||
'X-RateLimit-Reset': String(Math.ceil(rateLimit.resetAt / 1000)),
|
||||
|
||||
Reference in New Issue
Block a user