Repository navigation
Expand file tree
/
Copy pathproxy.ts
More file actions
59 lines (50 loc) · 1.99 KB
/
Copy pathproxy.ts
File metadata and controls
59 lines (50 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { isPublicApiRoute, mustHaveRateLimiter } from '@/lib/api-route-security';
import { getLimiterForRoute } from '@/lib/rate-limit';
export async function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
// --- API route protection and rate limiting ---
if (pathname.startsWith('/api')) {
const isPublic = isPublicApiRoute(pathname);
// Check auth for non-public API routes via session token cookie
if (!isPublic) {
const hasSession =
request.cookies.has('authjs.session-token') || request.cookies.has('__Secure-authjs.session-token');
if (!hasSession) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
}
// Rate limiting — key by session cookie or IP
const limiter = getLimiterForRoute(pathname);
if (!limiter && mustHaveRateLimiter(pathname, process.env.NODE_ENV)) {
return NextResponse.json({ error: 'Rate limiting is not configured' }, { status: 503 });
}
if (limiter) {
const key =
request.cookies.get('authjs.session-token')?.value ||
request.cookies.get('__Secure-authjs.session-token')?.value ||
request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||
'anonymous';
const { success } = await limiter.limit(key);
if (!success) {
return NextResponse.json({ error: 'Too many requests' }, { status: 429 });
}
}
return NextResponse.next();
}
// --- Non-API routes: cache control headers ---
const response = NextResponse.next();
response.headers.set('Cache-Control', 'no-store, max-age=0');
response.headers.set('Pragma', 'no-cache');
response.headers.set('Expires', '0');
return response;
}
export const config = {
matcher: [
// API routes (auth + rate limiting)
'/api/:path*',
// Non-API routes (cache headers) — exclude static files
'/((?!_next/static|_next/image|favicon.ico).*)',
],
};