Fixing CORS issues

This commit is contained in:
Tom Butcher 2025-03-27 22:30:26 +00:00
parent 0f1e01dacc
commit ec2985f783
6 changed files with 25 additions and 23 deletions

View File

@ -2,6 +2,7 @@ import { handleContactRequest } from './routes/contact.js';
import { handleSocialsRequest } from './routes/socials.js'; import { handleSocialsRequest } from './routes/socials.js';
import { handleBlogsListRequest, handleBlogsViewRequest } from './routes/blogs.js'; import { handleBlogsListRequest, handleBlogsViewRequest } from './routes/blogs.js';
import { handleFlushCacheRequest } from './routes/utils.js'; import { handleFlushCacheRequest } from './routes/utils.js';
import { globalHeaders } from './utils/api.js';
async function handleRequest(request) { async function handleRequest(request) {
if (request.method === 'POST' && request.url.split('?')[0].endsWith('/api/contact')) { if (request.method === 'POST' && request.url.split('?')[0].endsWith('/api/contact')) {
@ -25,7 +26,7 @@ async function handleRequest(request) {
} }
// Return 404 if the route is not found // Return 404 if the route is not found
return new Response('Not Found', { status: 404 }); return new Response('Not Found', { status: 404, headers: globalHeaders });
} }
addEventListener('fetch', (event) => { addEventListener('fetch', (event) => {

View File

@ -1,5 +1,6 @@
import { getNotionDatabaseWithCache, getNotionBlocksWithCache } from '../utils/notion.js'; import { getNotionDatabaseWithCache, getNotionBlocksWithCache } from '../utils/notion.js';
import { generateBlockHTML } from '../utils/htmlgen.js'; import { generateBlockHTML } from '../utils/htmlgen.js';
import { globalHeaders } from '../utils/api.js';
const blogsDB = BLOGS_DB; const blogsDB = BLOGS_DB;
export async function handleBlogsListRequest(request, env) { export async function handleBlogsListRequest(request, env) {
@ -29,7 +30,7 @@ export async function handleBlogsListRequest(request, env) {
}), }),
{ {
status: 404, status: 404,
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}, },
); );
} }
@ -60,8 +61,7 @@ export async function handleBlogsListRequest(request, env) {
console.log('Finished listing blogs.'); console.log('Finished listing blogs.');
return new Response(JSON.stringify(blogsResponse), { return new Response(JSON.stringify(blogsResponse), {
headers: { headers: {
'Content-Type': 'application/json', ...globalHeaders,
'Access-Control-Allow-Origin': '*', // Enable CORS
'Cache-Control': 'public, max-age=600', // 10 minute browser cache 'Cache-Control': 'public, max-age=600', // 10 minute browser cache
}, },
}); });
@ -74,7 +74,7 @@ export async function handleBlogsListRequest(request, env) {
}), }),
{ {
status: 500, status: 500,
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}, },
); );
} }
@ -109,7 +109,7 @@ export async function handleBlogsViewRequest(request, env) {
}), }),
{ {
status: 404, status: 404,
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}, },
); );
} }
@ -131,8 +131,7 @@ export async function handleBlogsViewRequest(request, env) {
console.log('Finished listing blogs.'); console.log('Finished listing blogs.');
return new Response(JSON.stringify(blogResponse), { return new Response(JSON.stringify(blogResponse), {
headers: { headers: {
'Content-Type': 'application/json', ...globalHeaders,
'Access-Control-Allow-Origin': '*', // Enable CORS
'Cache-Control': 'public, max-age=600', // 10 minute browser cache 'Cache-Control': 'public, max-age=600', // 10 minute browser cache
}, },
}); });
@ -145,7 +144,7 @@ export async function handleBlogsViewRequest(request, env) {
}), }),
{ {
status: 500, status: 500,
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}, },
); );
} }

View File

@ -1,5 +1,6 @@
import { getLocation } from '../utils/geolocation.js'; import { getLocation } from '../utils/geolocation.js';
import { addToNotionDatabase, getNotionDatabaseWithCache } from '../utils/notion.js'; import { addToNotionDatabase, getNotionDatabaseWithCache } from '../utils/notion.js';
import { globalHeaders } from '../utils/api.js';
const TURNSTILE_SECRET_KEY = TURNSTILE_AUTH; const TURNSTILE_SECRET_KEY = TURNSTILE_AUTH;
@ -9,7 +10,7 @@ export async function handleContactRequest(request) {
const { email, token } = await request.json(); const { email, token } = await request.json();
if (!email || !token) { if (!email || !token) {
return new Response('Email and token are required', { status: 400 }); return new Response('Email and token are required', { status: 400, headers: globalHeaders });
} }
// Extract the IP address from the request headers // Extract the IP address from the request headers
@ -23,7 +24,7 @@ export async function handleContactRequest(request) {
// Verify the Turnstile token // Verify the Turnstile token
const verificationResponse = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { const verificationResponse = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
body: JSON.stringify({ body: JSON.stringify({
secret: TURNSTILE_SECRET_KEY, secret: TURNSTILE_SECRET_KEY,
response: token, response: token,
@ -33,7 +34,7 @@ export async function handleContactRequest(request) {
const verificationData = await verificationResponse.json(); const verificationData = await verificationResponse.json();
if (!verificationData.success) { if (!verificationData.success) {
return new Response('Turnstile verification failed', { status: 400 }); return new Response('Turnstile verification failed', { status: 400, headers: globalHeaders });
} }
} }
@ -41,9 +42,9 @@ export async function handleContactRequest(request) {
try { try {
await addToNotionDatabase({ Name: email.split('@')[0], Email: email, Location: locationString }, '1abdd26d60b68076a886fb0525ff0a4f'); await addToNotionDatabase({ Name: email.split('@')[0], Email: email, Location: locationString }, '1abdd26d60b68076a886fb0525ff0a4f');
return new Response(JSON.stringify({ success: true, message: 'Email processed and added to Notion' }), { return new Response(JSON.stringify({ success: true, message: 'Email processed and added to Notion' }), {
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}); });
} catch (error) { } catch (error) {
return new Response('Error processing email', { status: 500 }); return new Response('Error processing email', { status: 500, headers: globalHeaders });
} }
} }

View File

@ -1,4 +1,5 @@
import { getNotionDatabaseWithCache } from '../utils/notion.js'; import { getNotionDatabaseWithCache } from '../utils/notion.js';
import { globalHeaders } from '../utils/api.js';
const socialsDB = SOCIALS_DB; const socialsDB = SOCIALS_DB;
const referrersDB = REFERRERS_DB; const referrersDB = REFERRERS_DB;
@ -32,7 +33,7 @@ export async function handleSocialsRequest(request, env) {
}), }),
{ {
status: 404, status: 404,
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}, },
); );
} }
@ -56,8 +57,7 @@ export async function handleSocialsRequest(request, env) {
console.log('Finished listing socials.'); console.log('Finished listing socials.');
return new Response(JSON.stringify(socialsResponse), { return new Response(JSON.stringify(socialsResponse), {
headers: { headers: {
'Content-Type': 'application/json', ...globalHeaders,
'Access-Control-Allow-Origin': '*', // Enable CORS
'Cache-Control': 'public, max-age=600', // 10 minute browser cache 'Cache-Control': 'public, max-age=600', // 10 minute browser cache
}, },
}); });
@ -70,7 +70,7 @@ export async function handleSocialsRequest(request, env) {
}), }),
{ {
status: 500, status: 500,
headers: { 'Content-Type': 'application/json' }, headers: globalHeaders,
}, },
); );
} }

View File

@ -1,4 +1,5 @@
import { flushCache } from '../utils/notion.js'; import { flushCache } from '../utils/notion.js';
import { globalHeaders } from '../utils/api.js';
export async function handleFlushCacheRequest(request) { export async function handleFlushCacheRequest(request) {
await flushCache(); await flushCache();
@ -6,10 +7,6 @@ export async function handleFlushCacheRequest(request) {
result: 'ok', result: 'ok',
}; };
return new Response(JSON.stringify(response), { return new Response(JSON.stringify(response), {
headers: { headers: globalHeaders,
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*', // Enable CORS
'Cache-Control': 'public, max-age=600', // 10 minute browser cache
},
}); });
} }

4
src/utils/api.js Normal file
View File

@ -0,0 +1,4 @@
export const globalHeaders = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': CORS_ORIGIN,
};