Files
blogflare/src/hooks.server.ts
T

80 lines
1.9 KiB
TypeScript

import { dev } from '$app/environment';
import { verifyAccessJwt } from '$lib/server/access';
import type { Handle } from '@sveltejs/kit';
function unauthorized(): Response {
return new Response('Unauthorized - Access credential verification failed', {
status: 401,
headers: {
'Cache-Control': 'no-store',
'Content-Type': 'text/plain; charset=utf-8'
}
});
}
function accessNotConfigured(): Response {
return new Response('Admin authentication is not configured', {
status: 503,
headers: {
'Cache-Control': 'no-store',
'Content-Type': 'text/plain; charset=utf-8'
}
});
}
export const handle: Handle = async ({ event, resolve }) => {
if (!event.url.pathname.startsWith('/admin')) {
return resolve(event);
}
if (dev) {
event.locals.user = {
email: event.request.headers.get('cf-access-authenticated-user-email') || 'dev@local.host'
};
return resolve(event);
}
const token = event.request.headers.get('cf-access-jwt-assertion');
const teamDomain = event.platform?.env.CF_ACCESS_TEAM_DOMAIN;
const audience = event.platform?.env.CF_ACCESS_AUD;
if (!teamDomain || !audience) {
console.error(
JSON.stringify({
message: 'Cloudflare Access configuration is missing',
path: event.url.pathname,
hasTeamDomain: Boolean(teamDomain),
hasAudience: Boolean(audience)
})
);
return accessNotConfigured();
}
if (!token) {
console.error(
JSON.stringify({
message: 'Cloudflare Access JWT is missing',
path: event.url.pathname
})
);
return unauthorized();
}
try {
event.locals.user = {
email: await verifyAccessJwt(token, teamDomain, audience)
};
} catch (cause) {
console.error(
JSON.stringify({
message: 'Cloudflare Access JWT verification failed',
path: event.url.pathname,
error: cause instanceof Error ? cause.message : String(cause)
})
);
return unauthorized();
}
return resolve(event);
};