@forge/manifest 3.3.0-next.4 → 3.3.0-next.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"permissions-validator.d.ts","sourceRoot":"","sources":["../../src/validators/permissions-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAmB,MAAM,UAAU,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAU,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,qBAAa,oBACX,YAAW,kBAAkB,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,EAAE,cAAc,CAAC;IACzF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,GAAG,wBAAwB,CAAC,cAAc,CAAC;CAkIzG"}
1
+ {"version":3,"file":"permissions-validator.d.ts","sourceRoot":"","sources":["../../src/validators/permissions-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAmB,MAAM,UAAU,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAU,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,qBAAa,oBACX,YAAW,kBAAkB,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,EAAE,cAAc,CAAC;IACzF,OAAO,CAAC,gBAAgB,CAAoB;;IAM5C,OAAO,CAAC,UAAU;IA+BlB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,8BAA8B;IAWtC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,GAAG,wBAAwB,CAAC,cAAc,CAAC;CA8FzG"}
@@ -9,97 +9,100 @@ const url_1 = require("url");
9
9
  const shipyard_scopes_json_1 = tslib_1.__importDefault(require("../scopes/shipyard-scopes.json"));
10
10
  const deprecated_shipyard_scopes_json_1 = tslib_1.__importDefault(require("../scopes/deprecated-shipyard-scopes.json"));
11
11
  class PermissionsValidator {
12
- validate(manifest) {
13
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
14
- if (!manifest || !manifest.typedContent || !manifest.typedContent.permissions) {
15
- return {
16
- success: false,
17
- manifestObject: manifest
18
- };
12
+ constructor() {
13
+ this.validationErrors = [];
14
+ }
15
+ isValidURL(inputURL) {
16
+ const protocolRegex = /^(.*?:\/\/)/;
17
+ const validURI = /^(\*\.)?[.a-zA-Z0-9_\-\/:~#%?=&]+$/;
18
+ const allowedProtocols = ['https:', 'wss:'];
19
+ const MAX_URL_LENGTH = 1000;
20
+ if (inputURL.length > MAX_URL_LENGTH) {
21
+ return false;
19
22
  }
20
- const validationErrors = [];
21
- function addValidationError(element, value, manifest) {
22
- validationErrors.push(Object.assign({ message: text_1.errors.permissions.invalidPermission(element, value), reference: text_1.References.Permissions, level: 'error' }, utils_1.findPosition(value, manifest.yamlContentByLine)));
23
+ if (inputURL === '*') {
24
+ return true;
23
25
  }
26
+ if (!inputURL.includes('.') || inputURL.includes(' ')) {
27
+ return false;
28
+ }
29
+ try {
30
+ const domainOrUrlWithProtocol = protocolRegex.test(inputURL) ? inputURL : `https://${inputURL}`;
31
+ const parsedUrl = new url_1.URL(domainOrUrlWithProtocol);
32
+ if (!allowedProtocols.includes(parsedUrl.protocol)) {
33
+ return false;
34
+ }
35
+ return validURI.test(parsedUrl.hostname);
36
+ }
37
+ catch (_) {
38
+ return false;
39
+ }
40
+ }
41
+ isValidHash(cspString) {
24
42
  const BASE_64_HASH_PATTERNS = [
25
43
  /^sha256-[a-zA-Z0-9=+/]{44}$/,
26
44
  /^sha384-[a-zA-Z0-9=+/]{64}$/,
27
45
  /^sha512-[a-zA-Z0-9=+/]{88}$/
28
46
  ];
29
- function isValidHash(cspString) {
30
- return BASE_64_HASH_PATTERNS.some((pattern) => pattern.test(cspString));
47
+ return BASE_64_HASH_PATTERNS.some((pattern) => pattern.test(cspString));
48
+ }
49
+ addValidationErrors(element, values, manifest) {
50
+ values.forEach((value) => {
51
+ this.validationErrors.push(Object.assign({ message: text_1.errors.permissions.invalidPermission(element, value), reference: text_1.References.Permissions, level: 'error' }, utils_1.findPosition(value, manifest.yamlContentByLine)));
52
+ });
53
+ }
54
+ validateExternalPermissionURLs(extPermType, perms, manifest) {
55
+ const invalidPerms = perms === null || perms === void 0 ? void 0 : perms.filter((key) => !this.isValidURL(key));
56
+ if (invalidPerms === null || invalidPerms === void 0 ? void 0 : invalidPerms.length) {
57
+ this.addValidationErrors(extPermType, invalidPerms, manifest);
31
58
  }
32
- const validURI = /^(\*\.)?[.a-zA-Z0-9_\-\/:~#%?=&]+$/;
33
- const protocolRegex = /^(.*?:\/\/)/;
34
- const allowedProtocols = ['https:', 'wss:'];
35
- const MAX_URL_LENGTH = 1000;
36
- function isValidURL(inputURL) {
37
- if (inputURL.length > MAX_URL_LENGTH) {
38
- return false;
39
- }
40
- if (inputURL === '*') {
41
- return true;
42
- }
43
- if (!inputURL.includes('.') || inputURL.includes(' ')) {
44
- return false;
45
- }
46
- try {
47
- const domainOrUrlWithProtocol = protocolRegex.test(inputURL) ? inputURL : `https://${inputURL}`;
48
- const parsedUrl = new url_1.URL(domainOrUrlWithProtocol);
49
- if (!allowedProtocols.includes(parsedUrl.protocol)) {
50
- return false;
51
- }
52
- return validURI.test(parsedUrl.hostname);
53
- }
54
- catch (_) {
55
- return false;
56
- }
59
+ }
60
+ validate(manifest) {
61
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
62
+ if (!manifest || !manifest.typedContent || !manifest.typedContent.permissions) {
63
+ return {
64
+ success: false,
65
+ manifestObject: manifest
66
+ };
57
67
  }
58
68
  const ALL_SCOPES = shipyard_scopes_json_1.default.concat(deprecated_shipyard_scopes_json_1.default);
59
- const invalidScope = (_a = manifest.typedContent.permissions.scopes) === null || _a === void 0 ? void 0 : _a.find((key) => !ALL_SCOPES.includes(key));
60
- if (invalidScope) {
61
- addValidationError('scopes', invalidScope, manifest);
69
+ const invalidScopes = (_a = manifest.typedContent.permissions.scopes) === null || _a === void 0 ? void 0 : _a.filter((key) => !ALL_SCOPES.includes(key));
70
+ if (invalidScopes === null || invalidScopes === void 0 ? void 0 : invalidScopes.length) {
71
+ this.addValidationErrors('scopes', invalidScopes, manifest);
62
72
  }
63
- const invalidScripts = (_c = (_b = manifest.typedContent.permissions.content) === null || _b === void 0 ? void 0 : _b.scripts) === null || _c === void 0 ? void 0 : _c.find((key) => !egress_types_1.EGRESS_TYPES.EGRESS_SCRIPTS.includes(key) && !isValidHash(key));
64
- if (invalidScripts) {
65
- addValidationError('content.scripts', invalidScripts, manifest);
73
+ const invalidScripts = (_c = (_b = manifest.typedContent.permissions.content) === null || _b === void 0 ? void 0 : _b.scripts) === null || _c === void 0 ? void 0 : _c.filter((key) => !egress_types_1.EGRESS_TYPES.ALLOWED_CSP_TYPES.includes(key) && !this.isValidHash(key));
74
+ if (invalidScripts === null || invalidScripts === void 0 ? void 0 : invalidScripts.length) {
75
+ this.addValidationErrors('content.scripts', invalidScripts, manifest);
66
76
  }
67
- const invalidBackendString = (_f = (_e = (_d = manifest.typedContent.permissions.external) === null || _d === void 0 ? void 0 : _d.fetch) === null || _e === void 0 ? void 0 : _e.backend) === null || _f === void 0 ? void 0 : _f.filter((item) => typeof item === 'string').find((key) => !isValidURL(key));
68
- if (invalidBackendString) {
69
- addValidationError('external.fetch.backend', invalidBackendString, manifest);
77
+ const invalidBackendStrings = (_f = (_e = (_d = manifest.typedContent.permissions.external) === null || _d === void 0 ? void 0 : _d.fetch) === null || _e === void 0 ? void 0 : _e.backend) === null || _f === void 0 ? void 0 : _f.filter((item) => typeof item === 'string' && !this.isValidURL(item));
78
+ if (invalidBackendStrings === null || invalidBackendStrings === void 0 ? void 0 : invalidBackendStrings.length) {
79
+ this.addValidationErrors('external.fetch.backend', invalidBackendStrings, manifest);
70
80
  }
71
81
  const remoteMap = (_g = manifest.typedContent.remotes) === null || _g === void 0 ? void 0 : _g.reduce((prev, item) => prev.set(item.key, item.baseUrl), new Map());
72
- const invalidBackendRemote = (_k = (_j = (_h = manifest.typedContent.permissions.external) === null || _h === void 0 ? void 0 : _h.fetch) === null || _j === void 0 ? void 0 : _j.backend) === null || _k === void 0 ? void 0 : _k.filter((item) => typeof item === 'object').find((item) => !remoteMap || !remoteMap.has(item.remote) || !isValidURL(remoteMap.get(item.remote)));
73
- if (invalidBackendRemote) {
74
- addValidationError('external.fetch.backend', invalidBackendRemote.remote, manifest);
75
- }
76
- const invalidClientString = (_o = (_m = (_l = manifest.typedContent.permissions.external) === null || _l === void 0 ? void 0 : _l.fetch) === null || _m === void 0 ? void 0 : _m.client) === null || _o === void 0 ? void 0 : _o.filter((item) => typeof item === 'string').find((key) => !isValidURL(key));
77
- if (invalidClientString) {
78
- addValidationError('external.fetch.client', invalidClientString, manifest);
79
- }
80
- const invalidClient = (_r = (_q = (_p = manifest.typedContent.permissions.external) === null || _p === void 0 ? void 0 : _p.fetch) === null || _q === void 0 ? void 0 : _q.client) === null || _r === void 0 ? void 0 : _r.filter((item) => typeof item === 'object').find((item) => !remoteMap || !remoteMap.has(item.remote) || !isValidURL(remoteMap.get(item.remote)));
81
- if (invalidClient) {
82
- addValidationError('external.fetch.client', invalidClient.remote, manifest);
83
- }
84
- const invalidNavigation = (_t = (_s = manifest.typedContent.permissions.external) === null || _s === void 0 ? void 0 : _s.navigation) === null || _t === void 0 ? void 0 : _t.find((key) => !isValidURL(key));
85
- if (invalidNavigation) {
86
- addValidationError('external.navigation', invalidNavigation, manifest);
87
- }
88
- const invalidImages = (_v = (_u = manifest.typedContent.permissions.external) === null || _u === void 0 ? void 0 : _u.images) === null || _v === void 0 ? void 0 : _v.find((key) => !isValidURL(key));
89
- if (invalidImages) {
90
- addValidationError('external.images', invalidImages, manifest);
82
+ const invalidBackendRemotes = (_k = (_j = (_h = manifest.typedContent.permissions.external) === null || _h === void 0 ? void 0 : _h.fetch) === null || _j === void 0 ? void 0 : _j.backend) === null || _k === void 0 ? void 0 : _k.filter((item) => typeof item === 'object' &&
83
+ (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote)))).map((item) => item.remote);
84
+ if (invalidBackendRemotes === null || invalidBackendRemotes === void 0 ? void 0 : invalidBackendRemotes.length) {
85
+ this.addValidationErrors('external.fetch.backend', invalidBackendRemotes, manifest);
91
86
  }
92
- const invalidMedia = (_x = (_w = manifest.typedContent.permissions.external) === null || _w === void 0 ? void 0 : _w.media) === null || _x === void 0 ? void 0 : _x.find((key) => !isValidURL(key));
93
- if (invalidMedia) {
94
- addValidationError('external.media', invalidMedia, manifest);
87
+ const invalidClientStrings = (_o = (_m = (_l = manifest.typedContent.permissions.external) === null || _l === void 0 ? void 0 : _l.fetch) === null || _m === void 0 ? void 0 : _m.client) === null || _o === void 0 ? void 0 : _o.filter((item) => typeof item === 'string' && !this.isValidURL(item));
88
+ if (invalidClientStrings) {
89
+ this.addValidationErrors('external.fetch.client', invalidClientStrings, manifest);
95
90
  }
96
- const invalidExternalScripts = (_z = (_y = manifest.typedContent.permissions.external) === null || _y === void 0 ? void 0 : _y.scripts) === null || _z === void 0 ? void 0 : _z.find((key) => !isValidURL(key));
97
- if (invalidExternalScripts) {
98
- addValidationError('external.scripts', invalidExternalScripts, manifest);
91
+ const invalidClients = (_r = (_q = (_p = manifest.typedContent.permissions.external) === null || _p === void 0 ? void 0 : _p.fetch) === null || _q === void 0 ? void 0 : _q.client) === null || _r === void 0 ? void 0 : _r.filter((item) => typeof item === 'object' &&
92
+ (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote)))).map((item) => item.remote);
93
+ if (invalidClients) {
94
+ this.addValidationErrors('external.fetch.client', invalidClients, manifest);
99
95
  }
96
+ this.validateExternalPermissionURLs('external.navigation', (_s = manifest.typedContent.permissions.external) === null || _s === void 0 ? void 0 : _s.navigation, manifest);
97
+ this.validateExternalPermissionURLs('external.images', (_t = manifest.typedContent.permissions.external) === null || _t === void 0 ? void 0 : _t.images, manifest);
98
+ this.validateExternalPermissionURLs('external.frames', (_u = manifest.typedContent.permissions.external) === null || _u === void 0 ? void 0 : _u.frames, manifest);
99
+ this.validateExternalPermissionURLs('external.scripts', (_v = manifest.typedContent.permissions.external) === null || _v === void 0 ? void 0 : _v.scripts, manifest);
100
+ this.validateExternalPermissionURLs('external.styles', (_w = manifest.typedContent.permissions.external) === null || _w === void 0 ? void 0 : _w.styles, manifest);
101
+ this.validateExternalPermissionURLs('external.media', (_x = manifest.typedContent.permissions.external) === null || _x === void 0 ? void 0 : _x.media, manifest);
102
+ this.validateExternalPermissionURLs('external.fonts', (_y = manifest.typedContent.permissions.external) === null || _y === void 0 ? void 0 : _y.fonts, manifest);
100
103
  return {
101
- success: validationErrors.length === 0,
102
- errors: validationErrors
104
+ success: this.validationErrors.length === 0,
105
+ errors: this.validationErrors
103
106
  };
104
107
  }
105
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/manifest",
3
- "version": "3.3.0-next.4",
3
+ "version": "3.3.0-next.7",
4
4
  "description": "Definitions and validations of the Forge manifest",
5
5
  "main": "out/index.js",
6
6
  "scripts": {