vite-plugin-csp
Version:
Create CSP meta tags and header configs from all sources in the final Vite html
232 lines (180 loc) • 11.5 kB
Markdown
# CSP (Content-Security-Policy) Vite Plugin
<!-- cspell: disable bracketsstartstop -->
[](https://github.com/josh-hemphill/vite-plugin-csp/releases)
[](https://npmjs.org/package/vite-plugin-csp)
[](https://codecov.io/gh/josh-hemphill/vite-plugin-csp)
[](https://libraries.io/npm/vite-plugin-csp)
[](https://openbase.io/js/vite-plugin-csp?utm_source=embedded&utm_medium=badge&utm_campaign=rate-badge)
[](https://github.com/josh-hemphill/vite-plugin-csp/actions/workflows/test.yml)
[](https://github.com/josh-hemphill/vite-plugin-csp/actions/workflows/release.yml)
Leverages [csp-typed-directives](https://github.com/josh-hemphill/csp-typed-directives) to create typed CSP `<meta>` policies and validated interdependant headers.
e.g. the CSP, CSP Report-Only, Report-To, and Referrer-Policy headers.
Mostly config compatible with [csp-html-webpack-plugin](https://github.com/slackhq/csp-html-webpack-plugin)
## WARNING, STILL EARLY AND THINGS LIKE MODULE RESOLUTION ARE FINICKY
### Now looking at making a multi-repo because this is going to require multiple layers of shared functionality and also built to an unplugin
## Installation
Install the plugin with npm:
```shell
$ npm install --save-dev vite-plugin-csp
# Or shorthand
npm i -D vite-plugin-csp
```
## Known issues
- Relative modules are resolved relative to the CWD, not the file
- no SSR support (and thus no nonce support)
- No parsing of JS embeded sources (since that would require framework specific plugins)
- Only `script` and `style` related directives are supported (except for the inclusion of `report-to` for generating headers)
## Under construction :)
<!--
## Zero Config Usage
Add your base logo as `logo.png` file to your assets folder.
Add the plugin to your vite config as follows:
```javascript
const ViteCspPlugin = require('vite-plugin-csp')
// or ESM
import { ViteCspPlugin } from "module";
plugins: [
ViteCspPlugin()
]
```
## Basic Usage <!-- [<svg alt="codesandbox" xmlns="http://www.w3.org/2000/svg" width="16" height="18"><path d="M7.219 15.877V9.394l-5.73-3.208v3.696l2.624 1.48v2.78l3.106 1.735zm1.488.038l3.163-1.773v-2.845l2.642-1.49V6.16l-5.805 3.26v6.496zm5.041-11l-3.05-1.72-2.68 1.512L5.32 3.193 2.241 4.937l5.744 3.215 5.763-3.237zM0 13.513V4.53L8 0l8 4.511V13.5l-8.001 4.484L0 13.513z" fill="currentColor"/></svg>](https://codesandbox.io/s/vite-plugin-csp-demo-uh195?file=/webpack.config.js) -->
<!--
Add the plugin to your vite config as follows:
```javascript
const ViteCspPlugin = require('vite-plugin-csp')
// or ESM
import { ViteCspPlugin } from "module";
...
plugins: [
ViteCspPlugin('/path/to/logo.png') // svg works too!
]
```
The default configuration will automatically generate webapp manifest files along with
[44 different icon formats](https://github.com/josh-hemphill/vite-plugin-csp/tree/master/test/fixtures/expected/default)
as appropriate for iOS devices, Android devices, Windows Phone and various desktop browsers out of your single `logo.png`.
> **Tip:** You might want to [fine tune](#advanced-usage) what vendors to support.
### A Note on Path Resolution
Under the hood, Vite/Rollup resolve the paths to the logo and favicons according to the following
rules:
* If `/path/to/logo` is absolute, there is nothing to resolve and the path
specified is used as is.
* If `./path/to/logo` is relative, it's resolved with respect to `process.cwd()`.
### HTML Injection
In combination with [Vite's html plugin hooks](https://vitejs.dev/guide/api-plugin.html#transformindexhtml) it will also inject the necessary html for you:
```html
<link rel="apple-touch-icon" sizes="57x57" href="/assets/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/assets/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/assets/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/assets/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/assets/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/assets/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/assets/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/assets/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="167x167" href="/assets/apple-touch-icon-167x167.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon-180x180.png">
<link rel="apple-touch-icon" sizes="1024x1024" href="/assets/apple-touch-icon-1024x1024.png">
<link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 1)" href="/assets/apple-touch-startup-image-320x460.png">
<link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)" href="/assets/apple-touch-startup-image-640x920.png">
<link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" href="/assets/apple-touch-startup-image-640x1096.png">
<link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" href="/assets/apple-touch-startup-image-750x1294.png">
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 3)" href="/assets/apple-touch-startup-image-1182x2208.png">
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 3)" href="/assets/apple-touch-startup-image-1242x2148.png">
<link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 1)" href="/assets/apple-touch-startup-image-748x1024.png">
<link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)" href="/assets/apple-touch-startup-image-1496x2048.png">
<link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 1)" href="/assets/apple-touch-startup-image-768x1004.png">
<link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)" href="/assets/apple-touch-startup-image-1536x2008.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="228x228" href="/assets/coast-228x228.png">
<link rel="manifest" href="/assets/manifest.json">
<link rel="shortcut icon" href="/assets/favicon.ico">
<link rel="yandex-tableau-widget" href="/assets/yandex-browser-manifest.json">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title">
<meta name="application-name">
<meta name="mobile-web-app-capable" content="yes">
<meta name="msapplication-TileColor" content="#fff">
<meta name="msapplication-TileImage" content="/assets/mstile-144x144.png">
<meta name="msapplication-config" content="/assets/browserconfig.xml">
<meta name="theme-color" content="#fff">
```
## Advanced Usage
```javascript
plugins: [
ViteCspPlugin({
/** Your source logo (Will default to ) */
logo?: "assets/logo.png",
/** Inject html links/metadata. */
inject?: true,
/** `Favicons` configuration options
* - [See `favicons` documentation](https://github.com/itgalaxy/favicons) */
favicons?: FaviconsConfig,
/** The root of the project from which you want to load metadata */
projectRoot?: process.cwd(),
/** prefix is delegated to Rollup/Vite (keeping for people migrating from Webpack)
* @deprecated */
prefix?: string,
/** Caching is delegated to Rollup/Vite (keeping for people migrating from Webpack)
* @deprecated */
cache?: boolean,
/** Public Path is delegated to Rollup/Vite (keeping for people migrating from Webpack)
* @deprecated */
publicPath?: string,
/** Output Path is delegated to Rollup/Vite (keeping for people migrating from Webpack)
* @deprecated */
outputPath?: string,
})
]
```
To fine tune what icons/metadata is generated, refer to
[favicons' documentation](https://github.com/haydenbleasel/favicons#usage).
The options specified under `favicons:` are handed over as is to [favicons],
except that if `appName`, `appDescription`, `version`, `developerName` or
`developerURL` are left `undefined`, they will be automatically inferred
respectively from `name`, `description`, `version`, `author.name` and
`author.url` as defined in the nearest `package.json` if available.
And if there's no `author` it will use the first in the `contributors`.
To disable automatically retrieving metadata from `package.json`, simply set
to `null` the properties you want to omit.
### Examples
#### Basic
```javascript
const ViteCspPlugin = require('vite-plugin-csp')
// or ESM
import { ViteCspPlugin } from "module";
plugins: [
ViteCspPlugin({
logo: './src/logo.png', // svg works too!
favicons: {
appName: 'my-app',
appDescription: 'My awesome App',
developerName: 'Me',
developerURL: null, // prevent retrieving from the nearest package.json
background: '#ddd',
theme_color: '#333',
icons: {
coast: false,
yandex: false
}
}
})
]
```
To fine tune what icons/metadata is generated, refer to
[favicons' documentation](https://github.com/haydenbleasel/favicons#usage).
#### Handling Multiple HTML Files
Vite calls the HTML transform hook for each HTML file template file you have configured in Vite, so this works automatically.
## Changelog
Take a look at the [CHANGELOG.md](https://github.com/josh-hemphill/vite-plugin-csp/tree/latest/CHANGELOG.md).
## Contribution
You're free to contribute to this project by submitting [issues](https://github.com/josh-hemphill/vite-plugin-csp/issues) and/or [pull requests](https://github.com/josh-hemphill/vite-plugin-csp/pulls).
Please keep in mind that every change and feature should be covered by
tests.
## License
This project is licensed under [MIT](https://github.com/josh-hemphill/vite-plugin-csp/blob/latest/LICENSE).
[favicons]: https://github.com/haydenbleasel/favicons
## Contributors
-->
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- ALL-CONTRIBUTORS-LIST:END -->