feat(web-tanstack): register security middleware and wire nonce to __root

- Add @tanstack/start + vinxi to deps so defineConfig is available
- Uncomment defineConfig registration in app.config.ts — middleware
  is now actually wired into the Nitro server hook, not just defined
- Update __root.tsx loader to call getNonce(getEvent().node.req)
  from @repo/core-shared/security/tanstack so the per-request nonce
  is read server-side and injected via <meta name="csp-nonce">
- Update __root.test.tsx: mock provides useLoaderData and asserts
  the nonce meta tag is rendered with the correct content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 11:06:26 +00:00
parent 8d35fabaa5
commit 5fd483af39
5 changed files with 5636 additions and 162 deletions

View File

@@ -8,10 +8,8 @@
// setHeader calls forward them to the response.
// req.headers["x-nonce"] is set so downstream loaders can call
// getNonce(event.node.req) from @repo/core-shared/security/tanstack.
//
// Note: @tanstack/start (and its defineConfig) is wired in a later story.
// Uncomment the export default block once @tanstack/start is added.
import { defineConfig } from "@tanstack/start/config";
import { withSecurityHeaders } from "@repo/core-shared/security/tanstack";
interface H3SecurityEvent {
@@ -34,8 +32,6 @@ export function applySecurityHeaders(event: H3SecurityEvent): void {
event.node.req.headers["x-nonce"] = nonce;
}
// Registration via TanStack Start (add @tanstack/start, then uncomment):
// import { defineConfig } from "@tanstack/start/config";
// export default defineConfig({
// server: { hooks: { request: applySecurityHeaders } },
// });
export default defineConfig({
server: { hooks: { request: applySecurityHeaders } },
});