@lwrjs/security 0.13.0-alpha.8 → 0.13.0
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/build/cjs/headers.cjs +11 -8
- package/build/cjs/wrapper.cjs +3 -0
- package/build/es/headers.js +13 -9
- package/build/es/wrapper.js +4 -0
- package/package.json +7 -4
package/build/cjs/headers.cjs
CHANGED
|
@@ -26,7 +26,6 @@ __markAsModule(exports);
|
|
|
26
26
|
__export(exports, {
|
|
27
27
|
resolveHeaders: () => resolveHeaders
|
|
28
28
|
});
|
|
29
|
-
var import_crypto = __toModule(require("crypto"));
|
|
30
29
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
31
30
|
var import_content_security_policy = __toModule(require("./headers/content-security-policy.cjs"));
|
|
32
31
|
var import_referrer_policy = __toModule(require("./headers/referrer-policy.cjs"));
|
|
@@ -40,22 +39,26 @@ function getResources(viewDefinition) {
|
|
|
40
39
|
if (viewRecord.bootstrapModule?.resources) {
|
|
41
40
|
resources.push(...viewRecord.bootstrapModule.resources);
|
|
42
41
|
}
|
|
42
|
+
if (viewRecord.moduleResources) {
|
|
43
|
+
resources.push(...viewRecord.moduleResources);
|
|
44
|
+
}
|
|
43
45
|
return resources;
|
|
44
46
|
}
|
|
45
|
-
function hash(source) {
|
|
46
|
-
return `'sha256-${(0, import_crypto.createHash)("sha256").update(source).digest("base64")}'`;
|
|
47
|
-
}
|
|
48
47
|
async function hashResources(resources) {
|
|
49
48
|
const hashes = [];
|
|
50
49
|
for (const resource of resources) {
|
|
51
|
-
if (!resource.inline || resource.type !== "application/javascript")
|
|
50
|
+
if (!resource.inline || resource.type !== "application/javascript") {
|
|
51
|
+
if (resource.integrity) {
|
|
52
|
+
hashes.push(`'${resource.integrity}'`);
|
|
53
|
+
}
|
|
52
54
|
continue;
|
|
55
|
+
}
|
|
53
56
|
if (resource.content) {
|
|
54
|
-
hashes.push(
|
|
57
|
+
hashes.push(`'${(0, import_shared_utils.createIntegrityHash)(resource.content)}'`);
|
|
55
58
|
}
|
|
56
59
|
if (resource.stream) {
|
|
57
60
|
const content = await (0, import_shared_utils.streamToString)(resource.stream());
|
|
58
|
-
hashes.push(
|
|
61
|
+
hashes.push(`'${(0, import_shared_utils.createIntegrityHash)(content)}'`);
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
return hashes;
|
|
@@ -67,7 +70,7 @@ async function getResourceHashes(viewResponse) {
|
|
|
67
70
|
const {viewDefinition} = viewResponse.metadata;
|
|
68
71
|
const resources = getResources(viewDefinition);
|
|
69
72
|
const hashes = await hashResources(resources);
|
|
70
|
-
if (viewDefinition.nonce) {
|
|
73
|
+
if ((0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE && viewDefinition.nonce) {
|
|
71
74
|
hashes.push(`'nonce-${viewDefinition.nonce}'`);
|
|
72
75
|
}
|
|
73
76
|
return hashes;
|
package/build/cjs/wrapper.cjs
CHANGED
|
@@ -51,6 +51,9 @@ function secure(routeHandler, options) {
|
|
|
51
51
|
return routeHandlerResponse;
|
|
52
52
|
}
|
|
53
53
|
if (isViewDefinitionResponse(routeHandlerResponse)) {
|
|
54
|
+
if (routeHandlerResponse.locale) {
|
|
55
|
+
routeHandlerResponse.view.locale = routeHandlerResponse.locale;
|
|
56
|
+
}
|
|
54
57
|
const viewResponse = await context.viewApi.getViewResponse(routeHandlerResponse.view, routeHandlerResponse.viewParams, routeHandlerResponse.renderOptions);
|
|
55
58
|
viewResponse.headers = {
|
|
56
59
|
...viewResponse.headers,
|
package/build/es/headers.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { streamToString } from '@lwrjs/shared-utils';
|
|
1
|
+
import { createIntegrityHash, getFeatureFlags, streamToString } from '@lwrjs/shared-utils';
|
|
3
2
|
import contentSecurityPolicy from './headers/content-security-policy.js';
|
|
4
3
|
import referrerPolicy from './headers/referrer-policy.js';
|
|
5
4
|
import strictTransportSecurity from './headers/strict-transport-security.js';
|
|
@@ -12,24 +11,29 @@ function getResources(viewDefinition) {
|
|
|
12
11
|
if (viewRecord.bootstrapModule?.resources) {
|
|
13
12
|
resources.push(...viewRecord.bootstrapModule.resources);
|
|
14
13
|
}
|
|
14
|
+
if (viewRecord.moduleResources) {
|
|
15
|
+
resources.push(...viewRecord.moduleResources);
|
|
16
|
+
}
|
|
15
17
|
return resources;
|
|
16
18
|
}
|
|
17
|
-
function hash(source) {
|
|
18
|
-
return `'sha256-${createHash('sha256').update(source).digest('base64')}'`;
|
|
19
|
-
}
|
|
20
19
|
async function hashResources(resources) {
|
|
21
20
|
const hashes = [];
|
|
22
21
|
for (const resource of resources) {
|
|
23
22
|
// TODO: support other inlined resource types
|
|
24
|
-
if (!resource.inline || resource.type !== 'application/javascript')
|
|
23
|
+
if (!resource.inline || resource.type !== 'application/javascript') {
|
|
24
|
+
// If there is a integrity add that to the CSP hashes
|
|
25
|
+
if (resource.integrity) {
|
|
26
|
+
hashes.push(`'${resource.integrity}'`);
|
|
27
|
+
}
|
|
25
28
|
continue;
|
|
29
|
+
}
|
|
26
30
|
if (resource.content) {
|
|
27
|
-
hashes.push(
|
|
31
|
+
hashes.push(`'${createIntegrityHash(resource.content)}'`);
|
|
28
32
|
}
|
|
29
33
|
if (resource.stream) {
|
|
30
34
|
// eslint-disable-next-line no-await-in-loop
|
|
31
35
|
const content = await streamToString(resource.stream());
|
|
32
|
-
hashes.push(
|
|
36
|
+
hashes.push(`'${createIntegrityHash(content)}'`);
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
return hashes;
|
|
@@ -42,7 +46,7 @@ async function getResourceHashes(viewResponse) {
|
|
|
42
46
|
const resources = getResources(viewDefinition);
|
|
43
47
|
const hashes = await hashResources(resources);
|
|
44
48
|
// Add nonce hash
|
|
45
|
-
if (viewDefinition.nonce) {
|
|
49
|
+
if (getFeatureFlags().ENABLE_NONCE && viewDefinition.nonce) {
|
|
46
50
|
hashes.push(`'nonce-${viewDefinition.nonce}'`);
|
|
47
51
|
}
|
|
48
52
|
return hashes;
|
package/build/es/wrapper.js
CHANGED
|
@@ -37,6 +37,10 @@ export function secure(routeHandler, options) {
|
|
|
37
37
|
return routeHandlerResponse;
|
|
38
38
|
}
|
|
39
39
|
if (isViewDefinitionResponse(routeHandlerResponse)) {
|
|
40
|
+
// We have to do this here because we are calling the getViewResponse here. Rather than after the routeHandler was returned
|
|
41
|
+
if (routeHandlerResponse.locale) {
|
|
42
|
+
routeHandlerResponse.view.locale = routeHandlerResponse.locale;
|
|
43
|
+
}
|
|
40
44
|
// resolve the view based on the route handler response
|
|
41
45
|
const viewResponse = await context.viewApi.getViewResponse(routeHandlerResponse.view, routeHandlerResponse.viewParams, routeHandlerResponse.renderOptions);
|
|
42
46
|
viewResponse.headers = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lwrjs/security",
|
|
3
|
-
"version": "0.13.0
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "build/es/index.d.ts",
|
|
@@ -28,14 +28,17 @@
|
|
|
28
28
|
"build/**/*.cjs",
|
|
29
29
|
"build/**/*.d.ts"
|
|
30
30
|
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -b"
|
|
33
|
+
},
|
|
31
34
|
"dependencies": {
|
|
32
|
-
"@lwrjs/shared-utils": "0.13.0
|
|
35
|
+
"@lwrjs/shared-utils": "0.13.0"
|
|
33
36
|
},
|
|
34
37
|
"devDependencies": {
|
|
35
|
-
"@lwrjs/types": "0.13.0
|
|
38
|
+
"@lwrjs/types": "0.13.0"
|
|
36
39
|
},
|
|
37
40
|
"engines": {
|
|
38
41
|
"node": ">=18.0.0"
|
|
39
42
|
},
|
|
40
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "21dc6b8ffd2e633f36b46daf9e1563992c5143b9"
|
|
41
44
|
}
|