Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/typescript-config #248

Merged
merged 14 commits into from
Oct 30, 2023
Merged
5 changes: 1 addition & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
{
"extends": ["@nuxtjs/eslint-config-typescript"],
"rules": {
"@typescript-eslint/no-unused-vars": ["off"]
}
"extends": ["@nuxt/eslint-config"]
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ coverage
Network Trash Folder
Temporary Items
.apdisk

# Yarn is the package manager, do not commit npm lock file
package-lock.json
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false
3 changes: 2 additions & 1 deletion .nuxtrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
imports.autoImport=true
imports.autoImport=false
typescript.includeWorkspace=true
1 change: 1 addition & 0 deletions docs/.nuxtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports.autoImport=true
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,22 @@
"dist"
],
"scripts": {
"prepack": "nuxt-module-build",
"dev": "nuxt-module-build --stub && nuxi prepare playground && nuxi dev playground",
"prepack": "nuxt-module-build build",
"dev": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && nuxi dev playground",
"dev:build": "nuxi build playground",
"dev:start": "nuxi start playground",
"dev:generate": "nuxi generate playground",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
"dev:preview": "nuxi preview playground",
"dev:docs": "cd docs && yarn dev",
"lint": "eslint --ext .js,.ts,.vue",
"lint": "eslint .",
"test": "vitest run --silent",
"test:watch": "vitest watch",
"stackblitz": "cd .stackblitz && yarn && yarn dev"
},
"packageManager": "[email protected]",
"dependencies": {
"@nuxt/kit": "^3.7.3",
"@nuxt/kit": "^3.8.0",
"basic-auth": "^2.0.1",
"defu": "^6.1.1",
"nuxt-csurf": "^1.3.1",
Expand All @@ -59,15 +59,15 @@
"xss": "^1.0.14"
},
"devDependencies": {
"@nuxt/module-builder": "latest",
"@nuxt/schema": "^3.7.3",
"@nuxt/test-utils": "^3.7.3",
"@nuxtjs/eslint-config-typescript": "latest",
"@types/node": "^18.14.4",
"eslint": "latest",
"nuxt": "^3.7.3",
"typescript": "5.2.2",
"vitest": "^0.28.5"
"@nuxt/module-builder": "^0.5.2",
"@nuxt/schema": "^3.8.0",
"@nuxt/test-utils": "^3.8.0",
"@nuxt/eslint-config": "^0.2.0",
"@types/node": "^18.18.1",
"eslint": "^8.50.0",
"nuxt": "^3.8.0",
"typescript": "^5.2.2",
"vitest": "^0.33.0"
},
"stackblitz": {
"installDependencies": false,
Expand Down
1 change: 1 addition & 0 deletions playground/.nuxtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports.autoImport=true
4 changes: 3 additions & 1 deletion playground/pages/secret.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<template>
Secret Route
<div>
Secret Route
</div>
</template>
3 changes: 0 additions & 3 deletions playground/server/api/test.post.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { defineEventHandler } from 'h3'


export default defineEventHandler((event) => {
console.log('test')
})
3 changes: 3 additions & 0 deletions playground/server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}
3 changes: 3 additions & 0 deletions playground/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "./.nuxt/tsconfig.json"
}
22 changes: 13 additions & 9 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,32 @@ import { fileURLToPath } from 'node:url'
import { resolve, normalize } from 'pathe'
import { defineNuxtModule, addServerHandler, installModule, addVitePlugin } from '@nuxt/kit'
import { defu } from 'defu'
import { Nuxt, RuntimeConfig } from '@nuxt/schema'
import type { Nuxt, RuntimeConfig } from '@nuxt/schema'
import viteRemove from 'unplugin-remove/vite'
import { defuReplaceArray } from './utils'
import {
import type {
ModuleOptions,
NuxtSecurityRouteRules
} from './types/index'
import {
import type {
SecurityHeaders
} from './types/headers'
import {
import type {
BasicAuth
} from './types/middlewares'
import {
defaultSecurityConfig
} from './defaultConfig'
import { SECURITY_MIDDLEWARE_NAMES } from './middlewares'
import { HeaderMapper, SECURITY_HEADER_NAMES, getHeaderValueFromOptions } from './headers'
import { type HeaderMapper, SECURITY_HEADER_NAMES, getHeaderValueFromOptions } from './headers'

declare module '@nuxt/schema' {
declare module 'nuxt/schema' {
interface NuxtOptions {
security: ModuleOptions;
security: ModuleOptions
}
interface RuntimeConfig {
security: ModuleOptions,
private: { basicAuth: BasicAuth | false, [key: string]: any }
}
}

Expand Down Expand Up @@ -67,7 +71,7 @@ export default defineNuxtModule<ModuleOptions>({
nuxt.options.runtimeConfig.private = defu(
nuxt.options.runtimeConfig.private,
{
basicAuth: securityOptions.basicAuth as BasicAuth | boolean
basicAuth: securityOptions.basicAuth
}
)

Expand All @@ -76,7 +80,7 @@ export default defineNuxtModule<ModuleOptions>({
nuxt.options.runtimeConfig.security = defu(
nuxt.options.runtimeConfig.security,
{
...(securityOptions as unknown as RuntimeConfig['security'])
...securityOptions
}
)

Expand Down
10 changes: 5 additions & 5 deletions src/runtime/nitro/plugins/01-hidePoweredBy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { NitroAppPlugin, RenderResponse } from 'nitropack'
import { defineNitroPlugin } from '#imports'

export default <NitroAppPlugin> function (nitro) {
nitro.hooks.hook('render:response', (response: RenderResponse) => {
if (response.headers['x-powered-by']) {
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:response', (response) => {
if (response?.headers?.['x-powered-by']) {
delete response.headers['x-powered-by']
}
})
}
})
27 changes: 8 additions & 19 deletions src/runtime/nitro/plugins/02-cspSsg.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from 'node:path'
import crypto from 'node:crypto'
import type { NitroAppPlugin } from 'nitropack'
import type { H3Event } from 'h3'
import defu from 'defu'
import type {
Expand All @@ -9,22 +8,12 @@ import type {
import type {
ContentSecurityPolicyValue
} from '../../../types/headers'
import { useRuntimeConfig } from '#imports'

interface NuxtRenderHTMLContext {
island?: boolean
htmlAttrs: string[]
head: string[]
bodyAttrs: string[]
bodyPrepend: string[]
body: string[]
bodyAppend: string[]
}

const moduleOptions = useRuntimeConfig().security as ModuleOptions

export default <NitroAppPlugin> function (nitro) {
nitro.hooks.hook('render:html', (html: NuxtRenderHTMLContext, { event }: { event: H3Event }) => {
import { defineNitroPlugin, useRuntimeConfig } from '#imports'

const moduleOptions = useRuntimeConfig().security

export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
// Content Security Policy

if (!isContentSecurityPolicyEnabled(event, moduleOptions)) {
Expand Down Expand Up @@ -54,7 +43,7 @@ export default <NitroAppPlugin> function (nitro) {
})

function generateCspMetaTag (policies: ContentSecurityPolicyValue, scriptHashes: string[]) {
const unsupportedPolicies = {
const unsupportedPolicies:Record<string, boolean> = {
'frame-ancestors': true,
'report-uri': true,
sandbox: true
Expand Down Expand Up @@ -120,4 +109,4 @@ export default <NitroAppPlugin> function (nitro) {

return true
}
}
})
22 changes: 4 additions & 18 deletions src/runtime/nitro/plugins/99-cspNonce.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
import type { NitroAppPlugin } from 'nitropack'
import { defineNitroPlugin } from '#imports'
import type { H3Event } from 'h3'
import type {
ModuleOptions
} from '../../../types'
import { useRuntimeConfig } from '#imports'

interface NuxtRenderHTMLContext {
island?: boolean
htmlAttrs: string[]
head: string[]
bodyAttrs: string[]
bodyPrepend: string[]
body: string[]
bodyAppend: string[]
}

// To prevent the nonce attribute from being added to literal strings,
// we need to make sure that the tag is not preceded by a single or double quote.
// This is done by using a negative lookbehind assertion. See https://www.regular-expressions.info/lookaround.html
// See https://regex101.com/r/DBE57j/1 for some examples.
const tagNotPrecededByQuotes = (tag: string) => new RegExp(`(?<!['|"])<${tag}`, 'g')

export default <NitroAppPlugin> function (nitro) {
nitro.hooks.hook('render:html', (html: NuxtRenderHTMLContext, { event }: { event: H3Event }) => {
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
if (isPrerendering(event)) {
// In SSG mode, do not inject nonces in html
// However first make sure we erase nonce placeholders from CSP meta
Expand Down Expand Up @@ -79,4 +65,4 @@ export default <NitroAppPlugin> function (nitro) {

return true
}
}
})
9 changes: 9 additions & 0 deletions src/runtime/nitro/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../../.nuxt/tsconfig.server.json",
"exclude": [
"../../../docs",
"../../../dist",
"../../../test",
"../../../playground"
]
}
4 changes: 1 addition & 3 deletions src/runtime/server/middleware/allowedMethodsRestricter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { defineEventHandler, createError } from 'h3'
// @ts-ignore
import { getRouteRules } from '#imports'
import { getRouteRules, defineEventHandler, createError } from '#imports'

export default defineEventHandler((event) => {
const routeRules = getRouteRules(event)
Expand Down
5 changes: 2 additions & 3 deletions src/runtime/server/middleware/basicAuth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @ts-ignore : the basic-auth module does not export types
import getCredentials from 'basic-auth'
import { createError, defineEventHandler, sendError, setHeader } from 'h3'
// @ts-ignore
import { useRuntimeConfig } from '#imports'
import { useRuntimeConfig, createError, defineEventHandler, sendError, setHeader } from '#imports'

type Credentials = {
name: string;
Expand Down
4 changes: 1 addition & 3 deletions src/runtime/server/middleware/corsHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { defineEventHandler, handleCors } from 'h3'
// @ts-ignore
import { getRouteRules } from '#imports'
import { getRouteRules, defineEventHandler, handleCors } from '#imports'

export default defineEventHandler((event) => {
const routeRules = getRouteRules(event)
Expand Down
4 changes: 1 addition & 3 deletions src/runtime/server/middleware/cspNonceHandler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import crypto from 'node:crypto'
import { defineEventHandler } from 'h3'
// @ts-ignore
import { getRouteRules } from '#imports'
import { getRouteRules, defineEventHandler } from '#imports'

export default defineEventHandler((event) => {
let csp = `${event.node.res.getHeader('Content-Security-Policy')}`
Expand Down
4 changes: 1 addition & 3 deletions src/runtime/server/middleware/requestSizeLimiter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { defineEventHandler, getRequestHeader, createError } from 'h3'
// @ts-ignore
import { getRouteRules } from '#imports'
import { defineEventHandler, getRequestHeader, createError, getRouteRules } from '#imports'

const FILE_UPLOAD_HEADER = 'multipart/form-data'

Expand Down
4 changes: 1 addition & 3 deletions src/runtime/server/middleware/xssValidator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { defineEventHandler, createError, getQuery, readBody } from 'h3'
import { FilterXSS } from 'xss'
// @ts-ignore
import { getRouteRules } from '#imports'
import { defineEventHandler, createError, getQuery, readBody, getRouteRules } from '#imports'

export default defineEventHandler(async (event) => {
const routeRules = getRouteRules(event)
Expand Down
9 changes: 9 additions & 0 deletions src/runtime/server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../../.nuxt/tsconfig.server.json",
"exclude": [
"../../../docs",
"../../../dist",
"../../../test",
"../../../playground"
]
}
6 changes: 3 additions & 3 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ModuleOptions as CsrfOptions } from 'nuxt-csurf'
import type { ModuleOptions as CsrfOptions } from 'nuxt-csurf'
import type { Options as RemoveOptions } from 'unplugin-remove/types'

import { SecurityHeaders } from './headers'
import { AllowedHTTPMethods, BasicAuth, CorsOptions, RateLimiter, RequestSizeLimiter, XssValidator } from './middlewares'
import type { SecurityHeaders } from './headers'
import type { AllowedHTTPMethods, BasicAuth, CorsOptions, RateLimiter, RequestSizeLimiter, XssValidator } from './middlewares'

export type Ssg = {
hashScripts?: boolean;
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/basicAuth/.nuxtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports.autoImport=true
2 changes: 0 additions & 2 deletions test/fixtures/basicAuth/server/api/hello.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import { defineEventHandler } from 'h3'

export default defineEventHandler(() => 'Hello World')
1 change: 1 addition & 0 deletions test/fixtures/nonce/.nuxtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports.autoImport=true
2 changes: 0 additions & 2 deletions test/fixtures/nonce/server/api/generated-script.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { defineEventHandler } from 'h3'

export default defineEventHandler((event) => {
event.node.res.setHeader('Content-Type', 'application/javascript')
return 'console.log("Hello World")'
Expand Down
2 changes: 0 additions & 2 deletions test/fixtures/nonce/server/api/nonce-exempt.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import { defineEventHandler } from 'h3'

export default defineEventHandler(() => 'Hello World')
3 changes: 3 additions & 0 deletions test/fixtures/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../playground/.nuxt/tsconfig.json"
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"extends": "./playground/.nuxt/tsconfig.json"
"extends": "./.nuxt/tsconfig.json"
}
Loading
Loading