(request: NextRequest)
| 229 | } |
| 230 | |
| 231 | export async function proxy(request: NextRequest) { |
| 232 | const url = request.nextUrl |
| 233 | |
| 234 | if (url.pathname.startsWith('/api/')) { |
| 235 | const policy = resolveApiCorsPolicy(request) |
| 236 | if (request.method === 'OPTIONS') { |
| 237 | return buildPreflightResponse(policy) |
| 238 | } |
| 239 | const response = NextResponse.next() |
| 240 | applyCorsHeaders(response, policy) |
| 241 | return response |
| 242 | } |
| 243 | |
| 244 | const sessionCookie = getSessionCookie(request) |
| 245 | const hasActiveSession = isAuthDisabled || !!sessionCookie |
| 246 | |
| 247 | const redirect = handleRootPathRedirects(request, hasActiveSession) |
| 248 | if (redirect) return track(request, redirect) |
| 249 | |
| 250 | if (url.pathname === '/login' || url.pathname === '/signup') { |
| 251 | if (hasActiveSession) { |
| 252 | return track(request, NextResponse.redirect(new URL('/workspace', request.url))) |
| 253 | } |
| 254 | const response = NextResponse.next() |
| 255 | response.headers.set('Content-Security-Policy', generateRuntimeCSP()) |
| 256 | response.headers.set('X-Content-Type-Options', 'nosniff') |
| 257 | response.headers.set('X-Frame-Options', 'SAMEORIGIN') |
| 258 | return track(request, response) |
| 259 | } |
| 260 | |
| 261 | // Chat pages are publicly accessible embeds — CSP is set in next.config.ts headers |
| 262 | if (url.pathname.startsWith('/chat/')) { |
| 263 | return track(request, NextResponse.next()) |
| 264 | } |
| 265 | |
| 266 | if (url.pathname.startsWith('/workspace')) { |
| 267 | if (!hasActiveSession) { |
| 268 | return track(request, NextResponse.redirect(new URL('/login', request.url))) |
| 269 | } |
| 270 | const response = NextResponse.next() |
| 271 | response.headers.set('Content-Security-Policy', generateRuntimeCSP()) |
| 272 | response.headers.set('X-Content-Type-Options', 'nosniff') |
| 273 | response.headers.set('X-Frame-Options', 'SAMEORIGIN') |
| 274 | return track(request, response) |
| 275 | } |
| 276 | |
| 277 | const invitationRedirect = handleInvitationRedirects(request, hasActiveSession) |
| 278 | if (invitationRedirect) return track(request, invitationRedirect) |
| 279 | |
| 280 | const securityBlock = handleSecurityFiltering(request) |
| 281 | if (securityBlock) return track(request, securityBlock) |
| 282 | |
| 283 | const response = NextResponse.next() |
| 284 | response.headers.set('Vary', 'User-Agent') |
| 285 | |
| 286 | if (url.pathname === '/') { |
| 287 | response.headers.set('Content-Security-Policy', generateRuntimeCSP()) |
| 288 | response.headers.set('X-Content-Type-Options', 'nosniff') |
nothing calls this directly
no test coverage detected