builder / lib /web /request-guards.ts
Leon4gr45's picture
Upload folder using huggingface_hub (part 3)
94193b5 verified
Raw
History Blame Contribute Delete
1.94 kB
import { NextRequest, NextResponse } from 'next/server';
import { getIdentifier } from '@/lib/analytics/rate-limiter';
import { checkRateLimit } from '@/lib/web/rate-limit';
function getCookie(request: NextRequest, name: string): string | null {
return request.cookies.get(name)?.value ?? null;
}
export function isSameOrigin(request: NextRequest): boolean {
const host = request.headers.get('host') || '';
const proto = request.headers.get('x-forwarded-proto') || 'https';
const selfOrigin = `${proto}://${host}`;
const origin = request.headers.get('origin') || '';
const referer = request.headers.get('referer') || '';
if (origin) return origin === selfOrigin;
if (referer) return referer.startsWith(selfOrigin + '/') || referer === selfOrigin;
return false;
}
/**
* Shared preflight for the web proxy routes: kill-switch, same-origin,
* server-mode session presence, and rate limiting. Returns either an rlKey
* (all checks passed) or a ready-to-return error response.
*/
export function webRequestPreflight(
request: NextRequest,
): { ok: true; rlKey: string } | { ok: false; response: NextResponse } {
if (process.env.OSW_DISABLE_WEB_PROXY === '1') {
return { ok: false, response: NextResponse.json({ error: 'web access is disabled on this instance' }, { status: 403 }) };
}
if (!isSameOrigin(request)) {
return { ok: false, response: NextResponse.json({ error: 'origin not allowed' }, { status: 403 }) };
}
const workspace = getCookie(request, 'osw_workspace');
if (process.env.NEXT_PUBLIC_SERVER_MODE === 'true' && !workspace) {
return { ok: false, response: NextResponse.json({ error: 'authentication required' }, { status: 401 }) };
}
const rlKey = workspace || getIdentifier(request);
if (!checkRateLimit(rlKey)) {
return { ok: false, response: NextResponse.json({ error: 'rate limit exceeded, slow down' }, { status: 429 }) };
}
return { ok: true, rlKey };
}