forked from MergeFi/frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnext.config.ts
More file actions
77 lines (73 loc) · 3.41 KB
/
Copy pathnext.config.ts
File metadata and controls
77 lines (73 loc) · 3.41 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import type { NextConfig } from "next";
import { loadValidatedEnv } from "./src/lib/env";
/**
* Validated at module-evaluation time — i.e. as soon as `next build`,
* `next dev`, or `next start` loads this file, before anything else runs
* (verified empirically: a throw here surfaces as "Build error occurred"
* and a non-zero exit code, not a runtime failure) — so a missing or
* invalid NEXT_PUBLIC_STELLAR_NETWORK/NEXT_PUBLIC_API_URL fails loudly at
* build time instead of silently shipping a build signed against the
* wrong Stellar network (#26). A relative import is used rather than the
* `@/*` path alias other files in this app use: next.config.ts is loaded
* outside the normal webpack/Turbopack module graph, so it isn't
* guaranteed to resolve tsconfig path aliases the same way application
* code does.
*/
loadValidatedEnv();
/**
* Production security headers (#50), applied to every route below.
*
* - X-Frame-Options: DENY — MergeFi has no legitimate iframe-embedding use
* case (checked: no `iframe`/embed usage anywhere in this app), and
* real-money actions (fund/claim) are one click away in this UI, making
* clickjacking a genuine risk. If a legitimate embed need shows up later
* (e.g. a GitHub App/marketplace surface), relax this to a scoped
* `frame-ancestors` allowlist via CSP instead of removing it outright.
* - X-Content-Type-Options: nosniff — stops the browser from MIME-sniffing
* a response into an executable content type.
* - Referrer-Policy: strict-origin-when-cross-origin — the GitHub OAuth
* callback at /auth/callback carries a short-lived token in its query
* string (see CallbackClient.tsx); this keeps the full URL out of the
* Referer header sent with any cross-origin request, while still
* sending it for same-origin requests, which is the least surprising
* choice absent a reason to be stricter.
* - Strict-Transport-Security: deliberately conservative to start — a
* short max-age, no `includeSubDomains`, no `preload`. HSTS is
* effectively irreversible once a browser has cached it (and
* preload-list removal is slow), so this is a "start small" rollout:
* once this has run in production for a while with no HTTPS/cert
* issues, raise max-age and add `includeSubDomains`, and only add
* `preload` (and submit to hstspreload.org) once *that* has been stable
* too. The browser ignores this header entirely over plain HTTP, so
* it's harmless to always send.
*
* Deliberately does NOT set Content-Security-Policy — that's tracked by a
* separate issue so it can compose correctly with the theme-init inline
* script (`themeInitScript` from ThemeContext, rendered in layout.tsx)
* without this change guessing at a nonce/hash strategy it doesn't own.
*/
const securityHeaders = [
{ key: "X-Frame-Options", value: "DENY" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Strict-Transport-Security", value: "max-age=86400" },
];
const nextConfig: NextConfig = {
devIndicators: false,
images: {
dangerouslyAllowSVG: true,
remotePatterns: [
{ protocol: "https", hostname: "avatars.githubusercontent.com" },
{ protocol: "https", hostname: "api.dicebear.com" },
],
},
async headers() {
return [
{
source: "/:path*",
headers: securityHeaders,
},
];
},
};
export default nextConfig;