-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.ts
More file actions
44 lines (39 loc) · 1.81 KB
/
middleware.ts
File metadata and controls
44 lines (39 loc) · 1.81 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
import { clerkMiddleware } from "@clerk/nextjs/server";
import { NextRequest, NextResponse } from "next/server";
import { isClerkEnabled } from "./lib/auth-config";
/**
* Middleware:
* 1. Clerk auth (optional — skipped if NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
* is not set; the app falls back to guest-only mode).
* 2. Security headers on every response — defense-in-depth against XSS
* framing, MIME confusion, and clickjacking. Public share URLs make
* this important because anyone can link to /share/[id] and we don't
* want them embedded in a malicious wrapper iframe.
*
* No routes are gated here for auth — that's done per-route via the
* resolveUserId() helper in lib/auth-guard.ts where applicable.
*/
function addSecurityHeaders(res: NextResponse): NextResponse {
// Prevent the page from being embedded in iframes on other origins.
res.headers.set("X-Frame-Options", "SAMEORIGIN");
// Force browsers to honor declared content-type (no MIME sniffing).
res.headers.set("X-Content-Type-Options", "nosniff");
// Don't leak full URLs of internal pages to third-party sites.
res.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
// Disable browser features we don't use; reduces attack surface.
res.headers.set("Permissions-Policy", "camera=(self), microphone=(), geolocation=(), interest-cohort=()");
return res;
}
function passthrough(_req: NextRequest) {
return addSecurityHeaders(NextResponse.next());
}
const middleware = isClerkEnabled()
? clerkMiddleware(async (_auth, req) => addSecurityHeaders(NextResponse.next({ request: req })))
: passthrough;
export default middleware;
export const config = {
matcher: [
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
"/(api|trpc)(.*)",
],
};