| 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; |
| } |
|
|
| |
| |
| |
| |
| |
| 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 }; |
| } |
|
|