proxy.ts
Rama main · réplica de lectura del repositorio original.
import { type NextRequest, NextResponse } from 'next/server'
import {
exceedsRelayBodyCap,
RELAY_PREFIX,
relayRequestHeaders,
relayTarget
} from '@/lib/analytics/relay-target'
import { getAuthProvider, resolveAuthProviderName } from '@/lib/auth/provider'
import { isMaintenanceMode, maintenanceResponse } from '@/lib/maintenance'
// Better Auth sends /relay through the route handler. Other providers
// proxy straight to PostHog so analytics requests cost no function
// invocation and keep upstream caching.
function relayRewrite(request: NextRequest): NextResponse | null {
const { pathname, search } = request.nextUrl
if (pathname !== RELAY_PREFIX && !pathname.startsWith(`${RELAY_PREFIX}/`)) {
return null
}
if (resolveAuthProviderName() === 'better-auth') {
return null
}
const target = relayTarget(pathname.slice(RELAY_PREFIX.length) || '/', search)
if (!target) {
return new NextResponse('Not found', { status: 404 })
}
if (exceedsRelayBodyCap(request.headers)) {
return new NextResponse('Payload too large', { status: 413 })
}
return NextResponse.rewrite(target, {
request: { headers: relayRequestHeaders(request.headers) }
})
}
export async function proxy(request: NextRequest) {
if (isMaintenanceMode()) {
return maintenanceResponse(request.nextUrl.pathname)
}
const relay = relayRewrite(request)
if (relay) {
return relay
}
// Get the protocol from X-Forwarded-Proto header or request protocol
const protocol =
request.headers.get('x-forwarded-proto') || request.nextUrl.protocol
// Get the host from X-Forwarded-Host header or request host
const host =
request.headers.get('x-forwarded-host') || request.headers.get('host') || ''
// Construct the base URL - ensure protocol has :// format
const baseUrl = `${protocol}${protocol.endsWith(':') ? '//' : '://'}${host}`
// Create a response via the active auth provider's session enforcement
// (supabase refreshes/validates the session, none passes through)
let response: NextResponse
response = await getAuthProvider().handleSession(request)
// Add request information to response headers
response.headers.set('x-url', request.url)
response.headers.set('x-host', host)
response.headers.set('x-protocol', protocol)
response.headers.set('x-base-url', baseUrl)
return response
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - api/favicon (source favicon images, which need no session)
* Feel free to modify this pattern to include more paths.
*/
'/((?!_next/static|_next/image|favicon.ico|api/favicon|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)'
]
}