@magicdima/vite-plugin-csp 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +33 -0
- package/dist/index.js +70 -0
- package/package.json +7 -5
- package/src/index.ts +0 -121
- package/tsconfig.json +0 -15
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Plugin, ResolvedConfig } from "vite";
|
|
2
|
+
export type CSPDirectiveValue = string | string[];
|
|
3
|
+
export interface CSPDirectives {
|
|
4
|
+
"default-src"?: CSPDirectiveValue;
|
|
5
|
+
"script-src"?: CSPDirectiveValue;
|
|
6
|
+
"style-src"?: CSPDirectiveValue;
|
|
7
|
+
"img-src"?: CSPDirectiveValue;
|
|
8
|
+
"font-src"?: CSPDirectiveValue;
|
|
9
|
+
"connect-src"?: CSPDirectiveValue;
|
|
10
|
+
"media-src"?: CSPDirectiveValue;
|
|
11
|
+
"object-src"?: CSPDirectiveValue;
|
|
12
|
+
"frame-src"?: CSPDirectiveValue;
|
|
13
|
+
"worker-src"?: CSPDirectiveValue;
|
|
14
|
+
"manifest-src"?: CSPDirectiveValue;
|
|
15
|
+
"form-action"?: CSPDirectiveValue;
|
|
16
|
+
}
|
|
17
|
+
export interface CSPPluginOptions {
|
|
18
|
+
/**
|
|
19
|
+
* CSP directives to apply. Can be an object or a function that receives the Vite config.
|
|
20
|
+
*/
|
|
21
|
+
directives?: CSPDirectives | ((config: ResolvedConfig) => CSPDirectives);
|
|
22
|
+
/**
|
|
23
|
+
* Whether to include CSP
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Additional CSP policy string to append
|
|
29
|
+
*/
|
|
30
|
+
policy?: string;
|
|
31
|
+
}
|
|
32
|
+
declare function cspPlugin(options?: CSPPluginOptions): Plugin;
|
|
33
|
+
export default cspPlugin;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const defaultDirectives = {
|
|
4
|
+
"default-src": "'self'",
|
|
5
|
+
"script-src": ["'self'"],
|
|
6
|
+
"style-src": ["'self'"],
|
|
7
|
+
"img-src": ["'self'", "data:"],
|
|
8
|
+
"font-src": "'self'",
|
|
9
|
+
"connect-src": "'self'",
|
|
10
|
+
"media-src": "'self'",
|
|
11
|
+
"object-src": "'none'",
|
|
12
|
+
"frame-src": "'none'",
|
|
13
|
+
"worker-src": "'self'",
|
|
14
|
+
"manifest-src": "'self'",
|
|
15
|
+
"form-action": "'self'",
|
|
16
|
+
};
|
|
17
|
+
function buildCSPHeader(directives) {
|
|
18
|
+
const policies = [];
|
|
19
|
+
for (const [directive, value] of Object.entries(directives)) {
|
|
20
|
+
if (value === true) {
|
|
21
|
+
policies.push(directive);
|
|
22
|
+
}
|
|
23
|
+
else if (value === false) {
|
|
24
|
+
// Skip false values
|
|
25
|
+
}
|
|
26
|
+
else if (typeof value === "string") {
|
|
27
|
+
policies.push(`${directive} ${value}`);
|
|
28
|
+
}
|
|
29
|
+
else if (Array.isArray(value)) {
|
|
30
|
+
policies.push(`${directive} ${value.join(" ")}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return policies.join("; ");
|
|
34
|
+
}
|
|
35
|
+
function cspPlugin(options = {}) {
|
|
36
|
+
const { directives = {}, enabled: includeCsp = true, policy: additionalPolicy, } = options;
|
|
37
|
+
let resolvedDirectives;
|
|
38
|
+
return {
|
|
39
|
+
name: "vite-csp-plugin",
|
|
40
|
+
configResolved(resolvedConfig) {
|
|
41
|
+
// Resolve directives (either function or object)
|
|
42
|
+
const userDirectives = typeof directives === "function"
|
|
43
|
+
? directives(resolvedConfig)
|
|
44
|
+
: directives;
|
|
45
|
+
// Merge default directives with user directives
|
|
46
|
+
resolvedDirectives = { ...defaultDirectives, ...userDirectives };
|
|
47
|
+
},
|
|
48
|
+
// configureServer(server) {
|
|
49
|
+
// if (includeDev) {
|
|
50
|
+
// const cspPolicy = buildCSPHeader(resolvedDirectives) +
|
|
51
|
+
// (additionalPolicy ? `; ${additionalPolicy}` : '')
|
|
52
|
+
// server.middlewares.use((_req, res, next) => {
|
|
53
|
+
// res.setHeader('Content-Security-Policy', cspPolicy)
|
|
54
|
+
// next()
|
|
55
|
+
// })
|
|
56
|
+
// }
|
|
57
|
+
// },
|
|
58
|
+
transformIndexHtml(html) {
|
|
59
|
+
if (!includeCsp) {
|
|
60
|
+
return html;
|
|
61
|
+
}
|
|
62
|
+
const cspPolicy = buildCSPHeader(resolvedDirectives) +
|
|
63
|
+
(additionalPolicy ? `; ${additionalPolicy}` : "");
|
|
64
|
+
const cspMetaTag = `<meta http-equiv="Content-Security-Policy" content="${cspPolicy}" />`;
|
|
65
|
+
// Insert the CSP meta tag at the beginning of the head
|
|
66
|
+
return html.replace(/<head>/, `<head>\n ${cspMetaTag}`);
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
exports.default = cspPlugin;
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magicdima/vite-plugin-csp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
6
11
|
"scripts": {
|
|
7
12
|
"build": "tsc"
|
|
8
13
|
},
|
|
9
|
-
"exports": {
|
|
10
|
-
".": "./dist/index.js"
|
|
11
|
-
},
|
|
12
14
|
"peerDependencies": {
|
|
13
15
|
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
14
16
|
},
|
package/src/index.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import type { Plugin, ResolvedConfig } from "vite";
|
|
2
|
-
|
|
3
|
-
export type CSPDirectiveValue = string | string[];
|
|
4
|
-
|
|
5
|
-
export interface CSPDirectives {
|
|
6
|
-
"default-src"?: CSPDirectiveValue;
|
|
7
|
-
"script-src"?: CSPDirectiveValue;
|
|
8
|
-
"style-src"?: CSPDirectiveValue;
|
|
9
|
-
"img-src"?: CSPDirectiveValue;
|
|
10
|
-
"font-src"?: CSPDirectiveValue;
|
|
11
|
-
"connect-src"?: CSPDirectiveValue;
|
|
12
|
-
"media-src"?: CSPDirectiveValue;
|
|
13
|
-
"object-src"?: CSPDirectiveValue;
|
|
14
|
-
"frame-src"?: CSPDirectiveValue;
|
|
15
|
-
"worker-src"?: CSPDirectiveValue;
|
|
16
|
-
"manifest-src"?: CSPDirectiveValue;
|
|
17
|
-
"form-action"?: CSPDirectiveValue;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface CSPPluginOptions {
|
|
21
|
-
/**
|
|
22
|
-
* CSP directives to apply. Can be an object or a function that receives the Vite config.
|
|
23
|
-
*/
|
|
24
|
-
directives?: CSPDirectives | ((config: ResolvedConfig) => CSPDirectives);
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Whether to include CSP
|
|
28
|
-
* @default true
|
|
29
|
-
*/
|
|
30
|
-
enabled?: boolean;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Additional CSP policy string to append
|
|
34
|
-
*/
|
|
35
|
-
policy?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const defaultDirectives: CSPDirectives = {
|
|
39
|
-
"default-src": "'self'",
|
|
40
|
-
"script-src": ["'self'"],
|
|
41
|
-
"style-src": ["'self'"],
|
|
42
|
-
"img-src": ["'self'", "data:"],
|
|
43
|
-
"font-src": "'self'",
|
|
44
|
-
"connect-src": "'self'",
|
|
45
|
-
"media-src": "'self'",
|
|
46
|
-
"object-src": "'none'",
|
|
47
|
-
"frame-src": "'none'",
|
|
48
|
-
"worker-src": "'self'",
|
|
49
|
-
"manifest-src": "'self'",
|
|
50
|
-
"form-action": "'self'",
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
function buildCSPHeader(directives: CSPDirectives): string {
|
|
54
|
-
const policies: string[] = [];
|
|
55
|
-
|
|
56
|
-
for (const [directive, value] of Object.entries(directives)) {
|
|
57
|
-
if (value === true) {
|
|
58
|
-
policies.push(directive);
|
|
59
|
-
} else if (value === false) {
|
|
60
|
-
// Skip false values
|
|
61
|
-
} else if (typeof value === "string") {
|
|
62
|
-
policies.push(`${directive} ${value}`);
|
|
63
|
-
} else if (Array.isArray(value)) {
|
|
64
|
-
policies.push(`${directive} ${value.join(" ")}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return policies.join("; ");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function cspPlugin(options: CSPPluginOptions = {}): Plugin {
|
|
72
|
-
const {
|
|
73
|
-
directives = {},
|
|
74
|
-
enabled: includeCsp = true,
|
|
75
|
-
policy: additionalPolicy,
|
|
76
|
-
} = options;
|
|
77
|
-
|
|
78
|
-
let resolvedDirectives: CSPDirectives;
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
name: "vite-csp-plugin",
|
|
82
|
-
configResolved(resolvedConfig) {
|
|
83
|
-
// Resolve directives (either function or object)
|
|
84
|
-
const userDirectives =
|
|
85
|
-
typeof directives === "function"
|
|
86
|
-
? directives(resolvedConfig)
|
|
87
|
-
: directives;
|
|
88
|
-
|
|
89
|
-
// Merge default directives with user directives
|
|
90
|
-
resolvedDirectives = { ...defaultDirectives, ...userDirectives };
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
// configureServer(server) {
|
|
94
|
-
// if (includeDev) {
|
|
95
|
-
// const cspPolicy = buildCSPHeader(resolvedDirectives) +
|
|
96
|
-
// (additionalPolicy ? `; ${additionalPolicy}` : '')
|
|
97
|
-
// server.middlewares.use((_req, res, next) => {
|
|
98
|
-
// res.setHeader('Content-Security-Policy', cspPolicy)
|
|
99
|
-
// next()
|
|
100
|
-
// })
|
|
101
|
-
// }
|
|
102
|
-
// },
|
|
103
|
-
|
|
104
|
-
transformIndexHtml(html) {
|
|
105
|
-
if (!includeCsp) {
|
|
106
|
-
return html;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const cspPolicy =
|
|
110
|
-
buildCSPHeader(resolvedDirectives) +
|
|
111
|
-
(additionalPolicy ? `; ${additionalPolicy}` : "");
|
|
112
|
-
|
|
113
|
-
const cspMetaTag = `<meta http-equiv="Content-Security-Policy" content="${cspPolicy}" />`;
|
|
114
|
-
|
|
115
|
-
// Insert the CSP meta tag at the beginning of the head
|
|
116
|
-
return html.replace(/<head>/, `<head>\n ${cspMetaTag}`);
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export default cspPlugin;
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"outDir": "dist",
|
|
4
|
-
"incremental": false,
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"module": "NodeNext",
|
|
7
|
-
"moduleResolution": "nodenext",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"skipDefaultLibCheck": true,
|
|
10
|
-
"strictNullChecks": true, /* viem */
|
|
11
|
-
"types": []
|
|
12
|
-
},
|
|
13
|
-
"include": ["src"],
|
|
14
|
-
"exclude": ["node_modules", "dist"]
|
|
15
|
-
}
|