Projektstart
This commit is contained in:
2
backend/node_modules/@fastify/helmet/.gitattributes
generated
vendored
Normal file
2
backend/node_modules/@fastify/helmet/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Set default behavior to automatically convert line endings
|
||||
* text=auto eol=lf
|
||||
13
backend/node_modules/@fastify/helmet/.github/dependabot.yml
generated
vendored
Normal file
13
backend/node_modules/@fastify/helmet/.github/dependabot.yml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
21
backend/node_modules/@fastify/helmet/.github/stale.yml
generated
vendored
Normal file
21
backend/node_modules/@fastify/helmet/.github/stale.yml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 15
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "discussion"
|
||||
- "feature request"
|
||||
- "bug"
|
||||
- "help wanted"
|
||||
- "plugin suggestion"
|
||||
- "good first issue"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
28
backend/node_modules/@fastify/helmet/.github/workflows/ci.yml
generated
vendored
Normal file
28
backend/node_modules/@fastify/helmet/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- next
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5
|
||||
with:
|
||||
license-check: true
|
||||
lint: true
|
||||
49
backend/node_modules/@fastify/helmet/LICENSE
generated
vendored
Normal file
49
backend/node_modules/@fastify/helmet/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-present The Fastify team
|
||||
|
||||
The Fastify team members are listed at https://github.com/fastify/fastify#team.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
--> Original helmet license
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2012-2017 Evan Hahn, Adam Baldwin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
262
backend/node_modules/@fastify/helmet/README.md
generated
vendored
Normal file
262
backend/node_modules/@fastify/helmet/README.md
generated
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
# @fastify/helmet
|
||||
|
||||
[](https://github.com/fastify/fastify-helmet/actions/workflows/ci.yml)
|
||||
[](https://www.npmjs.com/package/@fastify/helmet)
|
||||
[](https://github.com/neostandard/neostandard)
|
||||
|
||||
Important security headers for Fastify, using [helmet](https://npm.im/helmet).
|
||||
|
||||
## Install
|
||||
```
|
||||
npm i @fastify/helmet
|
||||
```
|
||||
|
||||
### Compatibility
|
||||
|
||||
| Plugin version | Fastify version |
|
||||
| ---------------|-----------------|
|
||||
| `>=12.x` | `^5.x` |
|
||||
| `>=9.x <12.x` | `^4.x` |
|
||||
| `>=7.x <9.x` | `^3.x` |
|
||||
| `>=1.x <7.x` | `^2.x` |
|
||||
| `>=1.x <7.x` | `^1.x` |
|
||||
|
||||
|
||||
Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin
|
||||
in the table above.
|
||||
See [Fastify's LTS policy](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details.
|
||||
|
||||
## Usage
|
||||
|
||||
Simply require this plugin to set basic security headers.
|
||||
|
||||
```js
|
||||
const fastify = require('fastify')()
|
||||
const helmet = require('@fastify/helmet')
|
||||
|
||||
fastify.register(
|
||||
helmet,
|
||||
// Example disables the `contentSecurityPolicy` middleware but keeps the rest.
|
||||
{ contentSecurityPolicy: false }
|
||||
)
|
||||
|
||||
fastify.listen({ port: 3000 }, err => {
|
||||
if (err) throw err
|
||||
})
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
`@fastify/helmet` is a wrapper around `helmet` that adds an `'onRequest'` hook
|
||||
and a `reply.helmet` decorator.
|
||||
|
||||
It accepts the same options as `helmet`. See [helmet documentation](https://helmetjs.github.io/).
|
||||
|
||||
### Apply Helmet to all routes
|
||||
|
||||
Pass `{ global: true }` to register Helmet for all routes.
|
||||
For granular control, pass `{ global: false }` to disable it at a global scope.
|
||||
Default is `true`.
|
||||
|
||||
#### Example - enable `@fastify/helmet` globally
|
||||
|
||||
```js
|
||||
fastify.register(helmet)
|
||||
// or
|
||||
fastify.register(helmet, { global: true })
|
||||
```
|
||||
|
||||
#### Example - disable `@fastify/helmet` globally
|
||||
|
||||
```js
|
||||
// register the package with the `{ global: false }` option
|
||||
fastify.register(helmet, { global: false })
|
||||
|
||||
fastify.get('/route-with-disabled-helmet', async (request, reply) => {
|
||||
return { message: 'helmet is not enabled here' }
|
||||
})
|
||||
|
||||
fastify.get('/route-with-enabled-helmet', {
|
||||
// We enable and configure helmet for this route only
|
||||
helmet: {
|
||||
dnsPrefetchControl: {
|
||||
allow: true
|
||||
},
|
||||
frameguard: {
|
||||
action: 'foo'
|
||||
},
|
||||
referrerPolicy: false
|
||||
}
|
||||
}, async (request, reply) => {
|
||||
return { message: 'helmet is enabled here' }
|
||||
})
|
||||
|
||||
// helmet is disabled on this route but we have access to `reply.helmet` decorator
|
||||
// that allows us to apply helmet conditionally
|
||||
fastify.get('/here-we-use-helmet-reply-decorator', async (request, reply) => {
|
||||
if (condition) {
|
||||
// we apply the default options
|
||||
await reply.helmet()
|
||||
} else {
|
||||
// we apply customized options
|
||||
await reply.helmet({ frameguard: false })
|
||||
}
|
||||
|
||||
return {
|
||||
message: 'we use the helmet reply decorator to conditionally apply helmet middlewares'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### `helmet` route option
|
||||
|
||||
`@fastify/helmet` allows enabling, disabling, and customizing `helmet` for each route using the `helmet` shorthand option
|
||||
when registering routes.
|
||||
|
||||
To disable `helmet` for a specific endpoint, pass `{ helmet: false }` to the route options.
|
||||
|
||||
To enable or customize `helmet` for a specific endpoint, pass a configuration object to route options, e.g., `{ helmet: { frameguard: false } }`.
|
||||
|
||||
#### Example - `@fastify/helmet` configuration using the `helmet` shorthand route option
|
||||
|
||||
```js
|
||||
// register the package with the `{ global: true }` option
|
||||
fastify.register(helmet, { global: true })
|
||||
|
||||
fastify.get('/route-with-disabled-helmet', { helmet: false }, async (request, reply) => {
|
||||
return { message: 'helmet is not enabled here' }
|
||||
})
|
||||
|
||||
fastify.get('/route-with-enabled-helmet', async (request, reply) => {
|
||||
return { message: 'helmet is enabled by default here' }
|
||||
})
|
||||
|
||||
fastify.get('/route-with-custom-helmet-configuration', {
|
||||
// We change the helmet configuration for this route only
|
||||
helmet: {
|
||||
enableCSPNonces: true,
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
'directive-1': ['foo', 'bar']
|
||||
},
|
||||
reportOnly: true
|
||||
},
|
||||
dnsPrefetchControl: {
|
||||
allow: true
|
||||
},
|
||||
frameguard: {
|
||||
action: 'foo'
|
||||
},
|
||||
hsts: {
|
||||
maxAge: 1,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
},
|
||||
permittedCrossDomainPolicies: {
|
||||
permittedPolicies: 'foo'
|
||||
},
|
||||
referrerPolicy: false
|
||||
}
|
||||
}, async (request, reply) => {
|
||||
return { message: 'helmet is enabled with a custom configuration on this route' }
|
||||
})
|
||||
```
|
||||
|
||||
### Content-Security-Policy Nonce
|
||||
|
||||
`@fastify/helmet` also allows CSP nonce generation, which can be enabled by passing `{ enableCSPNonces: true }` into the options.
|
||||
Retrieve the `nonces` through `reply.cspNonce`.
|
||||
|
||||
> ℹ️ Note: This feature is implemented by this module and is not supported by `helmet`.
|
||||
> For using `helmet` only for csp nonces, see [example](#example---generate-by-helmet).
|
||||
|
||||
#### Example - Generate by options
|
||||
|
||||
```js
|
||||
fastify.register(
|
||||
helmet,
|
||||
// enable csp nonces generation with default content-security-policy option
|
||||
{ enableCSPNonces: true }
|
||||
)
|
||||
|
||||
fastify.register(
|
||||
helmet,
|
||||
// customize content security policy with nonce generation
|
||||
{
|
||||
enableCSPNonces: true,
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fastify.get('/', function(request, reply) {
|
||||
// retrieve script nonce
|
||||
reply.cspNonce.script
|
||||
// retrieve style nonce
|
||||
reply.cspNonce.style
|
||||
})
|
||||
```
|
||||
|
||||
#### Example - Generate by helmet
|
||||
|
||||
```js
|
||||
fastify.register(
|
||||
helmet,
|
||||
{
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
scriptSrc: [
|
||||
function (req, res) {
|
||||
// "res" here is actually "reply.raw" in fastify
|
||||
res.scriptNonce = crypto.randomBytes(16).toString('hex')
|
||||
// make sure to return nonce-... directive to helmet, so it can be sent in the headers
|
||||
return `'nonce-${res.scriptNonce}'`
|
||||
}
|
||||
],
|
||||
styleSrc: [
|
||||
function (req, res) {
|
||||
// "res" here is actually "reply.raw" in fastify
|
||||
res.styleNonce = crypto.randomBytes(16).toString('hex')
|
||||
// make sure to return nonce-... directive to helmet, so it can be sent in the headers
|
||||
return `'nonce-${res.styleNonce}'`
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fastify.get('/', function(request, reply) {
|
||||
// access the generated nonce by "reply.raw"
|
||||
reply.raw.scriptNonce
|
||||
reply.raw.styleNonce
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
### Disable Default `helmet` Directives
|
||||
|
||||
By default, `helmet` adds [a default set of CSP directives](https://github.com/helmetjs/helmet/tree/main/middlewares/content-security-policy#content-security-policy-middleware) to the response.
|
||||
Disable this by setting `useDefaults: false` in the `contentSecurityPolicy` configuration.
|
||||
|
||||
```js
|
||||
fastify.register(
|
||||
helmet,
|
||||
{
|
||||
contentSecurityPolicy: {
|
||||
useDefaults: false,
|
||||
directives: {
|
||||
'default-src': ["'self'"]
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Licensed under [MIT](./LICENSE).
|
||||
6
backend/node_modules/@fastify/helmet/eslint.config.js
generated
vendored
Normal file
6
backend/node_modules/@fastify/helmet/eslint.config.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = require('neostandard')({
|
||||
ignores: require('neostandard').resolveIgnoresFromGitignore(),
|
||||
ts: true
|
||||
})
|
||||
46
backend/node_modules/@fastify/helmet/examples/example.js
generated
vendored
Normal file
46
backend/node_modules/@fastify/helmet/examples/example.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict'
|
||||
|
||||
const Fastify = require('fastify')
|
||||
const helmet = require('..')
|
||||
|
||||
const fastify = Fastify({
|
||||
logger: {
|
||||
level: 'info'
|
||||
}
|
||||
})
|
||||
|
||||
fastify.register(helmet)
|
||||
|
||||
const opts = {
|
||||
schema: {
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fastify.get('/', opts, function (_request, reply) {
|
||||
reply
|
||||
.header('Content-Type', 'application/json')
|
||||
.code(200)
|
||||
.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.get('/route-with-disabled-helmet', { ...opts, helmet: false }, function (_request, reply) {
|
||||
reply
|
||||
.header('Content-Type', 'application/json')
|
||||
.code(200)
|
||||
.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 3000 }, err => {
|
||||
if (err) throw err
|
||||
fastify.log.info(`Server listening on ${fastify.server.address().address}:${fastify.server.address().port}`)
|
||||
})
|
||||
151
backend/node_modules/@fastify/helmet/index.js
generated
vendored
Normal file
151
backend/node_modules/@fastify/helmet/index.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
'use strict'
|
||||
|
||||
const { randomBytes } = require('node:crypto')
|
||||
const fp = require('fastify-plugin')
|
||||
const helmet = require('helmet')
|
||||
|
||||
async function fastifyHelmet (fastify, options) {
|
||||
// helmet will throw when any option is explicitly set to "true"
|
||||
// using ECMAScript destructuring is a clean workaround as we do not need to alter options
|
||||
const { enableCSPNonces, global, ...globalConfiguration } = options
|
||||
|
||||
const isGlobal = typeof global === 'boolean' ? global : true
|
||||
|
||||
// We initialize the `helmet` reply decorator only if it does not already exists
|
||||
if (!fastify.hasReplyDecorator('helmet')) {
|
||||
fastify.decorateReply('helmet', null)
|
||||
}
|
||||
|
||||
// We initialize the `cspNonce` reply decorator only if it does not already exists
|
||||
if (!fastify.hasReplyDecorator('cspNonce')) {
|
||||
fastify.decorateReply('cspNonce', null)
|
||||
}
|
||||
|
||||
fastify.addHook('onRoute', (routeOptions) => {
|
||||
if (routeOptions.helmet !== undefined) {
|
||||
if (typeof routeOptions.helmet === 'object') {
|
||||
routeOptions.config = Object.assign(routeOptions.config || Object.create(null), { helmet: routeOptions.helmet })
|
||||
} else if (routeOptions.helmet === false) {
|
||||
routeOptions.config = Object.assign(routeOptions.config || Object.create(null), { helmet: { skipRoute: true } })
|
||||
} else {
|
||||
throw new Error('Unknown value for route helmet configuration')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fastify.addHook('onRequest', async function helmetConfigureReply (request, reply) {
|
||||
const { helmet: routeOptions } = request.routeOptions?.config
|
||||
|
||||
if (routeOptions !== undefined) {
|
||||
const { enableCSPNonces: enableRouteCSPNonces, skipRoute, ...helmetRouteConfiguration } = routeOptions
|
||||
// If route helmet options are set they overwrite the global helmet configuration
|
||||
const mergedHelmetConfiguration = Object.assign(Object.create(null), globalConfiguration, helmetRouteConfiguration)
|
||||
|
||||
// We decorate the reply with a fallback to the route scoped helmet options
|
||||
return replyDecorators(request, reply, mergedHelmetConfiguration, enableRouteCSPNonces)
|
||||
}
|
||||
|
||||
// We decorate the reply with a fallback to the global helmet options
|
||||
return replyDecorators(request, reply, globalConfiguration, enableCSPNonces)
|
||||
})
|
||||
|
||||
fastify.addHook('onRequest', function helmetApplyHeaders (request, reply, next) {
|
||||
const { helmet: routeOptions } = request.routeOptions?.config
|
||||
|
||||
if (routeOptions !== undefined) {
|
||||
const { enableCSPNonces: enableRouteCSPNonces, skipRoute, ...helmetRouteConfiguration } = routeOptions
|
||||
|
||||
if (skipRoute === true) {
|
||||
// If helmet route option is set to `false` we skip the route
|
||||
} else {
|
||||
// If route helmet options are set they overwrite the global helmet configuration
|
||||
const mergedHelmetConfiguration = Object.assign(Object.create(null), globalConfiguration, helmetRouteConfiguration)
|
||||
|
||||
return buildHelmetOnRoutes(request, reply, mergedHelmetConfiguration, enableRouteCSPNonces)
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
if (isGlobal) {
|
||||
// if the plugin is set globally (meaning that all the routes will be decorated)
|
||||
// As the endpoint, does not have a custom helmet configuration, use the global one.
|
||||
return buildHelmetOnRoutes(request, reply, globalConfiguration, enableCSPNonces)
|
||||
}
|
||||
|
||||
// if the plugin is not global we can skip the route
|
||||
return next()
|
||||
})
|
||||
}
|
||||
|
||||
async function replyDecorators (request, reply, configuration, enableCSP) {
|
||||
if (enableCSP) {
|
||||
reply.cspNonce = {
|
||||
script: randomBytes(16).toString('hex'),
|
||||
style: randomBytes(16).toString('hex')
|
||||
}
|
||||
}
|
||||
|
||||
reply.helmet = function (opts) {
|
||||
const helmetConfiguration = opts
|
||||
? Object.assign(Object.create(null), configuration, opts)
|
||||
: configuration
|
||||
|
||||
return helmet(helmetConfiguration)(request.raw, reply.raw, done)
|
||||
}
|
||||
}
|
||||
|
||||
async function buildHelmetOnRoutes (request, reply, configuration, enableCSP) {
|
||||
if (enableCSP === true && configuration.contentSecurityPolicy !== false) {
|
||||
const cspDirectives = configuration.contentSecurityPolicy
|
||||
? configuration.contentSecurityPolicy.directives
|
||||
: helmet.contentSecurityPolicy.getDefaultDirectives()
|
||||
const cspReportOnly = configuration.contentSecurityPolicy
|
||||
? configuration.contentSecurityPolicy.reportOnly
|
||||
: undefined
|
||||
const cspUseDefaults = configuration.contentSecurityPolicy
|
||||
? configuration.contentSecurityPolicy.useDefaults
|
||||
: undefined
|
||||
|
||||
// We get the csp nonce from the reply
|
||||
const { script: scriptCSPNonce, style: styleCSPNonce } = reply.cspNonce
|
||||
|
||||
// We prevent object reference: https://github.com/fastify/fastify-helmet/issues/118
|
||||
const directives = { ...cspDirectives }
|
||||
|
||||
// We push nonce to csp
|
||||
// We allow both 'script-src' or 'scriptSrc' syntax
|
||||
const scriptKey = Array.isArray(directives['script-src']) ? 'script-src' : 'scriptSrc'
|
||||
directives[scriptKey] = Array.isArray(directives[scriptKey]) ? [...directives[scriptKey]] : []
|
||||
directives[scriptKey].push(`'nonce-${scriptCSPNonce}'`)
|
||||
// allow both style-src or styleSrc syntax
|
||||
const styleKey = Array.isArray(directives['style-src']) ? 'style-src' : 'styleSrc'
|
||||
directives[styleKey] = Array.isArray(directives[styleKey]) ? [...directives[styleKey]] : []
|
||||
directives[styleKey].push(`'nonce-${styleCSPNonce}'`)
|
||||
|
||||
const contentSecurityPolicy = { directives, reportOnly: cspReportOnly, useDefaults: cspUseDefaults }
|
||||
const mergedHelmetConfiguration = Object.assign(Object.create(null), configuration, { contentSecurityPolicy })
|
||||
|
||||
helmet(mergedHelmetConfiguration)(request.raw, reply.raw, done)
|
||||
} else {
|
||||
helmet(configuration)(request.raw, reply.raw, done)
|
||||
}
|
||||
}
|
||||
|
||||
function done (error) {
|
||||
// Helmet used to forward an Error object, so we could just rethrow it.
|
||||
// Since Helmet v8.1.0 (see PR https://github.com/helmetjs/helmet/pull/485 ),
|
||||
// errors are thrown directly instead of being passed to a callback.
|
||||
// We keep the argument for compatibility, as v8.1.0 still accepts it
|
||||
// (see https://github.com/helmetjs/helmet/blob/v8.1.0/index.ts#L109 ).
|
||||
/* c8 ignore next */
|
||||
if (error) throw error
|
||||
}
|
||||
|
||||
module.exports = fp(fastifyHelmet, {
|
||||
fastify: '5.x',
|
||||
name: '@fastify/helmet'
|
||||
})
|
||||
module.exports.default = fastifyHelmet
|
||||
module.exports.fastifyHelmet = fastifyHelmet
|
||||
|
||||
module.exports.contentSecurityPolicy = helmet.contentSecurityPolicy
|
||||
2
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.gitattributes
generated
vendored
Normal file
2
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Set default behavior to automatically convert line endings
|
||||
* text=auto eol=lf
|
||||
13
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.github/dependabot.yml
generated
vendored
Normal file
13
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.github/dependabot.yml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
21
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.github/stale.yml
generated
vendored
Normal file
21
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.github/stale.yml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 15
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "discussion"
|
||||
- "feature request"
|
||||
- "bug"
|
||||
- "help wanted"
|
||||
- "plugin suggestion"
|
||||
- "good first issue"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
28
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.github/workflows/ci.yml
generated
vendored
Normal file
28
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- next
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5
|
||||
with:
|
||||
license-check: true
|
||||
lint: true
|
||||
23
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/LICENSE
generated
vendored
Normal file
23
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-present The Fastify team
|
||||
|
||||
The Fastify team members are listed at https://github.com/fastify/fastify#team.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
188
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/README.md
generated
vendored
Normal file
188
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/README.md
generated
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
# fastify-plugin
|
||||
|
||||
[](https://github.com/fastify/fastify-plugin/actions/workflows/ci.yml)
|
||||
[](https://www.npmjs.com/package/fastify-plugin)
|
||||
[](https://github.com/neostandard/neostandard)
|
||||
|
||||
`fastify-plugin` is a plugin helper for [Fastify](https://github.com/fastify/fastify).
|
||||
|
||||
When you build plugins for Fastify and you want them to be accessible in the same context where you require them, you have two ways:
|
||||
1. Use the `skip-override` hidden property
|
||||
2. Use this module
|
||||
|
||||
__Note: the v4.x series of this module covers Fastify v4__
|
||||
__Note: the v2.x & v3.x series of this module covers Fastify v3. For Fastify v2 support, refer to the v1.x series.__
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm i fastify-plugin
|
||||
```
|
||||
|
||||
## Usage
|
||||
`fastify-plugin` can do three things for you:
|
||||
- Add the `skip-override` hidden property
|
||||
- Check the bare-minimum version of Fastify
|
||||
- Pass some custom metadata of the plugin to Fastify
|
||||
|
||||
Example using a callback:
|
||||
```js
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
module.exports = fp(function (fastify, opts, done) {
|
||||
// your plugin code
|
||||
done()
|
||||
})
|
||||
```
|
||||
|
||||
Example using an [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) function:
|
||||
```js
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
// A callback function param is not required for async functions
|
||||
module.exports = fp(async function (fastify, opts) {
|
||||
// Wait for an async function to fulfill promise before proceeding
|
||||
await exampleAsyncFunction()
|
||||
})
|
||||
```
|
||||
|
||||
## Metadata
|
||||
In addition, if you use this module when creating new plugins, you can declare the dependencies, the name, and the expected Fastify version that your plugin needs.
|
||||
|
||||
#### Fastify version
|
||||
If you need to set a bare-minimum version of Fastify for your plugin, just add the [semver](https://semver.org/) range that you need:
|
||||
```js
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
module.exports = fp(function (fastify, opts, done) {
|
||||
// your plugin code
|
||||
done()
|
||||
}, { fastify: '5.x' })
|
||||
```
|
||||
|
||||
If you need to check the Fastify version only, you can pass just the version string.
|
||||
|
||||
You can check [here](https://github.com/npm/node-semver#ranges) how to define a `semver` range.
|
||||
|
||||
#### Name
|
||||
Fastify uses this option to validate the dependency graph, allowing it to ensure that no name collisions occur and making it possible to perform [dependency checks](https://github.com/fastify/fastify-plugin#dependencies).
|
||||
|
||||
```js
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
function plugin (fastify, opts, done) {
|
||||
// your plugin code
|
||||
done()
|
||||
}
|
||||
|
||||
module.exports = fp(plugin, {
|
||||
fastify: '5.x',
|
||||
name: 'your-plugin-name'
|
||||
})
|
||||
```
|
||||
|
||||
#### Dependencies
|
||||
You can also check if the `plugins` and `decorators` that your plugin intend to use are present in the dependency graph.
|
||||
> *Note:* This is the point where registering `name` of the plugins become important, because you can reference `plugin` dependencies by their [name](https://github.com/fastify/fastify-plugin#name).
|
||||
```js
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
function plugin (fastify, opts, done) {
|
||||
// your plugin code
|
||||
done()
|
||||
}
|
||||
|
||||
module.exports = fp(plugin, {
|
||||
fastify: '5.x',
|
||||
decorators: {
|
||||
fastify: ['plugin1', 'plugin2'],
|
||||
reply: ['compress']
|
||||
},
|
||||
dependencies: ['plugin1-name', 'plugin2-name']
|
||||
})
|
||||
```
|
||||
|
||||
#### Encapsulate
|
||||
|
||||
By default, `fastify-plugin` breaks the [encapsulation](https://github.com/fastify/fastify/blob/HEAD/docs/Reference/Encapsulation.md) but you can optionally keep the plugin encapsulated.
|
||||
This allows you to set the plugin's name and validate its dependencies without making the plugin accessible.
|
||||
```js
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
function plugin (fastify, opts, done) {
|
||||
// the decorator is not accessible outside this plugin
|
||||
fastify.decorate('util', function() {})
|
||||
done()
|
||||
}
|
||||
|
||||
module.exports = fp(plugin, {
|
||||
name: 'my-encapsulated-plugin',
|
||||
fastify: '5.x',
|
||||
decorators: {
|
||||
fastify: ['plugin1', 'plugin2'],
|
||||
reply: ['compress']
|
||||
},
|
||||
dependencies: ['plugin1-name', 'plugin2-name'],
|
||||
encapsulate: true
|
||||
})
|
||||
```
|
||||
|
||||
#### Bundlers and Typescript
|
||||
`fastify-plugin` adds a `.default` and `[name]` property to the passed in function.
|
||||
The type definition would have to be updated to leverage this.
|
||||
|
||||
## Known Issue: TypeScript Contextual Inference
|
||||
|
||||
[Documentation Reference](https://www.typescriptlang.org/docs/handbook/functions.html#inferring-the-types)
|
||||
|
||||
It is common for developers to inline their plugin with fastify-plugin such as:
|
||||
|
||||
```js
|
||||
fp((fastify, opts, done) => { done() })
|
||||
fp(async (fastify, opts) => { return })
|
||||
```
|
||||
|
||||
TypeScript can sometimes infer the types of the arguments for these functions. Plugins in Fastify are recommended to be typed using either `FastifyPluginCallback` or `FastifyPluginAsync`. These two definitions only differ in two ways:
|
||||
|
||||
1. The third argument `done` (the callback part)
|
||||
2. The return type `FastifyPluginCallback` or `FastifyPluginAsync`
|
||||
|
||||
At this time, TypeScript inference is not smart enough to differentiate by definition argument length alone.
|
||||
|
||||
Thus, if you are a TypeScript developer please use on the following patterns instead:
|
||||
|
||||
```ts
|
||||
// Callback
|
||||
|
||||
// Assign type directly
|
||||
const pluginCallback: FastifyPluginCallback = (fastify, options, done) => { }
|
||||
fp(pluginCallback)
|
||||
|
||||
// or define your own function declaration that satisfies the existing definitions
|
||||
const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, done: (error?: FastifyError) => void): void => { }
|
||||
fp(pluginCallbackWithTypes)
|
||||
// or inline
|
||||
fp((fastify: FastifyInstance, options: FastifyPluginOptions, done: (error?: FastifyError) => void): void => { })
|
||||
|
||||
// Async
|
||||
|
||||
// Assign type directly
|
||||
const pluginAsync: FastifyPluginAsync = async (fastify, options) => { }
|
||||
fp(pluginAsync)
|
||||
|
||||
// or define your own function declaration that satisfies the existing definitions
|
||||
const pluginAsyncWithTypes = async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { }
|
||||
fp(pluginAsyncWithTypes)
|
||||
// or inline
|
||||
fp(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { })
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
This project is kindly sponsored by:
|
||||
- [nearForm](https://nearform.com)
|
||||
- [LetzDoIt](https://www.letzdoitapp.com/)
|
||||
|
||||
## License
|
||||
|
||||
Licensed under [MIT](./LICENSE).
|
||||
6
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/eslint.config.js
generated
vendored
Normal file
6
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/eslint.config.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = require('neostandard')({
|
||||
ignores: require('neostandard').resolveIgnoresFromGitignore(),
|
||||
ts: true
|
||||
})
|
||||
25
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/lib/getPluginName.js
generated
vendored
Normal file
25
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/lib/getPluginName.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict'
|
||||
|
||||
const fpStackTracePattern = /at\s(?:.*\.)?plugin\s.*\n\s*(.*)/
|
||||
const fileNamePattern = /(\w*(\.\w*)*)\..*/
|
||||
|
||||
module.exports = function getPluginName (fn) {
|
||||
if (fn.name.length > 0) return fn.name
|
||||
|
||||
const stackTraceLimit = Error.stackTraceLimit
|
||||
Error.stackTraceLimit = 10
|
||||
try {
|
||||
throw new Error('anonymous function')
|
||||
} catch (e) {
|
||||
Error.stackTraceLimit = stackTraceLimit
|
||||
return extractPluginName(e.stack)
|
||||
}
|
||||
}
|
||||
|
||||
function extractPluginName (stack) {
|
||||
const m = stack.match(fpStackTracePattern)
|
||||
|
||||
// get last section of path and match for filename
|
||||
return m ? m[1].split(/[/\\]/).slice(-1)[0].match(fileNamePattern)[1] : 'anonymous'
|
||||
}
|
||||
module.exports.extractPluginName = extractPluginName
|
||||
10
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/lib/toCamelCase.js
generated
vendored
Normal file
10
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/lib/toCamelCase.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = function toCamelCase (name) {
|
||||
if (name[0] === '@') {
|
||||
name = name.slice(1).replace('/', '-')
|
||||
}
|
||||
return name.replace(/-(.)/g, function (match, g1) {
|
||||
return g1.toUpperCase()
|
||||
})
|
||||
}
|
||||
70
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/package.json
generated
vendored
Normal file
70
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/package.json
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "fastify-plugin",
|
||||
"version": "5.1.0",
|
||||
"description": "Plugin helper for Fastify",
|
||||
"main": "plugin.js",
|
||||
"type": "commonjs",
|
||||
"types": "types/plugin.d.ts",
|
||||
"scripts": {
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix",
|
||||
"test": "npm run test:unit && npm run test:typescript",
|
||||
"test:unit": "c8 --100 node --test",
|
||||
"test:coverage": "c8 node --test && c8 report --reporter=html",
|
||||
"test:typescript": "tsd"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/fastify-plugin.git"
|
||||
},
|
||||
"keywords": [
|
||||
"plugin",
|
||||
"helper",
|
||||
"fastify"
|
||||
],
|
||||
"author": "Tomas Della Vedova - @delvedor (http://delved.org)",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Matteo Collina",
|
||||
"email": "hello@matteocollina.com"
|
||||
},
|
||||
{
|
||||
"name": "Manuel Spigolon",
|
||||
"email": "behemoth89@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Aras Abbasi",
|
||||
"email": "aras.abbasi@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Frazer Smith",
|
||||
"email": "frazer.dev@icloud.com",
|
||||
"url": "https://github.com/fdawgs"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/fastify/fastify-plugin/issues"
|
||||
},
|
||||
"homepage": "https://github.com/fastify/fastify-plugin#readme",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"devDependencies": {
|
||||
"@fastify/type-provider-typebox": "^5.1.0",
|
||||
"@types/node": "^24.0.8",
|
||||
"c8": "^10.1.2",
|
||||
"eslint": "^9.17.0",
|
||||
"fastify": "^5.0.0",
|
||||
"neostandard": "^0.12.0",
|
||||
"proxyquire": "^2.1.3",
|
||||
"tsd": "^0.33.0"
|
||||
}
|
||||
}
|
||||
67
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/plugin.js
generated
vendored
Normal file
67
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/plugin.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
'use strict'
|
||||
|
||||
const getPluginName = require('./lib/getPluginName')
|
||||
const toCamelCase = require('./lib/toCamelCase')
|
||||
|
||||
let count = 0
|
||||
|
||||
function plugin (fn, options = {}) {
|
||||
let autoName = false
|
||||
|
||||
if (fn.default !== undefined) {
|
||||
// Support for 'export default' behaviour in transpiled ECMAScript module
|
||||
fn = fn.default
|
||||
}
|
||||
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError(
|
||||
`fastify-plugin expects a function, instead got a '${typeof fn}'`
|
||||
)
|
||||
}
|
||||
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
fastify: options
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
typeof options !== 'object' ||
|
||||
Array.isArray(options) ||
|
||||
options === null
|
||||
) {
|
||||
throw new TypeError('The options object should be an object')
|
||||
}
|
||||
|
||||
if (options.fastify !== undefined && typeof options.fastify !== 'string') {
|
||||
throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`)
|
||||
}
|
||||
|
||||
if (!options.name) {
|
||||
autoName = true
|
||||
options.name = getPluginName(fn) + '-auto-' + count++
|
||||
}
|
||||
|
||||
fn[Symbol.for('skip-override')] = options.encapsulate !== true
|
||||
fn[Symbol.for('fastify.display-name')] = options.name
|
||||
fn[Symbol.for('plugin-meta')] = options
|
||||
|
||||
// Faux modules support
|
||||
if (!fn.default) {
|
||||
fn.default = fn
|
||||
}
|
||||
|
||||
// TypeScript support for named imports
|
||||
// See https://github.com/fastify/fastify/issues/2404 for more details
|
||||
// The type definitions would have to be update to match this.
|
||||
const camelCase = toCamelCase(options.name)
|
||||
if (!autoName && !fn[camelCase]) {
|
||||
fn[camelCase] = fn
|
||||
}
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
module.exports = plugin
|
||||
module.exports.default = plugin
|
||||
module.exports.fastifyPlugin = plugin
|
||||
110
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/bundlers.test.js
generated
vendored
Normal file
110
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/bundlers.test.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fp = require('../plugin')
|
||||
|
||||
test('webpack removes require.main.filename', t => {
|
||||
const filename = require.main.filename
|
||||
const info = console.info
|
||||
t.after(() => {
|
||||
require.main.filename = filename
|
||||
console.info = info
|
||||
})
|
||||
|
||||
require.main.filename = null
|
||||
|
||||
console.info = function (msg) {
|
||||
t.assert.fail('logged: ' + msg)
|
||||
}
|
||||
|
||||
fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
fastify: '^5.0.0'
|
||||
})
|
||||
})
|
||||
|
||||
test('support faux modules', (t) => {
|
||||
const plugin = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.default, plugin)
|
||||
})
|
||||
|
||||
test('support faux modules does not override existing default field in babel module', (t) => {
|
||||
const module = {
|
||||
default: (_fastify, _opts, next) => next()
|
||||
}
|
||||
|
||||
module.default.default = 'Existing default field'
|
||||
|
||||
const plugin = fp(module)
|
||||
|
||||
t.assert.strictEqual(plugin.default, 'Existing default field')
|
||||
})
|
||||
|
||||
test('support ts named imports', (t) => {
|
||||
const plugin = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
name: 'hello'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.hello, plugin)
|
||||
})
|
||||
|
||||
test('from kebab-case to camelCase', (t) => {
|
||||
const plugin = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
name: 'hello-world'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.helloWorld, plugin)
|
||||
})
|
||||
|
||||
test('from @-prefixed named imports', (t) => {
|
||||
const plugin = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
name: '@hello/world'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.helloWorld, plugin)
|
||||
})
|
||||
|
||||
test('from @-prefixed named kebab-case to camelCase', (t) => {
|
||||
const plugin = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
name: '@hello/my-world'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.helloMyWorld, plugin)
|
||||
})
|
||||
|
||||
test('from kebab-case to camelCase multiple words', (t) => {
|
||||
const plugin = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
name: 'hello-long-world'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.helloLongWorld, plugin)
|
||||
})
|
||||
|
||||
test('from kebab-case to camelCase multiple words does not override', (t) => {
|
||||
const fn = (_fastify, _opts, next) => {
|
||||
next()
|
||||
}
|
||||
|
||||
const foobar = {}
|
||||
fn.helloLongWorld = foobar
|
||||
|
||||
const plugin = fp(fn, {
|
||||
name: 'hello-long-world'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(plugin.helloLongWorld, foobar)
|
||||
})
|
||||
67
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/checkVersion.test.js
generated
vendored
Normal file
67
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/checkVersion.test.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fp = require('../plugin')
|
||||
|
||||
test('checkVersion having require.main.filename', (t) => {
|
||||
const info = console.info
|
||||
t.assert.ok(require.main.filename)
|
||||
t.after(() => {
|
||||
console.info = info
|
||||
})
|
||||
|
||||
console.info = function (msg) {
|
||||
t.assert.fail('logged: ' + msg)
|
||||
}
|
||||
|
||||
fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
fastify: '^5.0.0'
|
||||
})
|
||||
})
|
||||
|
||||
test('checkVersion having no require.main.filename but process.argv[1]', (t) => {
|
||||
const filename = require.main.filename
|
||||
const info = console.info
|
||||
t.after(() => {
|
||||
require.main.filename = filename
|
||||
console.info = info
|
||||
})
|
||||
|
||||
require.main.filename = null
|
||||
|
||||
console.info = function (msg) {
|
||||
t.assert.fail('logged: ' + msg)
|
||||
}
|
||||
|
||||
fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
fastify: '^5.0.0'
|
||||
})
|
||||
})
|
||||
|
||||
test('checkVersion having no require.main.filename and no process.argv[1]', (t) => {
|
||||
const filename = require.main.filename
|
||||
const argv = process.argv
|
||||
const info = console.info
|
||||
t.after(() => {
|
||||
require.main.filename = filename
|
||||
process.argv = argv
|
||||
console.info = info
|
||||
})
|
||||
|
||||
require.main.filename = null
|
||||
process.argv[1] = null
|
||||
|
||||
console.info = function (msg) {
|
||||
t.assert.fail('logged: ' + msg)
|
||||
}
|
||||
|
||||
fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
fastify: '^5.0.0'
|
||||
})
|
||||
})
|
||||
14
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/composite.test.js
generated
vendored
Normal file
14
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/composite.test.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fp = require('../plugin')
|
||||
|
||||
test('anonymous function should be named composite.test0', (t) => {
|
||||
t.plan(2)
|
||||
const fn = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'composite.test-auto-0')
|
||||
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'composite.test-auto-0')
|
||||
})
|
||||
11
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/esm/esm.mjs
generated
vendored
Normal file
11
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/esm/esm.mjs
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { test } from 'node:test'
|
||||
import fp from '../../plugin.js'
|
||||
|
||||
test('esm base support', (t) => {
|
||||
fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
}, {
|
||||
fastify: '^5.0.0'
|
||||
})
|
||||
t.assert.ok(true, 'fp function called without throwing an error')
|
||||
})
|
||||
11
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/esm/index.test.js
generated
vendored
Normal file
11
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/esm/index.test.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
// Node v8 throw a `SyntaxError: Unexpected token import`
|
||||
// even if this branch is never touch in the code,
|
||||
// by using `eval` we can avoid this issue.
|
||||
// eslint-disable-next-line
|
||||
new Function('module', 'return import(module)')('./esm.mjs').catch((err) => {
|
||||
process.nextTick(() => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
49
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/extractPluginName.test.js
generated
vendored
Normal file
49
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/extractPluginName.test.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const extractPluginName = require('../lib/getPluginName').extractPluginName
|
||||
|
||||
const winStack = `Error: anonymous function
|
||||
at checkName (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\index.js:43:11)
|
||||
at plugin (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\index.js:24:20)
|
||||
at Test.test (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\test\\hello.test.js:9:14)
|
||||
at bound (domain.js:396:14)
|
||||
at Test.runBound (domain.js:409:12)
|
||||
at ret (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:278:21)
|
||||
at Test.main (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:282:7)
|
||||
at writeSubComment (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:371:13)
|
||||
at TAP.writeSubComment (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:403:5)
|
||||
at Test.runBeforeEach (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:370:14)
|
||||
at loop (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\function-loop\\index.js:35:15)
|
||||
at TAP.runBeforeEach (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:683:7)
|
||||
at TAP.processSubtest (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:369:12)
|
||||
at TAP.process (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:306:14)
|
||||
at TAP.sub (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:185:10)
|
||||
at TAP.test (C:\\Users\\leonardo.davinci\\Desktop\\fastify-plugin\\node_modules\\tap\\lib\\test.js:209:17)`
|
||||
|
||||
const nixStack = `Error: anonymous function
|
||||
at checkName (/home/leonardo/desktop/fastify-plugin/index.js:43:11)
|
||||
at plugin (/home/leonardo/desktop/fastify-plugin/index.js:24:20)
|
||||
at Test.test (/home/leonardo/desktop/fastify-plugin/test/this.is.a.test.js:9:14)
|
||||
at bound (domain.js:396:14)
|
||||
at Test.runBound (domain.js:409:12)
|
||||
at ret (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:278:21)
|
||||
at Test.main (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:282:7)
|
||||
at writeSubComment (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:371:13)
|
||||
at TAP.writeSubComment (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:403:5)
|
||||
at Test.runBeforeEach (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:370:14)
|
||||
at loop (/home/leonardo/desktop/fastify-plugin/node_modules/function-loop/index.js:35:15)
|
||||
at TAP.runBeforeEach (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:683:7)
|
||||
at TAP.processSubtest (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:369:12)
|
||||
at TAP.process (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:306:14)
|
||||
at TAP.sub (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:185:10)
|
||||
at TAP.test (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:209:17)`
|
||||
|
||||
const anonymousStack = 'Unable to parse this'
|
||||
|
||||
test('extractPluginName tests', (t) => {
|
||||
t.plan(3)
|
||||
t.assert.strictEqual(extractPluginName(winStack), 'hello.test')
|
||||
t.assert.strictEqual(extractPluginName(nixStack), 'this.is.a.test')
|
||||
t.assert.strictEqual(extractPluginName(anonymousStack), 'anonymous')
|
||||
})
|
||||
15
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/mu1tip1e.composite.test.js
generated
vendored
Normal file
15
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/mu1tip1e.composite.test.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fp = require('../plugin')
|
||||
|
||||
test('anonymous function should be named mu1tip1e.composite.test', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const fn = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'mu1tip1e.composite.test-auto-0')
|
||||
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'mu1tip1e.composite.test-auto-0')
|
||||
})
|
||||
396
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/test.js
generated
vendored
Normal file
396
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/test.js
generated
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const proxyquire = require('proxyquire')
|
||||
const fp = require('../plugin')
|
||||
const Fastify = require('fastify')
|
||||
|
||||
const pkg = require('../package.json')
|
||||
|
||||
test('fastify-plugin is a function', (t) => {
|
||||
t.plan(1)
|
||||
t.assert.ok(typeof fp === 'function')
|
||||
})
|
||||
|
||||
test('should return the function with the skip-override Symbol', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
function plugin (_fastify, _opts, next) {
|
||||
next()
|
||||
}
|
||||
|
||||
fp(plugin)
|
||||
t.assert.ok(plugin[Symbol.for('skip-override')])
|
||||
})
|
||||
|
||||
test('should support "default" function from babel module', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const plugin = {
|
||||
default: () => { }
|
||||
}
|
||||
|
||||
try {
|
||||
fp(plugin)
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.strictEqual(e.message, 'fastify-plugin expects a function, instead got a \'object\'')
|
||||
}
|
||||
})
|
||||
|
||||
test('should throw if the plugin is not a function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
try {
|
||||
fp('plugin')
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.strictEqual(e.message, 'fastify-plugin expects a function, instead got a \'string\'')
|
||||
}
|
||||
})
|
||||
|
||||
test('should check the fastify version', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
function plugin (_fastify, _opts, next) {
|
||||
next()
|
||||
}
|
||||
|
||||
try {
|
||||
fp(plugin, { fastify: '>=0.10.0' })
|
||||
t.assert.ok(true)
|
||||
} catch {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('should check the fastify version', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
function plugin (_fastify, _opts, next) {
|
||||
next()
|
||||
}
|
||||
|
||||
try {
|
||||
fp(plugin, '>=0.10.0')
|
||||
t.assert.ok(true)
|
||||
} catch {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('the options object should be an object', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
try {
|
||||
fp(() => { }, null)
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.strictEqual(e.message, 'The options object should be an object')
|
||||
}
|
||||
|
||||
try {
|
||||
fp(() => { }, [])
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.strictEqual(e.message, 'The options object should be an object')
|
||||
}
|
||||
})
|
||||
|
||||
test('should throw if the version number is not a string', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
try {
|
||||
fp(() => { }, { fastify: 12 })
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.strictEqual(e.message, 'fastify-plugin expects a version string, instead got \'number\'')
|
||||
}
|
||||
})
|
||||
|
||||
test('Should accept an option object', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const opts = { hello: 'world' }
|
||||
|
||||
function plugin (_fastify, _opts, next) {
|
||||
next()
|
||||
}
|
||||
|
||||
fp(plugin, opts)
|
||||
|
||||
t.assert.ok(plugin[Symbol.for('skip-override')], 'skip-override symbol should be present')
|
||||
t.assert.deepStrictEqual(plugin[Symbol.for('plugin-meta')], opts, 'plugin-meta should match opts')
|
||||
})
|
||||
|
||||
test('Should accept an option object and checks the version', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const opts = { hello: 'world', fastify: '>=0.10.0' }
|
||||
|
||||
function plugin (_fastify, _opts, next) {
|
||||
next()
|
||||
}
|
||||
|
||||
fp(plugin, opts)
|
||||
t.assert.ok(plugin[Symbol.for('skip-override')])
|
||||
t.assert.deepStrictEqual(plugin[Symbol.for('plugin-meta')], opts)
|
||||
})
|
||||
|
||||
test('should set anonymous function name to file it was called from with a counter', (t) => {
|
||||
const fp = proxyquire('../plugin.js', { stubs: {} })
|
||||
|
||||
const fn = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'test-auto-0')
|
||||
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'test-auto-0')
|
||||
|
||||
const fn2 = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn2[Symbol.for('plugin-meta')].name, 'test-auto-1')
|
||||
t.assert.strictEqual(fn2[Symbol.for('fastify.display-name')], 'test-auto-1')
|
||||
})
|
||||
|
||||
test('should set function name if Error.stackTraceLimit is set to 0', (t) => {
|
||||
const stackTraceLimit = Error.stackTraceLimit = 0
|
||||
|
||||
const fp = proxyquire('../plugin.js', { stubs: {} })
|
||||
|
||||
const fn = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'test-auto-0')
|
||||
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'test-auto-0')
|
||||
|
||||
const fn2 = fp((_fastify, _opts, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn2[Symbol.for('plugin-meta')].name, 'test-auto-1')
|
||||
t.assert.strictEqual(fn2[Symbol.for('fastify.display-name')], 'test-auto-1')
|
||||
|
||||
Error.stackTraceLimit = stackTraceLimit
|
||||
})
|
||||
|
||||
test('should set display-name to meta name', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const functionName = 'superDuperSpecialFunction'
|
||||
|
||||
const fn = fp((_fastify, _opts, next) => next(), {
|
||||
name: functionName
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, functionName)
|
||||
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], functionName)
|
||||
})
|
||||
|
||||
test('should preserve fastify version in meta', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const opts = { hello: 'world', fastify: '>=0.10.0' }
|
||||
|
||||
const fn = fp((_fastify, _opts, next) => next(), opts)
|
||||
|
||||
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].fastify, '>=0.10.0')
|
||||
})
|
||||
|
||||
test('should check fastify dependency graph - plugin', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'plugin1-name'
|
||||
}))
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'test',
|
||||
dependencies: ['plugin1-name', 'plugin2-name']
|
||||
}))
|
||||
|
||||
await t.assert.rejects(fastify.ready(), { message: "The dependency 'plugin2-name' of plugin 'test' is not registered" })
|
||||
})
|
||||
|
||||
test('should check fastify dependency graph - decorate', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.decorate('plugin1', fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'plugin1-name'
|
||||
}))
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'test',
|
||||
decorators: { fastify: ['plugin1', 'plugin2'] }
|
||||
}))
|
||||
|
||||
await t.assert.rejects(fastify.ready(), { message: "The decorator 'plugin2' required by 'test' is not present in Fastify" })
|
||||
})
|
||||
|
||||
test('should check fastify dependency graph - decorateReply', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.decorateReply('plugin1', fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'plugin1-name'
|
||||
}))
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'test',
|
||||
decorators: { reply: ['plugin1', 'plugin2'] }
|
||||
}))
|
||||
|
||||
await t.assert.rejects(fastify.ready(), { message: "The decorator 'plugin2' required by 'test' is not present in Reply" })
|
||||
})
|
||||
|
||||
test('should accept an option to encapsulate', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(fp((fastify, _opts, next) => {
|
||||
fastify.decorate('accessible', true)
|
||||
next()
|
||||
}, {
|
||||
name: 'accessible-plugin'
|
||||
}))
|
||||
|
||||
fastify.register(fp((fastify, _opts, next) => {
|
||||
fastify.decorate('alsoAccessible', true)
|
||||
next()
|
||||
}, {
|
||||
name: 'accessible-plugin2',
|
||||
encapsulate: false
|
||||
}))
|
||||
|
||||
fastify.register(fp((fastify, _opts, next) => {
|
||||
fastify.decorate('encapsulated', true)
|
||||
next()
|
||||
}, {
|
||||
name: 'encapsulated-plugin',
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
t.assert.ok(fastify.hasDecorator('accessible'))
|
||||
t.assert.ok(fastify.hasDecorator('alsoAccessible'))
|
||||
t.assert.ok(!fastify.hasDecorator('encapsulated'))
|
||||
})
|
||||
|
||||
test('should check dependencies when encapsulated', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
name: 'test',
|
||||
dependencies: ['missing-dependency-name'],
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
await t.assert.rejects(fastify.ready(), { message: "The dependency 'missing-dependency-name' of plugin 'test' is not registered" })
|
||||
})
|
||||
|
||||
test(
|
||||
'should check version when encapsulated',
|
||||
{ skip: /\d-.+/.test(pkg.devDependencies.fastify) },
|
||||
async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
name: 'test',
|
||||
fastify: '<=2.10.0',
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
await t.assert.rejects(fastify.ready(), { message: /fastify-plugin: test - expected '<=2.10.0' fastify version, '\d.\d+.\d+' is installed/ })
|
||||
}
|
||||
)
|
||||
|
||||
test('should check decorators when encapsulated', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.decorate('plugin1', 'foo')
|
||||
|
||||
fastify.register(fp((_fastify, _opts, next) => next(), {
|
||||
fastify: '5.x',
|
||||
name: 'test',
|
||||
encapsulate: true,
|
||||
decorators: { fastify: ['plugin1', 'plugin2'] }
|
||||
}))
|
||||
|
||||
await t.assert.rejects(fastify.ready(), { message: "The decorator 'plugin2' required by 'test' is not present in Fastify" })
|
||||
})
|
||||
|
||||
test('plugin name when encapsulated', async (t) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(function plugin (_instance, _opts, next) {
|
||||
next()
|
||||
})
|
||||
|
||||
fastify.register(fp(getFn('hello'), {
|
||||
fastify: '5.x',
|
||||
name: 'hello',
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
fastify.register(function plugin (fastify, _opts, next) {
|
||||
fastify.register(fp(getFn('deep'), {
|
||||
fastify: '5.x',
|
||||
name: 'deep',
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
fastify.register(fp(function genericPlugin (fastify, _opts, next) {
|
||||
t.assert.strictEqual(fastify.pluginName, 'deep-deep', 'should be deep-deep')
|
||||
|
||||
fastify.register(fp(getFn('deep-deep-deep'), {
|
||||
fastify: '5.x',
|
||||
name: 'deep-deep-deep',
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
fastify.register(fp(getFn('deep-deep -> not-encapsulated-2'), {
|
||||
fastify: '5.x',
|
||||
name: 'not-encapsulated-2'
|
||||
}))
|
||||
|
||||
next()
|
||||
}, {
|
||||
fastify: '5.x',
|
||||
name: 'deep-deep',
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
fastify.register(fp(getFn('plugin -> not-encapsulated'), {
|
||||
fastify: '5.x',
|
||||
name: 'not-encapsulated'
|
||||
}))
|
||||
|
||||
next()
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
function getFn (expectedName) {
|
||||
return function genericPlugin (fastify, _opts, next) {
|
||||
t.assert.strictEqual(fastify.pluginName, expectedName, `should be ${expectedName}`)
|
||||
next()
|
||||
}
|
||||
}
|
||||
})
|
||||
24
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/toCamelCase.test.js
generated
vendored
Normal file
24
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/test/toCamelCase.test.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const toCamelCase = require('../lib/toCamelCase')
|
||||
|
||||
test('from kebab-case to camelCase', (t) => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(toCamelCase('hello-world'), 'helloWorld')
|
||||
})
|
||||
|
||||
test('from @-prefixed named imports', (t) => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(toCamelCase('@hello/world'), 'helloWorld')
|
||||
})
|
||||
|
||||
test('from @-prefixed named kebab-case to camelCase', (t) => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(toCamelCase('@hello/my-world'), 'helloMyWorld')
|
||||
})
|
||||
|
||||
test('from kebab-case to camelCase multiple words', (t) => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(toCamelCase('hello-long-world'), 'helloLongWorld')
|
||||
})
|
||||
19
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/example-async.test-d.ts
generated
vendored
Normal file
19
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/example-async.test-d.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { FastifyPluginAsync } from 'fastify'
|
||||
|
||||
type FastifyExampleAsync = FastifyPluginAsync<fastifyExampleAsync.FastifyExampleAsyncOptions>
|
||||
|
||||
declare namespace fastifyExampleAsync {
|
||||
|
||||
export interface FastifyExampleAsyncOptions {
|
||||
foo?: 'bar'
|
||||
}
|
||||
|
||||
export interface FastifyExampleAsyncPluginOptions extends FastifyExampleAsyncOptions {
|
||||
}
|
||||
export const fastifyExampleAsync: FastifyExampleAsync
|
||||
export { fastifyExampleAsync as default }
|
||||
}
|
||||
|
||||
declare function fastifyExampleAsync (...params: Parameters<FastifyExampleAsync>): ReturnType<FastifyExampleAsync>
|
||||
|
||||
export default fastifyExampleAsync
|
||||
19
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/example-callback.test-d.ts
generated
vendored
Normal file
19
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/example-callback.test-d.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { FastifyPluginCallback } from 'fastify'
|
||||
|
||||
type FastifyExampleCallback = FastifyPluginCallback<fastifyExampleCallback.FastifyExampleCallbackOptions>
|
||||
|
||||
declare namespace fastifyExampleCallback {
|
||||
|
||||
export interface FastifyExampleCallbackOptions {
|
||||
foo?: 'bar'
|
||||
}
|
||||
|
||||
export interface FastifyExampleCallbackPluginOptions extends FastifyExampleCallbackOptions {
|
||||
}
|
||||
export const fastifyExampleCallback: FastifyExampleCallback
|
||||
export { fastifyExampleCallback as default }
|
||||
}
|
||||
|
||||
declare function fastifyExampleCallback (...params: Parameters<FastifyExampleCallback>): ReturnType<FastifyExampleCallback>
|
||||
|
||||
export default fastifyExampleCallback
|
||||
61
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/plugin.d.ts
generated
vendored
Normal file
61
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/// <reference types="fastify" />
|
||||
|
||||
import {
|
||||
FastifyPluginCallback,
|
||||
FastifyPluginAsync,
|
||||
FastifyPluginOptions,
|
||||
RawServerBase,
|
||||
RawServerDefault,
|
||||
FastifyTypeProvider,
|
||||
FastifyTypeProviderDefault,
|
||||
FastifyBaseLogger,
|
||||
} from 'fastify'
|
||||
|
||||
type FastifyPlugin = typeof fastifyPlugin
|
||||
|
||||
declare namespace fastifyPlugin {
|
||||
export interface PluginMetadata {
|
||||
/** Bare-minimum version of Fastify for your plugin, just add the semver range that you need. */
|
||||
fastify?: string,
|
||||
name?: string,
|
||||
/** Decorator dependencies for this plugin */
|
||||
decorators?: {
|
||||
fastify?: (string | symbol)[],
|
||||
reply?: (string | symbol)[],
|
||||
request?: (string | symbol)[]
|
||||
},
|
||||
/** The plugin dependencies */
|
||||
dependencies?: string[],
|
||||
encapsulate?: boolean
|
||||
}
|
||||
// Exporting PluginOptions for backward compatibility after renaming it to PluginMetadata
|
||||
/**
|
||||
* @deprecated Use PluginMetadata instead
|
||||
*/
|
||||
export interface PluginOptions extends PluginMetadata {}
|
||||
|
||||
export const fastifyPlugin: FastifyPlugin
|
||||
export { fastifyPlugin as default }
|
||||
}
|
||||
|
||||
/**
|
||||
* This function does three things for you:
|
||||
* 1. Add the `skip-override` hidden property
|
||||
* 2. Check bare-minimum version of Fastify
|
||||
* 3. Pass some custom metadata of the plugin to Fastify
|
||||
* @param fn Fastify plugin function
|
||||
* @param options Optional plugin options
|
||||
*/
|
||||
|
||||
declare function fastifyPlugin<
|
||||
Options extends FastifyPluginOptions = Record<never, never>,
|
||||
RawServer extends RawServerBase = RawServerDefault,
|
||||
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
|
||||
Logger extends FastifyBaseLogger = FastifyBaseLogger,
|
||||
Fn extends FastifyPluginCallback<Options, RawServer, TypeProvider, Logger> | FastifyPluginAsync<Options, RawServer, TypeProvider, Logger> = FastifyPluginCallback<Options, RawServer, TypeProvider, Logger>
|
||||
> (
|
||||
fn: Fn extends unknown ? Fn extends (...args: any) => Promise<any> ? FastifyPluginAsync<Options, RawServer, TypeProvider, Logger> : FastifyPluginCallback<Options, RawServer, TypeProvider, Logger> : Fn,
|
||||
options?: fastifyPlugin.PluginMetadata | string
|
||||
): Fn
|
||||
|
||||
export = fastifyPlugin
|
||||
166
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/plugin.test-d.ts
generated
vendored
Normal file
166
backend/node_modules/@fastify/helmet/node_modules/fastify-plugin/types/plugin.test-d.ts
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
import fastifyPlugin from '..'
|
||||
import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify'
|
||||
import { expectAssignable, expectError, expectNotType, expectType } from 'tsd'
|
||||
import { Server } from 'node:https'
|
||||
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
|
||||
import fastifyExampleCallback from './example-callback.test-d'
|
||||
import fastifyExampleAsync from './example-async.test-d'
|
||||
|
||||
interface Options {
|
||||
foo: string
|
||||
}
|
||||
|
||||
const testSymbol = Symbol('foobar')
|
||||
|
||||
// Callback
|
||||
|
||||
const pluginCallback: FastifyPluginCallback = (_fastify, _options, _next) => { }
|
||||
expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback))
|
||||
|
||||
const pluginCallbackWithTypes = (_fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void): void => { }
|
||||
expectAssignable<FastifyPluginCallback>(fastifyPlugin(pluginCallbackWithTypes))
|
||||
expectNotType<any>(fastifyPlugin(pluginCallbackWithTypes))
|
||||
|
||||
expectAssignable<FastifyPluginCallback>(fastifyPlugin((_fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void): void => { }))
|
||||
expectNotType<any>(fastifyPlugin((_fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void): void => { }))
|
||||
|
||||
expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback, ''))
|
||||
expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback, {
|
||||
fastify: '',
|
||||
name: '',
|
||||
decorators: {
|
||||
fastify: ['', testSymbol],
|
||||
reply: ['', testSymbol],
|
||||
request: ['', testSymbol]
|
||||
},
|
||||
dependencies: [''],
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
const pluginCallbackWithOptions: FastifyPluginCallback<Options> = (_fastify, options, _next) => {
|
||||
expectType<string>(options.foo)
|
||||
}
|
||||
|
||||
expectType<FastifyPluginCallback<Options>>(fastifyPlugin(pluginCallbackWithOptions))
|
||||
|
||||
const pluginCallbackWithServer: FastifyPluginCallback<Options, Server> = (fastify, _options, _next) => {
|
||||
expectType<Server>(fastify.server)
|
||||
}
|
||||
|
||||
expectType<FastifyPluginCallback<Options, Server>>(fastifyPlugin(pluginCallbackWithServer))
|
||||
|
||||
const pluginCallbackWithTypeProvider: FastifyPluginCallback<Options, Server, TypeBoxTypeProvider> = (_fastify, _options, _next) => { }
|
||||
|
||||
expectType<FastifyPluginCallback<Options, Server, TypeBoxTypeProvider>>(fastifyPlugin(pluginCallbackWithTypeProvider))
|
||||
|
||||
// Async
|
||||
|
||||
const pluginAsync: FastifyPluginAsync = async (_fastify, _options) => { }
|
||||
expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync))
|
||||
|
||||
const pluginAsyncWithTypes = async (_fastify: FastifyInstance, _options: FastifyPluginOptions): Promise<void> => { }
|
||||
expectType<FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault>>(fastifyPlugin(pluginAsyncWithTypes))
|
||||
|
||||
expectType<FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault>>(fastifyPlugin(async (_fastify: FastifyInstance, _options: FastifyPluginOptions): Promise<void> => { }))
|
||||
expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync, ''))
|
||||
expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync, {
|
||||
fastify: '',
|
||||
name: '',
|
||||
decorators: {
|
||||
fastify: ['', testSymbol],
|
||||
reply: ['', testSymbol],
|
||||
request: ['', testSymbol]
|
||||
},
|
||||
dependencies: [''],
|
||||
encapsulate: true
|
||||
}))
|
||||
|
||||
const pluginAsyncWithOptions: FastifyPluginAsync<Options> = async (_fastify, options) => {
|
||||
expectType<string>(options.foo)
|
||||
}
|
||||
|
||||
expectType<FastifyPluginAsync<Options>>(fastifyPlugin(pluginAsyncWithOptions))
|
||||
|
||||
const pluginAsyncWithServer: FastifyPluginAsync<Options, Server> = async (fastify, _options) => {
|
||||
expectType<Server>(fastify.server)
|
||||
}
|
||||
|
||||
expectType<FastifyPluginAsync<Options, Server>>(fastifyPlugin(pluginAsyncWithServer))
|
||||
|
||||
const pluginAsyncWithTypeProvider: FastifyPluginAsync<Options, Server, TypeBoxTypeProvider> = async (_fastify, _options) => { }
|
||||
|
||||
expectType<FastifyPluginAsync<Options, Server, TypeBoxTypeProvider>>(fastifyPlugin(pluginAsyncWithTypeProvider))
|
||||
|
||||
// Fastify register
|
||||
|
||||
const server = fastify()
|
||||
server.register(fastifyPlugin(pluginCallback))
|
||||
server.register(fastifyPlugin(pluginCallbackWithTypes), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginCallbackWithOptions), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginCallbackWithServer), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginCallbackWithTypeProvider), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginAsync))
|
||||
server.register(fastifyPlugin(pluginAsyncWithTypes), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginAsyncWithOptions), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginAsyncWithServer), { foo: 'bar' })
|
||||
server.register(fastifyPlugin(pluginAsyncWithTypeProvider), { foo: 'bar' })
|
||||
|
||||
// properly handling callback and async
|
||||
fastifyPlugin(function (fastify, options, next) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Record<never, never>>(options)
|
||||
expectType<(err?: Error) => void>(next)
|
||||
})
|
||||
|
||||
fastifyPlugin<Options>(function (fastify, options, next) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Options>(options)
|
||||
expectType<(err?: Error) => void>(next)
|
||||
})
|
||||
|
||||
fastifyPlugin<Options>(async function (fastify, options) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Options>(options)
|
||||
})
|
||||
|
||||
expectAssignable<FastifyPluginAsync<Options, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>>(fastifyPlugin(async function (_fastify: FastifyInstance, _options: Options) { }))
|
||||
expectNotType<any>(fastifyPlugin(async function (_fastify: FastifyInstance, _options: Options) { }))
|
||||
|
||||
fastifyPlugin(async function (fastify, options: Options) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Options>(options)
|
||||
})
|
||||
|
||||
fastifyPlugin(async function (fastify, options) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Record<never, never>>(options)
|
||||
})
|
||||
|
||||
expectError(
|
||||
fastifyPlugin(async function (fastify, options: Options, _next) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Options>(options)
|
||||
})
|
||||
)
|
||||
expectAssignable<FastifyPluginCallback<Options>>(fastifyPlugin(function (_fastify, _options, _next) { }))
|
||||
expectNotType<any>(fastifyPlugin(function (_fastify, _options, _next) { }))
|
||||
|
||||
fastifyPlugin(function (fastify, options: Options, next) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Options>(options)
|
||||
expectType<(err?: Error) => void>(next)
|
||||
})
|
||||
|
||||
expectError(
|
||||
fastifyPlugin(function (fastify, options: Options, _next) {
|
||||
expectType<FastifyInstance>(fastify)
|
||||
expectType<Options>(options)
|
||||
return Promise.resolve()
|
||||
})
|
||||
)
|
||||
|
||||
server.register(fastifyExampleCallback, { foo: 'bar' })
|
||||
expectError(server.register(fastifyExampleCallback, { foo: 'baz' }))
|
||||
|
||||
server.register(fastifyExampleAsync, { foo: 'bar' })
|
||||
expectError(server.register(fastifyExampleAsync, { foo: 'baz' }))
|
||||
82
backend/node_modules/@fastify/helmet/package.json
generated
vendored
Normal file
82
backend/node_modules/@fastify/helmet/package.json
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "@fastify/helmet",
|
||||
"version": "13.0.2",
|
||||
"description": "Important security headers for Fastify",
|
||||
"main": "index.js",
|
||||
"type": "commonjs",
|
||||
"types": "types/index.d.ts",
|
||||
"scripts": {
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix",
|
||||
"test": "npm run test:unit && npm run test:typescript",
|
||||
"test:typescript": "tsd",
|
||||
"test:unit": "c8 --100 node --test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/fastify-helmet.git"
|
||||
},
|
||||
"keywords": [
|
||||
"fastify",
|
||||
"helmet",
|
||||
"security",
|
||||
"headers",
|
||||
"x-frame-options",
|
||||
"csp",
|
||||
"hsts",
|
||||
"clickjack"
|
||||
],
|
||||
"author": "Matteo Collina <hello@matteocollina.com>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Tomas Della Vedova",
|
||||
"url": "http://delved.org"
|
||||
},
|
||||
{
|
||||
"name": "Manuel Spigolon",
|
||||
"email": "behemoth89@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Maksim Sinik",
|
||||
"url": "https://maksim.dev"
|
||||
},
|
||||
{
|
||||
"name": "Frazer Smith",
|
||||
"email": "frazer.dev@icloud.com",
|
||||
"url": "https://github.com/fdawgs"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/fastify/fastify-helmet/issues"
|
||||
},
|
||||
"homepage": "https://github.com/fastify/fastify-helmet#readme",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.3.0",
|
||||
"c8": "^10.1.2",
|
||||
"eslint": "^9.17.0",
|
||||
"fastify": "^5.0.0",
|
||||
"neostandard": "^0.12.0",
|
||||
"tsd": "^0.33.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastify-plugin": "^5.0.0",
|
||||
"helmet": "^8.0.0"
|
||||
},
|
||||
"tsd": {
|
||||
"directory": "test/types"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
1028
backend/node_modules/@fastify/helmet/test/global.test.js
generated
vendored
Normal file
1028
backend/node_modules/@fastify/helmet/test/global.test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
499
backend/node_modules/@fastify/helmet/test/routes.test.js
generated
vendored
Normal file
499
backend/node_modules/@fastify/helmet/test/routes.test.js
generated
vendored
Normal file
@@ -0,0 +1,499 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('fastify')
|
||||
const helmet = require('..')
|
||||
|
||||
test('It should apply route specific helmet options over the global options', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(helmet, { global: true })
|
||||
|
||||
fastify.get('/', { helmet: { frameguard: false } }, (_request, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/'
|
||||
})
|
||||
|
||||
const notExpected = {
|
||||
'x-frame-options': 'SAMEORIGIN'
|
||||
}
|
||||
|
||||
const expected = {
|
||||
'x-dns-prefetch-control': 'off',
|
||||
'x-download-options': 'noopen',
|
||||
'x-content-type-options': 'nosniff',
|
||||
'x-xss-protection': '0'
|
||||
}
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
|
||||
t.assert.notDeepStrictEqual(
|
||||
response.headers['x-frame-options'],
|
||||
notExpected['x-frame-options']
|
||||
)
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, expected)
|
||||
})
|
||||
|
||||
test('It should disable helmet on specific route when route `helmet` option is set to `false`', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(helmet, { global: true })
|
||||
|
||||
fastify.get('/disabled', { helmet: false }, (_request, reply) => {
|
||||
reply.send({ hello: 'disabled' })
|
||||
})
|
||||
|
||||
fastify.get('/enabled', (_request, reply) => {
|
||||
reply.send({ hello: 'enabled' })
|
||||
})
|
||||
|
||||
const helmetHeaders = {
|
||||
'x-frame-options': 'SAMEORIGIN',
|
||||
'x-dns-prefetch-control': 'off',
|
||||
'x-download-options': 'noopen',
|
||||
'x-content-type-options': 'nosniff',
|
||||
'x-xss-protection': '0'
|
||||
}
|
||||
|
||||
await fastify
|
||||
.inject({
|
||||
method: 'GET',
|
||||
path: '/disabled'
|
||||
})
|
||||
.then((response) => {
|
||||
const actualResponseHeaders = {
|
||||
'x-frame-options': response.headers['x-frame-options'],
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
|
||||
t.assert.notDeepStrictEqual(actualResponseHeaders, helmetHeaders)
|
||||
})
|
||||
.catch((err) => {
|
||||
t.assert.fail(err)
|
||||
})
|
||||
|
||||
await fastify
|
||||
.inject({
|
||||
method: 'GET',
|
||||
path: '/enabled'
|
||||
})
|
||||
.then((response) => {
|
||||
const actualResponseHeaders = {
|
||||
'x-frame-options': response.headers['x-frame-options'],
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, helmetHeaders)
|
||||
})
|
||||
.catch((err) => {
|
||||
t.assert.fail(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('It should add CSPNonce decorator and hooks when route `enableCSPNonces` option is set to `true`', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.register(helmet, {
|
||||
global: false,
|
||||
enableCSPNonces: false,
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
'script-src': ["'self'", "'unsafe-eval'", "'unsafe-inline'"],
|
||||
'style-src': ["'self'", "'unsafe-inline'"]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get(
|
||||
'/',
|
||||
{
|
||||
helmet: {
|
||||
enableCSPNonces: true
|
||||
}
|
||||
},
|
||||
(_request, reply) => {
|
||||
t.assert.ok(reply.cspNonce)
|
||||
reply.send(reply.cspNonce)
|
||||
}
|
||||
)
|
||||
|
||||
const response = await fastify.inject({ method: 'GET', path: '/' })
|
||||
const cspCache = response.json()
|
||||
|
||||
const expected = {
|
||||
'content-security-policy': `script-src 'self' 'unsafe-eval' 'unsafe-inline' 'nonce-${cspCache.script}';style-src 'self' 'unsafe-inline' 'nonce-${cspCache.style}';default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src-attr 'none';upgrade-insecure-requests`
|
||||
}
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'content-security-policy': response.headers['content-security-policy']
|
||||
}
|
||||
t.assert.ok(cspCache.script)
|
||||
t.assert.ok(cspCache.style)
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, expected)
|
||||
})
|
||||
|
||||
test('It should add CSPNonce decorator and hooks with default options when route `enableCSPNonces` option is set to `true`', async (t) => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.register(helmet, {
|
||||
global: false,
|
||||
enableCSPNonces: false
|
||||
})
|
||||
|
||||
fastify.get('/no-csp', (_request, reply) => {
|
||||
t.assert.equal(reply.cspNonce, null)
|
||||
reply.send({ message: 'no csp' })
|
||||
})
|
||||
|
||||
fastify.get(
|
||||
'/with-csp',
|
||||
{
|
||||
helmet: {
|
||||
enableCSPNonces: true
|
||||
}
|
||||
},
|
||||
(_request, reply) => {
|
||||
t.assert.ok(reply.cspNonce)
|
||||
reply.send(reply.cspNonce)
|
||||
}
|
||||
)
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/no-csp'
|
||||
})
|
||||
|
||||
let response
|
||||
|
||||
response = await fastify.inject({ method: 'GET', path: '/with-csp' })
|
||||
const cspCache = response.json()
|
||||
t.assert.ok(cspCache.script)
|
||||
t.assert.ok(cspCache.style)
|
||||
|
||||
response = await fastify.inject({ method: 'GET', path: '/with-csp' })
|
||||
const newCsp = response.json()
|
||||
t.assert.notEqual(cspCache, newCsp)
|
||||
t.assert.ok(cspCache.script)
|
||||
t.assert.ok(cspCache.style)
|
||||
})
|
||||
|
||||
test('It should not add CSPNonce decorator when route `enableCSPNonces` option is set to `false`', async (t) => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.register(helmet, {
|
||||
global: true,
|
||||
enableCSPNonces: true
|
||||
})
|
||||
|
||||
fastify.get('/with-csp', (_request, reply) => {
|
||||
t.assert.ok(reply.cspNonce)
|
||||
reply.send(reply.cspNonce)
|
||||
})
|
||||
|
||||
fastify.get(
|
||||
'/no-csp',
|
||||
{ helmet: { enableCSPNonces: false } },
|
||||
(_request, reply) => {
|
||||
t.assert.equal(reply.cspNonce, null)
|
||||
reply.send({ message: 'no csp' })
|
||||
}
|
||||
)
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/no-csp'
|
||||
})
|
||||
|
||||
let response
|
||||
|
||||
response = await fastify.inject({ method: 'GET', path: '/with-csp' })
|
||||
const cspCache = response.json()
|
||||
t.assert.ok(cspCache.script)
|
||||
t.assert.ok(cspCache.style)
|
||||
|
||||
response = await fastify.inject({ method: 'GET', path: '/with-csp' })
|
||||
const newCsp = response.json()
|
||||
t.assert.notEqual(cspCache, newCsp)
|
||||
t.assert.ok(cspCache.script)
|
||||
t.assert.ok(cspCache.style)
|
||||
})
|
||||
|
||||
test('It should not set default directives when route useDefaults is set to `false`', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.register(helmet, {
|
||||
global: false,
|
||||
enableCSPNonces: false,
|
||||
contentSecurityPolicy: {
|
||||
directives: {}
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get(
|
||||
'/',
|
||||
{
|
||||
helmet: {
|
||||
contentSecurityPolicy: {
|
||||
useDefaults: false,
|
||||
directives: {
|
||||
'default-src': ["'self'"],
|
||||
'script-src': ["'self'", "'unsafe-eval'", "'unsafe-inline'"],
|
||||
'style-src': ["'self'", "'unsafe-inline'"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
(_request, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
)
|
||||
|
||||
const response = await fastify.inject({ method: 'GET', path: '/' })
|
||||
|
||||
const expected = {
|
||||
'content-security-policy':
|
||||
"default-src 'self';script-src 'self' 'unsafe-eval' 'unsafe-inline';style-src 'self' 'unsafe-inline'"
|
||||
}
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'content-security-policy': response.headers['content-security-policy']
|
||||
}
|
||||
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, expected)
|
||||
})
|
||||
|
||||
test('It should not set `content-security-policy` header, if route contentSecurityPolicy is false', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.register(helmet, {
|
||||
global: false,
|
||||
enableCSPNonces: false,
|
||||
contentSecurityPolicy: {
|
||||
directives: {}
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get(
|
||||
'/',
|
||||
{
|
||||
helmet: {
|
||||
contentSecurityPolicy: false
|
||||
}
|
||||
},
|
||||
(_request, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
)
|
||||
|
||||
const response = await fastify.inject({ method: 'GET', path: '/' })
|
||||
|
||||
const expected = {
|
||||
'content-security-policy': undefined
|
||||
}
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'content-security-policy': response.headers['content-security-policy']
|
||||
}
|
||||
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, expected)
|
||||
})
|
||||
|
||||
test('It should be able to conditionally apply the middlewares through the `helmet` reply decorator', async (t) => {
|
||||
t.plan(10)
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(helmet, { global: false })
|
||||
|
||||
fastify.get('/:condition', async (request, reply) => {
|
||||
const { condition } = request.params
|
||||
|
||||
t.assert.ok(reply.helmet)
|
||||
t.assert.notEqual(reply.helmet, null)
|
||||
|
||||
if (condition !== 'frameguard') {
|
||||
await reply.helmet({ frameguard: false })
|
||||
} else {
|
||||
await reply.helmet({ frameguard: true })
|
||||
}
|
||||
return { message: 'ok' }
|
||||
})
|
||||
|
||||
const expected = {
|
||||
'x-dns-prefetch-control': 'off',
|
||||
'x-download-options': 'noopen',
|
||||
'x-content-type-options': 'nosniff',
|
||||
'x-xss-protection': '0'
|
||||
}
|
||||
|
||||
const maybeExpected = {
|
||||
'x-frame-options': 'SAMEORIGIN'
|
||||
}
|
||||
|
||||
{
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/no-frameguard'
|
||||
})
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
|
||||
t.assert.equal(response.statusCode, 200)
|
||||
t.assert.notDeepStrictEqual(
|
||||
response.headers['x-frame-options'],
|
||||
maybeExpected['x-frame-options']
|
||||
)
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, expected)
|
||||
}
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/frameguard'
|
||||
})
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
|
||||
t.assert.equal(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(
|
||||
response.headers['x-frame-options'],
|
||||
maybeExpected['x-frame-options']
|
||||
)
|
||||
t.assert.deepStrictEqual(actualResponseHeaders, expected)
|
||||
})
|
||||
|
||||
test('It should throw an error when route specific helmet options are of an invalid type', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(helmet)
|
||||
|
||||
try {
|
||||
fastify.get('/', { helmet: 'invalid_options' }, () => {
|
||||
return { message: 'ok' }
|
||||
})
|
||||
} catch (error) {
|
||||
t.assert.ok(error)
|
||||
t.assert.equal(
|
||||
error.message,
|
||||
'Unknown value for route helmet configuration'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
test('It should forward `helmet` reply decorator and route specific errors to `fastify-helmet`', async (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(helmet, { global: false })
|
||||
|
||||
fastify.get('/helmet-reply-decorator-error', async (_request, reply) => {
|
||||
await reply.helmet({
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'", () => 'bad;value']
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return { message: 'ok' }
|
||||
})
|
||||
|
||||
fastify.get(
|
||||
'/helmet-route-configuration-error',
|
||||
{
|
||||
helmet: {
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'", () => 'bad;value']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
async () => {
|
||||
return { message: 'ok' }
|
||||
}
|
||||
)
|
||||
|
||||
const notExpected = {
|
||||
'x-dns-prefetch-control': 'off',
|
||||
'x-frame-options': 'SAMEORIGIN',
|
||||
'x-download-options': 'noopen',
|
||||
'x-content-type-options': 'nosniff',
|
||||
'x-xss-protection': '0'
|
||||
}
|
||||
|
||||
{
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/helmet-reply-decorator-error'
|
||||
})
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
|
||||
t.assert.equal(response.statusCode, 500)
|
||||
t.assert.equal(
|
||||
JSON.parse(response.payload).message,
|
||||
'Content-Security-Policy received an invalid directive value for "default-src"'
|
||||
)
|
||||
t.assert.notDeepStrictEqual(actualResponseHeaders, notExpected)
|
||||
}
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/helmet-route-configuration-error'
|
||||
})
|
||||
|
||||
const actualResponseHeaders = {
|
||||
'x-dns-prefetch-control': response.headers['x-dns-prefetch-control'],
|
||||
'x-download-options': response.headers['x-download-options'],
|
||||
'x-content-type-options': response.headers['x-content-type-options'],
|
||||
'x-xss-protection': response.headers['x-xss-protection']
|
||||
}
|
||||
|
||||
t.assert.equal(response.statusCode, 500)
|
||||
t.assert.equal(
|
||||
JSON.parse(response.payload).message,
|
||||
'Content-Security-Policy received an invalid directive value for "default-src"'
|
||||
)
|
||||
t.assert.notDeepStrictEqual(actualResponseHeaders, notExpected)
|
||||
})
|
||||
41
backend/node_modules/@fastify/helmet/types/index.d.ts
generated
vendored
Normal file
41
backend/node_modules/@fastify/helmet/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { FastifyPluginAsync, RawServerBase, RawServerDefault } from 'fastify'
|
||||
import helmet, { contentSecurityPolicy, HelmetOptions } from 'helmet'
|
||||
|
||||
declare module 'fastify' {
|
||||
export interface RouteShorthandOptions<
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
RawServer extends RawServerBase = RawServerDefault
|
||||
> extends fastifyHelmet.FastifyHelmetRouteOptions { }
|
||||
|
||||
interface FastifyReply {
|
||||
cspNonce: {
|
||||
script: string;
|
||||
style: string;
|
||||
},
|
||||
helmet: (opts?: HelmetOptions) => typeof helmet
|
||||
}
|
||||
|
||||
export interface RouteOptions extends fastifyHelmet.FastifyHelmetRouteOptions { }
|
||||
}
|
||||
|
||||
type FastifyHelmet = FastifyPluginAsync<fastifyHelmet.FastifyHelmetOptions> & {
|
||||
contentSecurityPolicy: typeof contentSecurityPolicy;
|
||||
}
|
||||
|
||||
declare namespace fastifyHelmet {
|
||||
|
||||
export interface FastifyHelmetRouteOptions {
|
||||
helmet?: Omit<FastifyHelmetOptions, 'global'> | false;
|
||||
}
|
||||
|
||||
export type FastifyHelmetOptions = {
|
||||
enableCSPNonces?: boolean,
|
||||
global?: boolean;
|
||||
} & NonNullable<HelmetOptions>
|
||||
|
||||
export const fastifyHelmet: FastifyHelmet
|
||||
export { fastifyHelmet as default }
|
||||
}
|
||||
|
||||
declare function fastifyHelmet (...params: Parameters<FastifyHelmet>): ReturnType<FastifyHelmet>
|
||||
export = fastifyHelmet
|
||||
184
backend/node_modules/@fastify/helmet/types/index.test-d.ts
generated
vendored
Normal file
184
backend/node_modules/@fastify/helmet/types/index.test-d.ts
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
import fastify, { FastifyPluginAsync } from 'fastify'
|
||||
import helmet from 'helmet'
|
||||
import { expectAssignable, expectError, expectType } from 'tsd'
|
||||
import fastifyHelmet, { FastifyHelmetOptions, FastifyHelmetRouteOptions } from '..'
|
||||
|
||||
// Plugin registered with no options
|
||||
const appOne = fastify()
|
||||
appOne.register(fastifyHelmet)
|
||||
|
||||
// Plugin registered with an empty object option
|
||||
const appTwo = fastify()
|
||||
expectAssignable<FastifyHelmetOptions>({})
|
||||
appTwo.register(fastifyHelmet, {})
|
||||
|
||||
// Plugin registered with all helmet middlewares disabled
|
||||
const appThree = fastify()
|
||||
const helmetOptions = {
|
||||
contentSecurityPolicy: false,
|
||||
dnsPrefetchControl: false,
|
||||
frameguard: false,
|
||||
hidePoweredBy: false,
|
||||
hsts: false,
|
||||
ieNoOpen: false,
|
||||
noSniff: false,
|
||||
permittedCrossDomainPolicies: false,
|
||||
referrerPolicy: false,
|
||||
xssFilter: false
|
||||
}
|
||||
expectAssignable<FastifyHelmetOptions>(helmetOptions)
|
||||
appThree.register(fastifyHelmet, helmetOptions)
|
||||
|
||||
// Plugin registered with helmet middlewares custom settings
|
||||
const appFour = fastify()
|
||||
appFour.register(fastifyHelmet, {
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
'directive-1': ['foo', 'bar']
|
||||
},
|
||||
reportOnly: true,
|
||||
useDefaults: false
|
||||
},
|
||||
dnsPrefetchControl: {
|
||||
allow: true
|
||||
},
|
||||
frameguard: {
|
||||
action: 'deny'
|
||||
},
|
||||
hsts: {
|
||||
maxAge: 1,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
},
|
||||
permittedCrossDomainPolicies: {
|
||||
permittedPolicies: 'master-only'
|
||||
},
|
||||
referrerPolicy: {
|
||||
policy: 'no-referrer'
|
||||
}
|
||||
// these options are false or never
|
||||
// hidePoweredBy: false
|
||||
// ieNoOpen: false,
|
||||
// noSniff: false,
|
||||
// xssFilter: false
|
||||
})
|
||||
|
||||
// Plugin registered with `enableCSPNonces` option and helmet default CSP settings
|
||||
const appFive = fastify()
|
||||
appFive.register(fastifyHelmet, { enableCSPNonces: true })
|
||||
|
||||
appFive.get('/', function (_request, reply) {
|
||||
expectType<{
|
||||
script: string;
|
||||
style: string;
|
||||
}>(reply.cspNonce)
|
||||
})
|
||||
|
||||
// Plugin registered with `enableCSPNonces` option and custom CSP settings
|
||||
const appSix = fastify()
|
||||
appSix.register(fastifyHelmet, {
|
||||
enableCSPNonces: true,
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
'directive-1': ['foo', 'bar']
|
||||
},
|
||||
reportOnly: true
|
||||
}
|
||||
})
|
||||
|
||||
appSix.get('/', function (_request, reply) {
|
||||
expectType<{
|
||||
script: string;
|
||||
style: string;
|
||||
}>(reply.cspNonce)
|
||||
})
|
||||
|
||||
const csp = fastifyHelmet.contentSecurityPolicy
|
||||
expectType<typeof helmet.contentSecurityPolicy>(csp)
|
||||
|
||||
// Plugin registered with `global` set to `true`
|
||||
const appSeven = fastify()
|
||||
appSeven.register(fastifyHelmet, { global: true })
|
||||
|
||||
appSeven.get('/route-with-disabled-helmet', { helmet: false }, function (_request, reply) {
|
||||
expectType<typeof helmet>(reply.helmet())
|
||||
})
|
||||
|
||||
expectError(
|
||||
appSeven.get('/route-with-disabled-helmet', {
|
||||
helmet: 'trigger a typescript error'
|
||||
}, function (_request, reply) {
|
||||
expectType<typeof helmet>(reply.helmet())
|
||||
})
|
||||
)
|
||||
|
||||
// Plugin registered with `global` set to `false`
|
||||
const appEight = fastify()
|
||||
appEight.register(fastifyHelmet, { global: false })
|
||||
|
||||
appEight.get('/disabled-helmet', function (_request, reply) {
|
||||
expectType<typeof helmet>(reply.helmet(helmetOptions))
|
||||
})
|
||||
|
||||
const routeHelmetOptions = {
|
||||
helmet: {
|
||||
enableCSPNonces: true,
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
'directive-1': ['foo', 'bar']
|
||||
},
|
||||
reportOnly: true
|
||||
},
|
||||
dnsPrefetchControl: {
|
||||
allow: true
|
||||
},
|
||||
frameguard: {
|
||||
action: 'deny' as const
|
||||
},
|
||||
hsts: {
|
||||
maxAge: 1,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
},
|
||||
permittedCrossDomainPolicies: {
|
||||
permittedPolicies: 'all' as const
|
||||
},
|
||||
referrerPolicy: {
|
||||
policy: 'no-referrer' as const
|
||||
}
|
||||
}
|
||||
}
|
||||
expectAssignable<FastifyHelmetRouteOptions>(routeHelmetOptions)
|
||||
|
||||
appEight.get('/enabled-helmet', routeHelmetOptions, function (_request, reply) {
|
||||
expectType<typeof helmet>(reply.helmet())
|
||||
expectType<{
|
||||
script: string;
|
||||
style: string;
|
||||
}>(reply.cspNonce)
|
||||
})
|
||||
|
||||
appEight.get('/enable-framegard', {
|
||||
helmet: { frameguard: true }
|
||||
}, function (_request, reply) {
|
||||
expectType<typeof helmet>(reply.helmet())
|
||||
expectType<{
|
||||
script: string;
|
||||
style: string;
|
||||
}>(reply.cspNonce)
|
||||
})
|
||||
|
||||
// Plugin registered with an invalid helmet option
|
||||
const appThatTriggerAnError = fastify()
|
||||
expectError(
|
||||
appThatTriggerAnError.register(fastifyHelmet, {
|
||||
thisOptionDoesNotExist: 'trigger a typescript error'
|
||||
})
|
||||
)
|
||||
|
||||
// fastify-helmet instance is using the FastifyHelmetOptions options
|
||||
expectType<
|
||||
FastifyPluginAsync<FastifyHelmetOptions> & {
|
||||
contentSecurityPolicy: typeof helmet.contentSecurityPolicy;
|
||||
}
|
||||
>(fastifyHelmet)
|
||||
Reference in New Issue
Block a user