mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-05-27 09:32:28 +02:00
63043b32b5
Reduce cold-start stalls by raising the default backend memory limit, bounding heavy feed concurrency, preserving non-empty startup caches, and refreshing working news feeds. Fix the Next API proxy for Docker control-plane writes by stripping unsupported hop/body headers and forwarding small request bodies safely. Keep the dashboard dynamic so production users do not get stuck on a cached startup shell.
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
/**
|
|
* Phase 5F-A: CSP nonce plumbing middleware.
|
|
*
|
|
* Generates a per-request cryptographic nonce and emits a dynamic
|
|
* Content-Security-Policy header for document (page) responses.
|
|
* API routes, static assets, and image optimization paths are excluded.
|
|
*/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
function buildCsp(nonce: string): string {
|
|
const isDev = process.env.NODE_ENV !== 'production';
|
|
const directives = [
|
|
"default-src 'self'",
|
|
isDev
|
|
? "script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:"
|
|
: "script-src 'self' 'unsafe-inline' blob:",
|
|
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
|
|
"img-src 'self' data: blob: https:",
|
|
isDev
|
|
? "connect-src 'self' ws: wss: http://127.0.0.1:8000 http://127.0.0.1:8787 https:"
|
|
: "connect-src 'self' ws: wss: https:",
|
|
"font-src 'self' data: https://fonts.gstatic.com",
|
|
"object-src 'none'",
|
|
"worker-src 'self' blob:",
|
|
"child-src 'self' blob:",
|
|
"frame-src 'self' https://video.ibm.com https://ustream.tv https://www.ustream.tv",
|
|
"frame-ancestors 'none'",
|
|
"base-uri 'self'",
|
|
"form-action 'self'",
|
|
];
|
|
return directives.join('; ');
|
|
}
|
|
|
|
export function middleware(request: NextRequest) {
|
|
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
|
|
|
|
// Forward a nonce for future fully-wired CSP support. Do not include it in
|
|
// script-src until every Next inline bootstrap script receives the nonce;
|
|
// otherwise production hydration can fail and leave the app on the static
|
|
// "prioritizing map feeds" shell.
|
|
const requestHeaders = new Headers(request.headers);
|
|
requestHeaders.set('x-nonce', nonce);
|
|
|
|
const response = NextResponse.next({
|
|
request: { headers: requestHeaders },
|
|
});
|
|
|
|
response.headers.set('Content-Security-Policy', buildCsp(nonce));
|
|
|
|
return response;
|
|
}
|
|
|
|
export const config = {
|
|
matcher: [
|
|
/*
|
|
* Match all document/page paths. Exclude:
|
|
* - /api/* (API routes — handled by route handlers)
|
|
* - /_next/static/* (static assets)
|
|
* - /_next/image/* (image optimization)
|
|
* - /favicon.ico (browser icon)
|
|
*/
|
|
'/((?!api|_next/static|_next/image|favicon.ico).*)',
|
|
],
|
|
};
|