Skip to content

Commit

Permalink
further docs update
Browse files Browse the repository at this point in the history
  • Loading branch information
vejja committed Apr 21, 2024
1 parent 4819a5b commit f141124
Show file tree
Hide file tree
Showing 6 changed files with 3,800 additions and 3,152 deletions.
137 changes: 95 additions & 42 deletions docs/content/1.documentation/1.getting-started/3.usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Nuxt Security by default registers a set of **global** Nuxt `routeRules` that wi

## Global configuration

To override default behavior for Nuxt Security globally, follow this pattern:
To override the default behavior for Nuxt Security globally, follow this pattern:

```ts
```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
security: {
headers: {
Expand All @@ -36,7 +36,7 @@ export default defineNuxtConfig({

To enable per-route configuration, use the `routeRules` like following:

```ts
```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/custom-route': {
Expand Down Expand Up @@ -74,11 +74,96 @@ If your application defines conflicting headers at both levels, the `security` p

For more information on `routeRules` please see the [Nuxt documentation](https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering)

## Nested route configuration

Nuxt Security will recursively resolve nested routes using your `routeRules` definitions:
## Runtime hooks

If you need to change the configuration at runtime, it is possible to do it through the `nuxt-security:routeRules` hook.

```ts
In order to use the runtime hooks feature, you will need to create a Nitro plugin.

In the `server/plugins` directory, create a new file with the name of your choice:

```ts{}[server/plugins/filename.ts]
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => {
// You can fetch configuration data asynchronously from an external source
const validDomain = await $fetch('https://some-site.com/rules')
// You can then override the security options of any route
routeRules['/some/route'] = {
headers: {
contentSecurityPolicy: {
"connect-src": ["'self'", validDomain]
},
xFrameOptions: false
},
hidePoweredBy: false
}
})
})
```

## Configuration priority order

Nuxt-Security applies your rules in the following prority order:


1. Default rules

Nuxt-Security default values.
See [here](/documentation/getting-started/configuration#default)


2. Inline module options

```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
modules: [
['nuxt-security', { /* Inline Options */ }]
]
})
```


3. Global module options

```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
security: {
// Global Options
}
})
```

4. Per-route options

```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/some-route': {
security: {
// Per-route Options
}
}
}
})
```

5. Runtime-hook options

```ts{}[server/plugins/filename.ts]
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', routeRules => {
// Runtime Options
})
})
```


## Route merging strategy (nested router)

If you define nested route rules in your `routeRules` definitions, Nuxt Security will recursively merge the options to resolve the security rules of a given route:

```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
// Global
security: {
Expand Down Expand Up @@ -146,7 +231,7 @@ experimental: {

To disable certain middleware or headers, follow this pattern:

```ts
```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
// global
security: {
Expand All @@ -170,45 +255,13 @@ export default defineNuxtConfig({
})
```

## Runtime hooks

If you need to change the configuration at runtime, it is possible to do it through `nuxt-security:routeRules` hook.

### Usage

In order to use the runtime hooks feature, you will need to create a Nitro plugin.

In the `server/plugins` directory, create a new file.
You can give it any name of your choice, e.g. `my-runtime-security-config.ts`:

```ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => {
// You can fetch configuration data asynchronously from an external source
const validDomain = await $fetch('https://some-site.com/rules')
// You can then override the security options of any route
routeRules['/some/route'] = {
headers: {
contentSecurityPolicy: {
"connect-src": ["'self'", validDomain]
},
xFrameOptions: false
},
hidePoweredBy: false
}
})
})
```

Consistent with the Nuxt router rules, your new route configuration will be merged recursively with higher-level existing security route rules.

## Overwriting or modifying existing values

### Overwriting or modifying existing values

If you don't want to overwrite existing rules with your runtime hook, you can modify existing values.
Within your runtime hooks, you can either overwrite or modify the existing values for any security option.
One of the easiest way to merge existing rules with your own is to use `defu`:

```ts
```ts{}[server/plugins/filename.ts]
import defu from 'defu'
export default defineNitroPlugin((nitroApp) => {
Expand Down
17 changes: 3 additions & 14 deletions docs/content/1.documentation/2.headers/1.csp.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,6 @@ contentSecurityPolicy: {
} | false
```

::callout
#summary
Array and String syntaxes
#content
Directives can be written using the array syntax or the string syntax.

- Array syntax for clear definition of policies: `"script-src": ["'self'", "https:", "'unsafe-inline'"]`
- String syntax if you prefer to stick with native MDN syntax: `"script-src": "'self' https: 'unsafe-inline'"`

Please note that these two syntaxes behave differently for deeply nested route definitions: see [Per-route Configuration](#per-route-configuration)
::

::callout
#summary
CSPSourceValue type
Expand Down Expand Up @@ -342,8 +330,9 @@ Note that this is not necessary if you use our default configuration settings.

## Per-route configuration

All Content Security Policy options can be defined on a per-route level.
Nuxt Security resolves the `contentSecurityPolicy` options substitutively at each nested level.
All Content Security Policy options can be defined on a per-route level.

As examplified below, Nuxt Security resolves the `contentSecurityPolicy` options substitutively at each nested level.

```ts
export default defineNuxtConfig({
Expand Down
29 changes: 7 additions & 22 deletions docs/content/1.documentation/2.headers/2.permissions-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,12 @@ type PermissionsPolicyValue = {
::
::callout
#summary
Array and String syntaxes
#content
Directives can be written using the array syntax or the string syntax.
- Array syntax for clear definition of policies: `"geolocation": ["self", "https://a.example.com", "https://b.example.com"]`
- String syntax if you prefer to stick with native MDN syntax: `"geolocation": '(self "https://a.example.com" "https://b.example.com")'`
Please note that these two syntaxes behave differently for deeply nested route definitions: see [Per-route Configuration](#per-route-configuration)
::
## Per-route configuration
All Permissions Policy options can be defined on a per-route level.
As examplified below, rules are merged recursively when resolved :
```ts
export default defineNuxtConfig({
// Global
Expand All @@ -148,17 +139,17 @@ export default defineNuxtConfig({
'/some-prefix/some-route/**': {
security: {
headers: {
permissionsPolicy: { // With array syntax : additive
'geolocation': ['https://*.example.com'] // Self AND *.example.com allowed for routes beginning with /some-prefix/some-route/
permissionsPolicy: {
'geolocation': ['self', 'https://*.example.com'] // Self AND *.example.com allowed for routes beginning with /some-prefix/some-route/
}
}
}
},
'/some-prefix/some-route/some-page': {
security: {
headers: {
contentSecurityPolicy: { // With string syntax : substitutive
'geolocation': 'self' // ONLY self allowed on /some-prefix/some-route/some-page
contentSecurityPolicy: {
'geolocation': ['self'] // ONLY self allowed on /some-prefix/some-route/some-page
}
}
}
Expand All @@ -167,9 +158,3 @@ export default defineNuxtConfig({
})
```

Nuxt Security resolves the `permissionsPolicy` options using the native Nitro router strategy:
- **Additive merging** with the array syntax: If you write your rules with the array syntax (e.g. `"geolocation": ["self"]`), the new route policies will be added to the policies defined for higher-level routes.
Use this strategy if you need to add specific policy values to your route without deleting the existing ones.

- **Substitutive merging** with the string syntax: If you write your rules with the string syntax (e.g. `"geolocation": "self"`), the new route policies will be substituted to the policies defined for higher-level routes.
Use this strategy if you need to delete existing policies before setting your specific route policies.
4 changes: 4 additions & 0 deletions docs/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export default defineNuxtConfig({
extends: '@nuxt-themes/docus',
modules: ['@nuxtjs/plausible', '@nuxtlabs/github-module'],
experimental: {
// Need this otherwise vue-server-renderer not found
externalVue: false
},

github: {
owner: 'Baroshem',
Expand Down
9 changes: 5 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
},
"devDependencies": {
"@nuxt-themes/docus": "^1.14.7",
"@nuxtjs/plausible": "^1.0.0",
"@nuxtlabs/github-module": "^1.6.3",
"@nuxtjs/plausible": "^0.2.1",
"nuxt": "^3.8.0"
"nuxt": "^3.11.2"
},
"resolutions": {
"string-width": "4.2.3"
}
"pinceau": "0.15.4",
"mdast-util-gfm-table": "2.0.0"
}
}
Loading

0 comments on commit f141124

Please sign in to comment.