@dargmuesli/nuxt-vio 8.3.3 → 8.4.0

Sign up to get free protection for your applications and to get access to all the features.
package/nuxt.config.ts CHANGED
@@ -51,10 +51,42 @@ export default defineNuxtConfig(
51
51
  '@nuxtjs/tailwindcss',
52
52
  '@nuxtseo/module',
53
53
  '@pinia/nuxt',
54
+ // nuxt-security: remove invalid `'none'`s
55
+ (_options, nuxt) => {
56
+ const nuxtConfigSecurity = nuxt.options.security
57
+
58
+ if (
59
+ typeof nuxtConfigSecurity.headers !== 'boolean' &&
60
+ nuxtConfigSecurity.headers.contentSecurityPolicy &&
61
+ typeof nuxtConfigSecurity.headers.contentSecurityPolicy !==
62
+ 'boolean' &&
63
+ typeof nuxtConfigSecurity.headers.contentSecurityPolicy !== 'string'
64
+ ) {
65
+ for (const [key, value] of Object.entries(
66
+ nuxtConfigSecurity.headers.contentSecurityPolicy,
67
+ )) {
68
+ if (!Array.isArray(value)) continue
69
+
70
+ const valueFiltered = value.filter((x) => x !== "'none'")
71
+
72
+ if (valueFiltered.length) {
73
+ ;(
74
+ nuxtConfigSecurity.headers.contentSecurityPolicy as Record<
75
+ string,
76
+ any
77
+ >
78
+ )[key] = [...new Set(valueFiltered)]
79
+ }
80
+ }
81
+ }
82
+ },
54
83
  'nuxt-security',
55
84
  ],
56
85
  nitro: {
57
86
  compressPublicAssets: true,
87
+ experimental: {
88
+ openAPI: process.env.NODE_ENV === 'development',
89
+ },
58
90
  },
59
91
  runtimeConfig: {
60
92
  public: {
@@ -144,6 +176,17 @@ export default defineNuxtConfig(
144
176
  security: {
145
177
  headers: {
146
178
  contentSecurityPolicy: defu(
179
+ {
180
+ // Cloudflare
181
+ ...(process.env.NODE_ENV === 'production'
182
+ ? {
183
+ 'connect-src': ["'self'"], // `${SITE_URL}/cdn-cgi/rum`
184
+ 'script-src-elem': [
185
+ 'https://static.cloudflareinsights.com',
186
+ ],
187
+ }
188
+ : {}),
189
+ },
147
190
  {
148
191
  // Google Analytics 4 (https://developers.google.com/tag-platform/tag-manager/web/csp)
149
192
  'connect-src': [
@@ -159,6 +202,7 @@ export default defineNuxtConfig(
159
202
  },
160
203
  {
161
204
  // vio
205
+ 'connect-src': ["'self'"], // `${SITE_URL}/api/healthcheck`
162
206
  'manifest-src': [`${SITE_URL}/site.webmanifest`],
163
207
  'script-src-elem': [
164
208
  'https://polyfill.io/v3/polyfill.min.js', // ESLint plugin compat
@@ -166,19 +210,36 @@ export default defineNuxtConfig(
166
210
  },
167
211
  {
168
212
  // @nuxt/devtools
169
- 'frame-src': [
170
- ...(process.env.NODE_ENV === 'development'
171
- ? ['http://localhost:3000/__nuxt_devtools__/client/']
172
- : []),
173
- ],
213
+ ...(process.env.NODE_ENV === 'development'
214
+ ? {
215
+ 'frame-src': [
216
+ 'http://localhost:3000/__nuxt_devtools__/client/',
217
+ ],
218
+ }
219
+ : {}),
174
220
  },
175
221
  {
176
222
  // nuxt-link-checker
177
- 'connect-src': [
178
- ...(process.env.NODE_ENV === 'development'
179
- ? ['http://localhost:3000/api/__link_checker__/inspect']
180
- : []),
181
- ],
223
+ ...(process.env.NODE_ENV === 'development'
224
+ ? {
225
+ 'connect-src': ["'self'"], // 'http://localhost:3000/api/__link_checker__/inspect'
226
+ }
227
+ : {}),
228
+ },
229
+ {
230
+ // nuxt-og-image
231
+ ...(process.env.NODE_ENV === 'development'
232
+ ? {
233
+ 'font-src': ['https://fonts.gstatic.com/s/inter/'],
234
+ 'frame-ancestors': ["'self'"],
235
+ 'frame-src': ["'self'"],
236
+ 'script-src-elem': ['https://cdn.tailwindcss.com/'],
237
+ 'style-src': [
238
+ // TODO: replace with `style-src-elem` once Webkit supports it
239
+ 'https://cdn.jsdelivr.net/npm/gardevoir https://fonts.googleapis.com/css2',
240
+ ],
241
+ }
242
+ : {}),
182
243
  },
183
244
  {
184
245
  // nuxt-simple-sitemap
@@ -189,12 +250,12 @@ export default defineNuxtConfig(
189
250
  'connect-src': [
190
251
  ...(process.env.NODE_ENV === 'development'
191
252
  ? [
192
- 'http://localhost:3000/_nuxt/', // Nuxt development
193
- 'https://localhost:3000/_nuxt/', // Nuxt development
194
- 'ws://localhost:3000/_nuxt/', // Nuxt development
195
- 'wss://localhost:3000/_nuxt/', // Nuxt development
253
+ 'http://localhost:3000/_nuxt/', // hot reload
254
+ 'https://localhost:3000/_nuxt/', // hot reload
255
+ 'ws://localhost:3000/_nuxt/', // hot reload
256
+ 'wss://localhost:3000/_nuxt/', // hot reload
196
257
  ]
197
- : ["'self'"]), // Nuxt build metadata and payloads
258
+ : ["'self'"]), // build metadata and payloads
198
259
  ],
199
260
  'img-src': [
200
261
  "'self'", // TODO: replace with `"'nonce-{{nonce}}'",`
@@ -207,6 +268,18 @@ export default defineNuxtConfig(
207
268
  "'unsafe-inline'", // TODO: replace with `"'nonce-{{nonce}}'",` (https://github.com/vitejs/vite/pull/11864)
208
269
  ],
209
270
  },
271
+ {
272
+ // nitro
273
+ 'connect-src': ["'self'"] /* swagger
274
+ 'http://localhost:3000/_nitro/openapi.json',
275
+ 'http://localhost:3000/_nitro/swagger', */,
276
+ 'script-src-elem': [
277
+ 'https://cdn.jsdelivr.net/npm/', // swagger // TODO: increase precision (https://github.com/unjs/nitro/issues/1757)
278
+ ],
279
+ 'style-src': [
280
+ 'https://cdn.jsdelivr.net/npm/', // swagger // TODO: increase precision (https://github.com/unjs/nitro/issues/1757)
281
+ ],
282
+ },
210
283
  {
211
284
  // base
212
285
  'base-uri': ["'none'"], // does not fallback to `default-src`
@@ -224,6 +297,8 @@ export default defineNuxtConfig(
224
297
  'prefetch-src': [],
225
298
  'report-to': [],
226
299
  'report-uri': [],
300
+ // TODO: evaluate header (https://github.com/maevsi/maevsi/issues/830) // https://stackoverflow.com/questions/62081028/this-document-requires-trustedscripturl-assignment
301
+ // 'require-trusted-types-for': ["'script'"], // csp-evaluator
227
302
  sandbox: [],
228
303
  'script-src': [],
229
304
  'script-src-attr': [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dargmuesli/nuxt-vio",
3
- "version": "8.3.3",
3
+ "version": "8.4.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/dargmuesli/vio.git"
@@ -105,7 +105,6 @@
105
105
  "eslint-plugin-prettier": "5.0.1",
106
106
  "eslint-plugin-yml": "1.10.0",
107
107
  "h3": "1.8.2",
108
- "is-https": "4.0.0",
109
108
  "jiti": "1.20.0",
110
109
  "jose": "4.15.4",
111
110
  "lint-staged": "15.0.2",
@@ -1,5 +1,3 @@
1
- import { defineEventHandler } from 'h3'
2
-
3
1
  export default defineEventHandler((event) => {
4
2
  const { res } = event.node
5
3
  res.setHeader('Content-Type', 'text/plain')
@@ -1,10 +1,6 @@
1
- import { appendHeader, defineEventHandler } from 'h3'
2
1
  import type { H3Event } from 'h3'
3
2
  import type { AppConfig } from 'nuxt/schema'
4
3
 
5
- import { TIMEZONE_HEADER_KEY } from '../../utils/constants'
6
- import { getTimezone } from '../../utils/networking'
7
-
8
4
  export default defineEventHandler(async (event) => {
9
5
  setRequestHeader(event, TIMEZONE_HEADER_KEY, await getTimezone(event))
10
6
  setResponseHeaders(event)
@@ -0,0 +1,2 @@
1
+ export { TIMEZONE_HEADER_KEY } from '../../utils/constants'
2
+ export { getTimezone } from '../../utils/networking'