From 522bf6a01946820e91c2528c1fbb65752ef94ad5 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Sat, 18 Apr 2026 13:01:12 +0200 Subject: [PATCH] perf: make root HTML cacheable by dropping per-request CSP nonce --- README.md | 2 +- app/[locale]/layout.tsx | 9 +-------- app/layout.tsx | 23 +---------------------- components/providers/intl-provider.tsx | 1 - proxy.ts | 12 ++---------- public/theme-init.js | 12 ++++++++++++ 6 files changed, 17 insertions(+), 42 deletions(-) create mode 100644 public/theme-init.js diff --git a/README.md b/README.md index 0feff814..90e79e64 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ Built with Next.js and the JMAP protocol. - **TOTP two-factor authentication** - **Account security panel** - manage passwords and 2FA via Stalwart admin API - **"Remember me"** - AES-256-GCM encrypted httpOnly cookie (opt-in) -- **Security headers** - enforced CSP with per-request nonce, X-Frame-Options, Referrer-Policy; SSRF redirect validation; PDF iframe sandbox; IP spoofing prevention +- **Security headers** - enforced CSP (script-src 'self', no unsafe-inline), X-Frame-Options, Referrer-Policy; SSRF redirect validation; PDF iframe sandbox; IP spoofing prevention - **Plugin hardening** - dangerous-pattern detection, admin approval required, secure HTTP proxy API (no auth-header exposure) - **Newsletter unsubscribe** (RFC 2369) diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx index 12b1a4e3..1bedc98c 100644 --- a/app/[locale]/layout.tsx +++ b/app/[locale]/layout.tsx @@ -18,15 +18,8 @@ export default async function LocaleLayout({ if (!(locales as readonly string[]).includes(locale)) notFound(); - let messages; - try { - messages = (await import(`@/locales/${locale}/common.json`)).default; - } catch { - notFound(); - } - return ( - + diff --git a/app/layout.tsx b/app/layout.tsx index c2a54606..58c11fe6 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,5 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; -import { headers } from "next/headers"; import { getLocale } from "next-intl/server"; import { PWAInstallPrompt } from "@/components/pwa-install-prompt"; import { ServiceWorkerRegistration } from "@/components/service-worker-registration"; @@ -40,7 +39,6 @@ export default async function RootLayout({ children: React.ReactNode; }) { const locale = await getLocale(); - const nonce = (await headers()).get("x-nonce") ?? ""; const parentOrigin = process.env.NEXT_PUBLIC_PARENT_ORIGIN || ""; return ( @@ -57,26 +55,7 @@ export default async function RootLayout({ {parentOrigin && ( )} -