diff options
| author | ertopogo <erwin.t.pombett@gmail.com> | 2026-02-19 11:34:16 +0100 |
|---|---|---|
| committer | ertopogo <erwin.t.pombett@gmail.com> | 2026-02-19 11:34:16 +0100 |
| commit | a21bd6a6710d123ef3bfc3c9aab37fc0c276f9c5 (patch) | |
| tree | e2cc828607ea91e5c90ae0ea98c6b7d11324eaf1 /src/middleware.ts | |
feat: initial project setup - Next.js 16, Payload CMS v3, palette Mapuche
Next.js 16 App Router + TypeScript + Tailwind CSS v4. Payload CMS v3 with PostgreSQL adapter. Mapuche Corporate palette. Public pages, Docker Compose + Caddy, security middleware.
Co-authored-by: Cursor <cursoragent@cursor.com>
Diffstat (limited to 'src/middleware.ts')
| -rw-r--r-- | src/middleware.ts | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..74f5aed --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,40 @@ +import { NextResponse } from "next/server"; +import type { NextRequest } from "next/server"; + +export function middleware(request: NextRequest) { + const response = NextResponse.next(); + const { pathname } = request.nextUrl; + + const nonce = Buffer.from(crypto.randomUUID()).toString("base64"); + + const cspDirectives = [ + "default-src 'self'", + `script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`, + `style-src 'self' 'unsafe-inline'`, + "img-src 'self' data: blob:", + "font-src 'self'", + `connect-src 'self' ${process.env.KEYCLOAK_ISSUER || ""}`, + "frame-ancestors 'none'", + "base-uri 'self'", + "form-action 'self'", + "upgrade-insecure-requests", + ]; + + if (pathname.startsWith("/admin")) { + return response; + } + + response.headers.set( + "Content-Security-Policy", + cspDirectives.join("; ") + ); + response.headers.set("X-Nonce", nonce); + + return response; +} + +export const config = { + matcher: [ + "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)", + ], +}; |
