@nosecone/sveltekit 1.0.0-alpha.30 → 1.0.0-alpha.32

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.
Files changed (4) hide show
  1. package/index.d.ts +71 -2
  2. package/index.js +11 -8
  3. package/package.json +8 -9
  4. package/index.ts +0 -119
package/index.d.ts CHANGED
@@ -1,7 +1,76 @@
1
- import nosecone, { defaults } from "nosecone";
1
+ import nosecone from "nosecone";
2
2
  import type { CspDirectives, NoseconeOptions } from "nosecone";
3
3
  import type { Handle, KitConfig } from "@sveltejs/kit";
4
- export { defaults };
4
+ export declare const defaults: {
5
+ readonly directives: {
6
+ readonly scriptSrc: readonly ["'strict-dynamic'"];
7
+ readonly baseUri: readonly ["'none'"];
8
+ readonly childSrc: readonly ["'none'"];
9
+ readonly connectSrc: readonly ["'self'"];
10
+ readonly defaultSrc: readonly ["'self'"];
11
+ readonly fontSrc: readonly ["'self'"];
12
+ readonly formAction: readonly ["'self'"];
13
+ readonly frameAncestors: readonly ["'none'"];
14
+ readonly frameSrc: readonly ["'none'"];
15
+ readonly imgSrc: readonly ["'self'", "blob:", "data:"];
16
+ readonly manifestSrc: readonly ["'self'"];
17
+ readonly mediaSrc: readonly ["'self'"];
18
+ readonly objectSrc: readonly ["'none'"];
19
+ readonly styleSrc: readonly ["'self'"];
20
+ readonly workerSrc: readonly ["'self'"];
21
+ readonly upgradeInsecureRequests: true;
22
+ };
23
+ readonly contentSecurityPolicy: {
24
+ readonly directives: {
25
+ readonly baseUri: readonly ["'none'"];
26
+ readonly childSrc: readonly ["'none'"];
27
+ readonly connectSrc: readonly ["'self'"];
28
+ readonly defaultSrc: readonly ["'self'"];
29
+ readonly fontSrc: readonly ["'self'"];
30
+ readonly formAction: readonly ["'self'"];
31
+ readonly frameAncestors: readonly ["'none'"];
32
+ readonly frameSrc: readonly ["'none'"];
33
+ readonly imgSrc: readonly ["'self'", "blob:", "data:"];
34
+ readonly manifestSrc: readonly ["'self'"];
35
+ readonly mediaSrc: readonly ["'self'"];
36
+ readonly objectSrc: readonly ["'none'"];
37
+ readonly scriptSrc: readonly ["'self'"];
38
+ readonly styleSrc: readonly ["'self'"];
39
+ readonly workerSrc: readonly ["'self'"];
40
+ readonly upgradeInsecureRequests: true;
41
+ };
42
+ };
43
+ readonly crossOriginEmbedderPolicy: {
44
+ readonly policy: "require-corp";
45
+ };
46
+ readonly crossOriginOpenerPolicy: {
47
+ readonly policy: "same-origin";
48
+ };
49
+ readonly crossOriginResourcePolicy: {
50
+ readonly policy: "same-origin";
51
+ };
52
+ readonly originAgentCluster: true;
53
+ readonly referrerPolicy: {
54
+ readonly policy: readonly ["no-referrer"];
55
+ };
56
+ readonly strictTransportSecurity: {
57
+ readonly maxAge: number;
58
+ readonly includeSubDomains: true;
59
+ readonly preload: false;
60
+ };
61
+ readonly xContentTypeOptions: true;
62
+ readonly xDnsPrefetchControl: {
63
+ readonly allow: false;
64
+ };
65
+ readonly xDownloadOptions: true;
66
+ readonly xFrameOptions: {
67
+ readonly action: "sameorigin";
68
+ };
69
+ readonly xPermittedCrossDomainPolicies: {
70
+ readonly permittedPolicies: "none";
71
+ };
72
+ readonly xXssProtection: true;
73
+ };
5
74
  export default nosecone;
6
75
  /**
7
76
  * Create a SvelteKit hook that sets secure headers on every request.
package/index.js CHANGED
@@ -1,6 +1,13 @@
1
- import nosecone, { defaults, CONTENT_SECURITY_POLICY_DIRECTIVES, NoseconeValidationError, QUOTED } from 'nosecone';
2
- export { default, defaults } from 'nosecone';
1
+ import nosecone, { defaults as defaults$1, CONTENT_SECURITY_POLICY_DIRECTIVES, NoseconeValidationError, QUOTED } from 'nosecone';
2
+ export { default } from 'nosecone';
3
3
 
4
+ const defaults = {
5
+ ...defaults$1,
6
+ directives: {
7
+ ...defaults$1.contentSecurityPolicy.directives,
8
+ scriptSrc: ["'strict-dynamic'"],
9
+ },
10
+ };
4
11
  /**
5
12
  * Create a SvelteKit hook that sets secure headers on every request.
6
13
  *
@@ -21,10 +28,6 @@ function createHook(options = defaults) {
21
28
  return response;
22
29
  };
23
30
  }
24
- const directives = {
25
- ...defaults.contentSecurityPolicy.directives,
26
- scriptSrc: ["'strict-dynamic'"],
27
- };
28
31
  function unquote(value) {
29
32
  for (const [unquoted, quoted] of QUOTED) {
30
33
  if (value === quoted) {
@@ -70,11 +73,11 @@ function directivesToSvelteKitConfig(directives) {
70
73
  }
71
74
  return sveltekitDirectives;
72
75
  }
73
- function csp(options = { mode: "auto", directives }) {
76
+ function csp(options = { mode: "auto" }) {
74
77
  return {
75
78
  mode: options.mode ? options.mode : "auto",
76
79
  directives: directivesToSvelteKitConfig(options.directives ?? defaults.contentSecurityPolicy.directives),
77
80
  };
78
81
  }
79
82
 
80
- export { createHook, csp };
83
+ export { createHook, csp, defaults };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nosecone/sveltekit",
3
- "version": "1.0.0-alpha.30",
3
+ "version": "1.0.0-alpha.32",
4
4
  "description": "Protect your SvelteKit application with secure headers",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://arcjet.com",
@@ -29,7 +29,6 @@
29
29
  "README.md",
30
30
  "*.js",
31
31
  "*.d.ts",
32
- "*.ts",
33
32
  "!*.config.js"
34
33
  ],
35
34
  "scripts": {
@@ -40,19 +39,19 @@
40
39
  "test": "node --test"
41
40
  },
42
41
  "dependencies": {
43
- "nosecone": "1.0.0-alpha.30"
42
+ "nosecone": "1.0.0-alpha.32"
44
43
  },
45
44
  "peerDependencies": {
46
45
  "@sveltejs/kit": ">=2"
47
46
  },
48
47
  "devDependencies": {
49
- "@arcjet/eslint-config": "1.0.0-alpha.30",
50
- "@arcjet/rollup-config": "1.0.0-alpha.30",
51
- "@arcjet/tsconfig": "1.0.0-alpha.30",
52
- "@rollup/wasm-node": "4.27.3",
53
- "@sveltejs/kit": "^2.8.0",
48
+ "@arcjet/eslint-config": "1.0.0-alpha.32",
49
+ "@arcjet/rollup-config": "1.0.0-alpha.32",
50
+ "@arcjet/tsconfig": "1.0.0-alpha.32",
51
+ "@rollup/wasm-node": "4.27.4",
52
+ "@sveltejs/kit": "^2.8.4",
54
53
  "@types/node": "18.18.0",
55
- "typescript": "5.6.3"
54
+ "typescript": "5.7.2"
56
55
  },
57
56
  "publishConfig": {
58
57
  "access": "public",
package/index.ts DELETED
@@ -1,119 +0,0 @@
1
- import nosecone, {
2
- CONTENT_SECURITY_POLICY_DIRECTIVES,
3
- QUOTED,
4
- defaults,
5
- NoseconeValidationError,
6
- } from "nosecone";
7
- import type { CspDirectives, NoseconeOptions } from "nosecone";
8
- import type { Handle, KitConfig } from "@sveltejs/kit";
9
-
10
- // Re-exports the defaults for easier overrides
11
- export { defaults };
12
-
13
- // We export `nosecone` as the default so it can be used with `new Response()`
14
- export default nosecone;
15
-
16
- /**
17
- * Create a SvelteKit hook that sets secure headers on every request.
18
- *
19
- * @param options: Configuration to provide to Nosecone
20
- * @returns A SvelteKit hook that sets secure headers
21
- */
22
- export function createHook(options: NoseconeOptions = defaults): Handle {
23
- return async ({ event, resolve }) => {
24
- const response = await resolve(event);
25
-
26
- const headers = nosecone(options);
27
- for (const [headerName, headerValue] of Object.entries(headers)) {
28
- // Only add headers that aren't already set. For example, SvelteKit will
29
- // likely have added `Content-Security-Policy` if configured with `csp`
30
- if (!response.headers.has(headerName)) {
31
- response.headers.set(headerName, headerValue);
32
- }
33
- }
34
-
35
- return response;
36
- };
37
- }
38
-
39
- type SvelteKitCsp = Exclude<KitConfig["csp"], undefined>;
40
-
41
- export type ContentSecurityPolicyConfig = {
42
- mode?: SvelteKitCsp["mode"];
43
- directives?: CspDirectives;
44
- // TODO: Support `reportOnly`
45
- };
46
-
47
- const directives: CspDirectives = {
48
- ...defaults.contentSecurityPolicy.directives,
49
- scriptSrc: ["'strict-dynamic'"],
50
- };
51
-
52
- function unquote(value?: string) {
53
- for (const [unquoted, quoted] of QUOTED) {
54
- if (value === quoted) {
55
- return unquoted;
56
- }
57
- }
58
-
59
- return value;
60
- }
61
-
62
- function resolveValue(v: (() => string) | string) {
63
- if (typeof v === "function") {
64
- return v();
65
- } else {
66
- return v;
67
- }
68
- }
69
-
70
- function directivesToSvelteKitConfig(
71
- directives: Readonly<CspDirectives>,
72
- ): SvelteKitCsp["directives"] {
73
- const sveltekitDirectives: SvelteKitCsp["directives"] = {};
74
- for (const [optionKey, optionValues] of Object.entries(directives)) {
75
- const key = CONTENT_SECURITY_POLICY_DIRECTIVES.get(
76
- // @ts-expect-error because we're validating this option key
77
- optionKey,
78
- );
79
- if (!key) {
80
- throw new NoseconeValidationError(
81
- `${optionKey} is not a Content-Security-Policy directive`,
82
- );
83
- }
84
-
85
- // Skip anything falsey
86
- if (!optionValues) {
87
- continue;
88
- }
89
-
90
- // TODO: What do we want to do if array is empty? I think they work differently for some directives
91
- const resolvedValues = Array.isArray(optionValues)
92
- ? new Set(optionValues.map(resolveValue))
93
- : new Set<string>();
94
-
95
- // TODO: Add validations for SvelteKit CSP directives
96
-
97
- const values = Array.from(resolvedValues);
98
-
99
- if (key === "upgrade-insecure-requests") {
100
- sveltekitDirectives[key] = true;
101
- } else {
102
- // @ts-ignore because we're mapping to SvelteKit options
103
- sveltekitDirectives[key] = values.map(unquote);
104
- }
105
- }
106
-
107
- return sveltekitDirectives;
108
- }
109
-
110
- export function csp(
111
- options: ContentSecurityPolicyConfig = { mode: "auto", directives },
112
- ): SvelteKitCsp {
113
- return {
114
- mode: options.mode ? options.mode : "auto",
115
- directives: directivesToSvelteKitConfig(
116
- options.directives ?? defaults.contentSecurityPolicy.directives,
117
- ),
118
- };
119
- }