import { type Handle } from '@sveltejs/kit'; import { getCurrentDid } from '$lib/server/auth'; import { checkRateLimit, getRateLimitKey, getRateLimitConfig } from '$lib/server/rate-limit'; // Ingester runs as a separate process on the LiteFS primary machine // See src/ingester/main.ts and fly.ingester.toml export const handle: Handle = async ({ event, resolve }) => { // Load the current user's DID from session cookie const did = await getCurrentDid(event.cookies); event.locals.did = did; // Apply rate limiting to API routes const path = event.url.pathname; if (path.startsWith('/api/')) { const ip = event.getClientAddress(); const key = getRateLimitKey(ip, path, did); const config = getRateLimitConfig(path); const { allowed, remaining, resetAt } = checkRateLimit(key, config); if (!allowed) { const retryAfter = Math.ceil((resetAt - Date.now()) / 1000); return new Response(JSON.stringify({ error: 'Too many requests' }), { status: 429, headers: { 'Content-Type': 'application/json', 'Retry-After': String(retryAfter), 'X-RateLimit-Remaining': '0', 'X-RateLimit-Reset': String(resetAt) } }); } // Add rate limit headers to response const response = await resolve(event); response.headers.set('X-RateLimit-Remaining', String(remaining)); response.headers.set('X-RateLimit-Reset', String(resetAt)); return response; } return resolve(event); };