-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnext.config.js
More file actions
132 lines (120 loc) · 4.49 KB
/
Copy pathnext.config.js
File metadata and controls
132 lines (120 loc) · 4.49 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//@ts-check
const path = require('path');
const { composePlugins, withNx } = require('@nx/next');
const {
buildUserWebCspDirectives,
normalizeCspHeaderValue,
} = require('./csp-config.js');
const isDev = process.env.NODE_ENV === 'development';
const isProduction = process.env.NODE_ENV === 'production';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const cspEnforce = process.env.USER_WEB_CSP_ENFORCE === 'true';
/**
* @param {string | undefined} raw
* @returns {boolean}
*/
function isExplicitTruthyEnvValue(raw) {
if (raw == null || String(raw).trim() === '') {
return false;
}
const flag = String(raw).trim().toLowerCase();
return flag === 'true' || flag === '1';
}
/**
* Fail closed when a production build would enable MFA device trust in the client bundle
* (`NEXT_PUBLIC_*` flags) but ship Report-Only CSP headers (`USER_WEB_CSP_ENFORCE` unset).
*/
function assertProductionMfaDeviceTrustRequiresEnforcedCsp() {
if (!isProduction) {
return;
}
const clientTrustWouldEnable =
isExplicitTruthyEnvValue(process.env.NEXT_PUBLIC_USER_MFA_DEVICE_TRUST) &&
isExplicitTruthyEnvValue(process.env.NEXT_PUBLIC_USER_WEB_CSP_ENFORCE);
if (!clientTrustWouldEnable) {
return;
}
if (process.env.USER_WEB_CSP_ENFORCE !== 'true') {
throw new Error(
'Production build misconfiguration: MFA device trust is enabled in the client bundle ' +
'(NEXT_PUBLIC_USER_MFA_DEVICE_TRUST and NEXT_PUBLIC_USER_WEB_CSP_ENFORCE) but USER_WEB_CSP_ENFORCE is not "true". ' +
'Device trust stores session tokens in localStorage and requires enforced Content-Security-Policy headers. ' +
'Set USER_WEB_CSP_ENFORCE=true at build/deploy time, or unset NEXT_PUBLIC_USER_WEB_CSP_ENFORCE until Phase B CSP.',
);
}
}
assertProductionMfaDeviceTrustRequiresEnforcedCsp();
const userWebCspHeaderValue = normalizeCspHeaderValue(
buildUserWebCspDirectives({
supabaseUrl,
isDev,
isProduction,
}),
);
const userWebCspHeaders = cspEnforce
? [{ key: 'Content-Security-Policy', value: userWebCspHeaderValue }]
: [
{
key: 'Content-Security-Policy-Report-Only',
value: userWebCspHeaderValue,
},
];
/**
* @type {import('@nx/next/plugins/with-nx').WithNxOptions}
**/
const nextConfig = {
// Use this to set Nx-specific options
// See: https://nx.dev/recipes/next/next-config-setup
nx: {},
// Transpile workspace packages. `@abstrack/types` must match TS `customConditions: @abstrack/source`
// so the dev server does not bundle a stale `packages/types/dist` (see webpack alias below).
transpilePackages: [
'@abstrack/ui',
'@abstrack/ui-web',
'@abstrack/types',
'@abstrack/supabase',
'react-native',
'react-native-web',
],
webpack: (config) => {
const supabaseSrc = path.join(__dirname, '../../packages/supabase/src');
const uiSrc = path.join(__dirname, '../../packages/ui/src');
const uiWebSrc = path.join(__dirname, '../../packages/ui-web/src');
config.resolve.alias = {
...config.resolve.alias,
'react-native$': 'react-native-web',
// Resolve to source: package `exports` default points at `dist/`, which is easy to forget to
// rebuild and causes runtime undefined exports (e.g. new helpers not in dist yet).
// Use exact `$` on the root entry so subpath imports (`/browser`, `/server`, …) are not
// rewritten to `index.ts/<subpath>`; map subpaths explicitly to match package.json exports.
'@abstrack/types$': path.join(
__dirname,
'../../packages/types/src/index.ts',
),
'@abstrack/supabase$': path.join(supabaseSrc, 'index.ts'),
'@abstrack/supabase/browser': path.join(supabaseSrc, 'browser.ts'),
'@abstrack/supabase/server': path.join(supabaseSrc, 'server.ts'),
'@abstrack/supabase/native': path.join(supabaseSrc, 'native.ts'),
'@abstrack/supabase/admin': path.join(supabaseSrc, 'admin.ts'),
'@abstrack/ui$': path.join(uiSrc, 'index.ts'),
'@abstrack/ui/a11y-web': path.join(uiSrc, 'a11y-web.ts'),
'@abstrack/ui/insights-web': path.join(uiSrc, 'insights-web.ts'),
'@abstrack/ui-web$': path.join(uiWebSrc, 'index.ts'),
'@abstrack/ui-web/sidebar': path.join(uiWebSrc, 'components/sidebar.tsx'),
};
return config;
},
async headers() {
return [
{
source: '/:path*',
headers: userWebCspHeaders,
},
];
},
};
const plugins = [
// Add more Next.js plugins to this list if needed.
withNx,
];
module.exports = composePlugins(...plugins)(nextConfig);