@forge/lint 3.4.1-next.5 → 3.5.0-experimental-5ec0ed7

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 (37) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/out/lint/lint.d.ts.map +1 -1
  3. package/out/lint/lint.js +2 -0
  4. package/out/lint/linters/dynamic-properties-linter/verifiers/dynamic-properties-icon-verifier.d.ts +0 -1
  5. package/out/lint/linters/dynamic-properties-linter/verifiers/dynamic-properties-icon-verifier.d.ts.map +1 -1
  6. package/out/lint/linters/dynamic-properties-linter/verifiers/dynamic-properties-icon-verifier.js +2 -10
  7. package/out/lint/linters/manifest-linter/remote-compute-manifest-linter.d.ts +9 -0
  8. package/out/lint/linters/manifest-linter/remote-compute-manifest-linter.d.ts.map +1 -0
  9. package/out/lint/linters/manifest-linter/remote-compute-manifest-linter.js +19 -0
  10. package/out/lint/linters/permission-linter/api-call-interface.d.ts +7 -2
  11. package/out/lint/linters/permission-linter/api-call-interface.d.ts.map +1 -1
  12. package/out/lint/linters/permission-linter/api-call-interface.js +1 -0
  13. package/out/lint/linters/permission-linter/permission-linter.d.ts +2 -1
  14. package/out/lint/linters/permission-linter/permission-linter.d.ts.map +1 -1
  15. package/out/lint/linters/permission-linter/permission-linter.js +6 -0
  16. package/out/lint/linters/permission-linter/verifiers/external-fetch-verifier.d.ts +0 -1
  17. package/out/lint/linters/permission-linter/verifiers/external-fetch-verifier.d.ts.map +1 -1
  18. package/out/lint/linters/permission-linter/verifiers/external-fetch-verifier.js +2 -10
  19. package/out/lint/linters/permission-linter/verifiers/image-url-verifier.d.ts +11 -0
  20. package/out/lint/linters/permission-linter/verifiers/image-url-verifier.d.ts.map +1 -0
  21. package/out/lint/linters/permission-linter/verifiers/image-url-verifier.js +35 -0
  22. package/out/lint/linters/permission-linter/verifiers/index.d.ts +1 -0
  23. package/out/lint/linters/permission-linter/verifiers/index.d.ts.map +1 -1
  24. package/out/lint/linters/permission-linter/verifiers/index.js +1 -0
  25. package/out/lint/linters/permission-linter/visitors/image-url-visitor.d.ts +11 -0
  26. package/out/lint/linters/permission-linter/visitors/image-url-visitor.d.ts.map +1 -0
  27. package/out/lint/linters/permission-linter/visitors/image-url-visitor.js +57 -0
  28. package/out/lint/linters/permission-linter/visitors/index.d.ts +1 -0
  29. package/out/lint/linters/permission-linter/visitors/index.d.ts.map +1 -1
  30. package/out/lint/linters/permission-linter/visitors/index.js +1 -0
  31. package/out/lint/linters/utils.d.ts +4 -0
  32. package/out/lint/linters/utils.d.ts.map +1 -0
  33. package/out/lint/linters/utils.js +12 -0
  34. package/out/lint/text/messages.d.ts +4 -0
  35. package/out/lint/text/messages.d.ts.map +1 -1
  36. package/out/lint/text/messages.js +4 -0
  37. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # @forge/lint
2
2
 
3
+ ## 3.5.0-experimental-5ec0ed7
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5fc7847]
8
+ - @forge/cli-shared@3.12.0-experimental-5ec0ed7
9
+
10
+ ## 3.5.0
11
+
12
+ ### Minor Changes
13
+
14
+ - cf0ab7be: Add egress permissions check for Image component URLs
15
+ - aa9b9754: Add scope validations for forge remote compute scopes
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [5eff9d5f]
20
+ - Updated dependencies [7dd1550b]
21
+ - Updated dependencies [0449769b]
22
+ - Updated dependencies [d94f614e]
23
+ - Updated dependencies [aa9b9754]
24
+ - Updated dependencies [83eb996c]
25
+ - Updated dependencies [08c6f1a8]
26
+ - Updated dependencies [05d6c05e]
27
+ - @forge/cli-shared@3.12.0
28
+ - @forge/manifest@4.13.0
29
+
30
+ ## 3.5.0-next.8
31
+
32
+ ### Minor Changes
33
+
34
+ - aa9b9754: Add scope validations for forge remote compute scopes
35
+
36
+ ### Patch Changes
37
+
38
+ - Updated dependencies [aa9b9754]
39
+ - @forge/manifest@4.13.0-next.4
40
+ - @forge/cli-shared@3.12.0-next.7
41
+
42
+ ## 3.5.0-next.7
43
+
44
+ ### Patch Changes
45
+
46
+ - Updated dependencies [d94f614e]
47
+ - @forge/cli-shared@3.12.0-next.6
48
+
49
+ ## 3.5.0-next.6
50
+
51
+ ### Minor Changes
52
+
53
+ - cf0ab7be: Add egress permissions check for Image component URLs
54
+
3
55
  ## 3.4.1-next.5
4
56
 
5
57
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/lint/lint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,oBAAoB,CAAC;AASxG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,WAAY,UAAU,eAAe,UAAU,EAAE,4BAAuB,IA+CrG,CAAC;AAEF,eAAO,MAAM,YAAY,gBAAiB,UAAU,EAAE,KAAG,YAQxD,CAAC;AAEF,eAAO,MAAM,eAAe,aAChB,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAOnB,CAAC;AAEF,eAAO,MAAM,IAAI,gBACF,MAAM,EAAE,YACX,QAAQ,eACL,MAAM,UACX,UAAU,6BAhBR,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAAC,YAeV,eAAe,EAAE,KAQzB,QAAQ,UAAU,EAAE,CAmCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,WACX,UAAU,WACV,eAAe,KACtB,QAAQ,UAAU,EAAE,CAGtB,CAAC"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/lint/lint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,oBAAoB,CAAC;AAUxG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,WAAY,UAAU,eAAe,UAAU,EAAE,4BAAuB,IA+CrG,CAAC;AAEF,eAAO,MAAM,YAAY,gBAAiB,UAAU,EAAE,KAAG,YAQxD,CAAC;AAEF,eAAO,MAAM,eAAe,aAChB,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAOnB,CAAC;AAEF,eAAO,MAAM,IAAI,gBACF,MAAM,EAAE,YACX,QAAQ,eACL,MAAM,UACX,UAAU,6BAhBR,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAAC,YAeV,eAAe,EAAE,KASzB,QAAQ,UAAU,EAAE,CAmCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,WACX,UAAU,WACV,eAAe,KACtB,QAAQ,UAAU,EAAE,CAGtB,CAAC"}
package/out/lint/lint.js CHANGED
@@ -14,6 +14,7 @@ const permissions_manifest_linter_1 = require("./linters/manifest-linter/permiss
14
14
  const permission_linter_1 = require("./linters/permission-linter/permission-linter");
15
15
  const deprecated_csp_permissions_manifest_linter_1 = require("./linters/manifest-linter/deprecated-csp-permissions-manifest-linter");
16
16
  const dynamic_properties_permissions_linter_1 = require("./linters/dynamic-properties-linter/dynamic-properties-permissions-linter");
17
+ const remote_compute_manifest_linter_1 = require("./linters/manifest-linter/remote-compute-manifest-linter");
17
18
  const reportLintResults = (logger, lintResults, showSummary = true) => {
18
19
  let numErrors = 0, numWarnings = 0;
19
20
  let noProblemsFound = true;
@@ -79,6 +80,7 @@ const lint = async (filesToLint, manifest, environment, logger, parseFunction =
79
80
  new permission_linter_1.PermissionLinter(environment, manifest, logger),
80
81
  new permissions_manifest_linter_1.PermissionsManifestLinter(logger),
81
82
  new deprecated_csp_permissions_manifest_linter_1.DeprecatedCspPermissionsManifestLinter(logger),
83
+ new remote_compute_manifest_linter_1.RemoteComputeManifestLinter(logger),
82
84
  new full_manifest_linter_1.FullManifestLinter(logger),
83
85
  new handler_linter_1.HandlerLinter(environment, manifest, logger),
84
86
  new dynamic_properties_permissions_linter_1.DynamicPropertiesPermissionsLinter(environment, manifest, logger)
@@ -7,7 +7,6 @@ export declare class DynamicPropertiesIconVerifier extends AbstractDynamicProper
7
7
  private egressFilteringService;
8
8
  constructor(environment: string, manifest: Manifest);
9
9
  protected getLintClass(): LintClass;
10
- private extractDomain;
11
10
  process(iconUrls: DynamicPropertiesIconUrl[]): Promise<LintResultRule[]>;
12
11
  }
13
12
  //# sourceMappingURL=dynamic-properties-icon-verifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-properties-icon-verifier.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/dynamic-properties-linter/verifiers/dynamic-properties-icon-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAE3F,qBAAa,6BACX,SAAQ,iCACR,YAAW,iBAAiB,CAAC,wBAAwB,EAAE,CAAC;IACxD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IASnD,SAAS,CAAC,YAAY,IAAI,SAAS;IAInC,OAAO,CAAC,aAAa,CAMnB;IAEW,OAAO,CAAC,QAAQ,EAAE,wBAAwB,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAmBtF"}
1
+ {"version":3,"file":"dynamic-properties-icon-verifier.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/dynamic-properties-linter/verifiers/dynamic-properties-icon-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAE3F,qBAAa,6BACX,SAAQ,iCACR,YAAW,iBAAiB,CAAC,wBAAwB,EAAE,CAAC;IACxD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IASnD,SAAS,CAAC,YAAY,IAAI,SAAS;IAItB,OAAO,CAAC,QAAQ,EAAE,wBAAwB,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAmBtF"}
@@ -3,21 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DynamicPropertiesIconVerifier = void 0;
4
4
  const egress_1 = require("@forge/egress");
5
5
  const linter_interface_1 = require("../../../linter-interface");
6
+ const utils_1 = require("../../utils");
6
7
  const text_1 = require("../../../text");
7
- const url_1 = require("url");
8
8
  const abstract_dynamic_properties_verifier_1 = require("./abstract-dynamic-properties-verifier");
9
9
  class DynamicPropertiesIconVerifier extends abstract_dynamic_properties_verifier_1.AbstractDynamicPropertiesVerifier {
10
10
  constructor(environment, manifest) {
11
11
  var _a, _b, _c, _d;
12
12
  super(environment, manifest);
13
- this.extractDomain = (iconUrl) => {
14
- try {
15
- return new url_1.URL(iconUrl.url).hostname;
16
- }
17
- catch (e) {
18
- return iconUrl.url;
19
- }
20
- };
21
13
  const allowList = (_d = (_c = (_b = (_a = this.manifest) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.external) === null || _c === void 0 ? void 0 : _c.images) !== null && _d !== void 0 ? _d : [];
22
14
  const collectedUrls = allowList.filter((item) => typeof item === 'string');
23
15
  this.egressFilteringService = new egress_1.EgressFilteringService(collectedUrls);
@@ -39,7 +31,7 @@ class DynamicPropertiesIconVerifier extends abstract_dynamic_properties_verifier
39
31
  column: iconUrl.column,
40
32
  line: iconUrl.line,
41
33
  metadata: {
42
- missingExternalImagesPermission: this.extractDomain(iconUrl)
34
+ missingExternalImagesPermission: (0, utils_1.extractDomain)(iconUrl)
43
35
  }
44
36
  }))
45
37
  ];
@@ -0,0 +1,9 @@
1
+ import { ManifestValidationResult, SchemaValidationError } from '@forge/manifest';
2
+ import { AbstractManifestLinter } from './abstract-manifest-linter';
3
+ import { LintResultRule, LintFixState, LintLogger } from '../../linter-interface';
4
+ export declare class RemoteComputeManifestLinter extends AbstractManifestLinter {
5
+ constructor(logger: LintLogger);
6
+ getFixer(): ((errors: LintResultRule[], warnings: LintResultRule[], state: LintFixState) => Promise<LintFixState>) | undefined;
7
+ getResultsForFixer(results: ManifestValidationResult<any>): SchemaValidationError[];
8
+ }
9
+ //# sourceMappingURL=remote-compute-manifest-linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-compute-manifest-linter.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/manifest-linter/remote-compute-manifest-linter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGlF,qBAAa,2BAA4B,SAAQ,sBAAsB;gBACzD,MAAM,EAAE,UAAU;IAI9B,QAAQ,IACJ,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,GACtG,SAAS;IAIb,kBAAkB,CAAC,OAAO,EAAE,wBAAwB,CAAC,GAAG,CAAC,GAAG,qBAAqB,EAAE;CAGpF"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RemoteComputeManifestLinter = void 0;
4
+ const manifest_1 = require("@forge/manifest");
5
+ const abstract_manifest_linter_1 = require("./abstract-manifest-linter");
6
+ const permission_linter_1 = require("../permission-linter/permission-linter");
7
+ class RemoteComputeManifestLinter extends abstract_manifest_linter_1.AbstractManifestLinter {
8
+ constructor(logger) {
9
+ super(manifest_1.ValidationTypes.FORGE_REMOTE_COMPUTE, logger);
10
+ }
11
+ getFixer() {
12
+ return permission_linter_1.fixMissingPermissions;
13
+ }
14
+ getResultsForFixer(results) {
15
+ var _a;
16
+ return ((_a = results.errors) === null || _a === void 0 ? void 0 : _a.filter((error) => { var _a; return (_a = error.metadata) === null || _a === void 0 ? void 0 : _a.missingPermission; })) || [];
17
+ }
18
+ }
19
+ exports.RemoteComputeManifestLinter = RemoteComputeManifestLinter;
@@ -4,7 +4,8 @@ export declare enum ApiCallTypes {
4
4
  'HOOK' = 1,
5
5
  'STORAGE' = 2,
6
6
  'EXTERNAL' = 3,
7
- 'CONTENT_PROPERTY' = 4
7
+ 'CONTENT_PROPERTY' = 4,
8
+ 'IMAGE' = 5
8
9
  }
9
10
  export interface ProductApiCall extends LintCriteriaMatch {
10
11
  type: ApiCallTypes.PRODUCT;
@@ -24,10 +25,14 @@ export interface ExternalApiCall extends LintCriteriaMatch {
24
25
  type: ApiCallTypes.EXTERNAL;
25
26
  url: string;
26
27
  }
28
+ export interface ImageUrl extends LintCriteriaMatch {
29
+ type: ApiCallTypes.IMAGE;
30
+ url: string;
31
+ }
27
32
  export interface ContentPropertyApiCall extends LintCriteriaMatch {
28
33
  type: ApiCallTypes.CONTENT_PROPERTY;
29
34
  context: string;
30
35
  method: string;
31
36
  }
32
- export declare type ApiCall = ProductApiCall | UIHookApiCall | StorageApiCall | ExternalApiCall | ContentPropertyApiCall;
37
+ export declare type ApiCall = ProductApiCall | UIHookApiCall | StorageApiCall | ExternalApiCall | ImageUrl | ContentPropertyApiCall;
33
38
  //# sourceMappingURL=api-call-interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-call-interface.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/permission-linter/api-call-interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,oBAAY,YAAY;IACtB,SAAS,IAAA;IACT,MAAM,IAAA;IACN,SAAS,IAAA;IACT,UAAU,IAAA;IACV,kBAAkB,IAAA;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,YAAY,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,OAAO,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,GAAG,eAAe,GAAG,sBAAsB,CAAC"}
1
+ {"version":3,"file":"api-call-interface.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/permission-linter/api-call-interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,oBAAY,YAAY;IACtB,SAAS,IAAA;IACT,MAAM,IAAA;IACN,SAAS,IAAA;IACT,UAAU,IAAA;IACV,kBAAkB,IAAA;IAClB,OAAO,IAAA;CACR;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,YAAY,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAS,SAAQ,iBAAiB;IACjD,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,OAAO,GACf,cAAc,GACd,aAAa,GACb,cAAc,GACd,eAAe,GACf,QAAQ,GACR,sBAAsB,CAAC"}
@@ -8,4 +8,5 @@ var ApiCallTypes;
8
8
  ApiCallTypes[ApiCallTypes["STORAGE"] = 2] = "STORAGE";
9
9
  ApiCallTypes[ApiCallTypes["EXTERNAL"] = 3] = "EXTERNAL";
10
10
  ApiCallTypes[ApiCallTypes["CONTENT_PROPERTY"] = 4] = "CONTENT_PROPERTY";
11
+ ApiCallTypes[ApiCallTypes["IMAGE"] = 5] = "IMAGE";
11
12
  })(ApiCallTypes = exports.ApiCallTypes || (exports.ApiCallTypes = {}));
@@ -1,7 +1,7 @@
1
1
  import type { ManifestSchema as Manifest } from '@forge/manifest';
2
2
  import BaseLinter from '../../base-linter';
3
3
  import { LintFixState, LintLogger, LintResultRule } from '../../linter-interface';
4
- import { ApiCall, ExternalApiCall, ProductApiCall, StorageApiCall, UIHookApiCall } from './api-call-interface';
4
+ import { ApiCall, ExternalApiCall, ImageUrl, ProductApiCall, StorageApiCall, UIHookApiCall } from './api-call-interface';
5
5
  import { PathMethods } from './verifiers';
6
6
  interface SwaggerFormat {
7
7
  paths: {
@@ -18,6 +18,7 @@ interface PermissionLintCriteriaMatches {
18
18
  storage: StorageApiCall[];
19
19
  uiHook: UIHookApiCall[];
20
20
  external: ExternalApiCall[];
21
+ image: ImageUrl[];
21
22
  }
22
23
  export declare class PermissionLinter extends BaseLinter<ApiCall, PermissionLintCriteriaMatches, ApiCall[]> {
23
24
  private manifest;
@@ -1 +1 @@
1
- {"version":3,"file":"permission-linter.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/permission-linter/permission-linter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAe,MAAM,iBAAiB,CAAC;AAE/E,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EACL,OAAO,EAEP,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAML,WAAW,EAGZ,MAAM,aAAa,CAAC;AAUrB,UAAU,aAAa;IACrB,KAAK,EAAE;QACL,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;KAC7B,CAAC;CACH;AAED,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAKhD,eAAO,MAAM,sBAAsB,WACzB,cAAc,EAAE,YACd,cAAc,EAAE,mBAEtB,mBAAmB,GACnB,gCAAgC,GAChC,+BAA+B,GAC/B,iCAAiC,UAC7B,YAAY,KACnB,IAAI,MAAM,CAkBZ,CAAC;AAEF,eAAO,MAAM,qBAAqB,WACxB,cAAc,EAAE,YACd,cAAc,EAAE,SACnB,YAAY,KAClB,QAAQ,YAAY,CAgEtB,CAAC;AAEF,UAAU,6BAA6B;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IACzB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,qBAAa,gBAAiB,SAAQ,UAAU,CAAC,OAAO,EAAE,6BAA6B,EAAE,OAAO,EAAE,CAAC;IAUhE,OAAO,CAAC,QAAQ;IATjD,MAAM,CAAC,cAAc,SAAgC;IACrD,MAAM,CAAC,aAAa,SAA+B;IACnD,MAAM,CAAC,aAAa,SAA+B;IACnD,MAAM,CAAC,oBAAoB,SAAsC;IAEjE,OAAO,CAAC,IAAI,CAAC,CAA0B;IACvC,OAAO,CAAC,UAAU,CAAC,CAA0B;IAC7C,OAAO,CAAC,KAAK,CAAC,CAAa;gBAEf,WAAW,EAAE,MAAM,EAAU,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAIlE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAgEvC,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAajD,SAAS,CAAC,QAAQ,IACd,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,GACtG,SAAS;IAIb,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAsB3D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAWtE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKrE,OAAO,CAAC,YAAY;CAarB"}
1
+ {"version":3,"file":"permission-linter.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/permission-linter/permission-linter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAe,MAAM,iBAAiB,CAAC;AAE/E,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EACL,OAAO,EAEP,eAAe,EACf,QAAQ,EACR,cAAc,EACd,cAAc,EACd,aAAa,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAOL,WAAW,EAGZ,MAAM,aAAa,CAAC;AAWrB,UAAU,aAAa;IACrB,KAAK,EAAE;QACL,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;KAC7B,CAAC;CACH;AAED,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAKhD,eAAO,MAAM,sBAAsB,WACzB,cAAc,EAAE,YACd,cAAc,EAAE,mBAEtB,mBAAmB,GACnB,gCAAgC,GAChC,+BAA+B,GAC/B,iCAAiC,UAC7B,YAAY,KACnB,IAAI,MAAM,CAkBZ,CAAC;AAEF,eAAO,MAAM,qBAAqB,WACxB,cAAc,EAAE,YACd,cAAc,EAAE,SACnB,YAAY,KAClB,QAAQ,YAAY,CAgEtB,CAAC;AAEF,UAAU,6BAA6B;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IACzB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,qBAAa,gBAAiB,SAAQ,UAAU,CAAC,OAAO,EAAE,6BAA6B,EAAE,OAAO,EAAE,CAAC;IAUhE,OAAO,CAAC,QAAQ;IATjD,MAAM,CAAC,cAAc,SAAgC;IACrD,MAAM,CAAC,aAAa,SAA+B;IACnD,MAAM,CAAC,aAAa,SAA+B;IACnD,MAAM,CAAC,oBAAoB,SAAsC;IAEjE,OAAO,CAAC,IAAI,CAAC,CAA0B;IACvC,OAAO,CAAC,UAAU,CAAC,CAA0B;IAC7C,OAAO,CAAC,KAAK,CAAC,CAAa;gBAEf,WAAW,EAAE,MAAM,EAAU,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU;IAIlE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAkEvC,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAcjD,SAAS,CAAC,QAAQ,IACd,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,GACtG,SAAS;IAIb,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAyB3D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAWtE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKrE,OAAO,CAAC,YAAY;CAarB"}
@@ -109,6 +109,7 @@ class PermissionLinter extends base_linter_1.default {
109
109
  new visitors_1.UIHookNodeVisitor(),
110
110
  new visitors_1.StorageAPINodeVisitor(),
111
111
  new visitors_1.ExternalApiCallVisitor(),
112
+ new visitors_1.ImageUrlVisitor(),
112
113
  new visitors_1.ContentPropertyVisitor()
113
114
  ];
114
115
  const humanReadableEnvironment = (0, cli_shared_1.environmentToOption)(this.environment);
@@ -118,6 +119,7 @@ class PermissionLinter extends base_linter_1.default {
118
119
  storage: new verifiers_1.StorageAPIVerifier(humanReadableEnvironment, this.manifest),
119
120
  uiHook: new verifiers_1.UIHookVerifier(humanReadableEnvironment, this.manifest),
120
121
  external: new verifiers_1.ExternalFetchVerifier(humanReadableEnvironment, this.manifest),
122
+ image: new verifiers_1.ImageUrlVerifier(humanReadableEnvironment, this.manifest),
121
123
  contentProperty: new verifiers_1.ContentPropertyVerifier(humanReadableEnvironment, this.manifest)
122
124
  };
123
125
  }
@@ -130,6 +132,7 @@ class PermissionLinter extends base_linter_1.default {
130
132
  uiHook: [],
131
133
  storage: [],
132
134
  external: [],
135
+ image: [],
133
136
  contentProperty: []
134
137
  });
135
138
  }
@@ -151,6 +154,9 @@ class PermissionLinter extends base_linter_1.default {
151
154
  case api_call_interface_1.ApiCallTypes.EXTERNAL:
152
155
  criteriaMatches.external.push(apiCall);
153
156
  break;
157
+ case api_call_interface_1.ApiCallTypes.IMAGE:
158
+ criteriaMatches.image.push(apiCall);
159
+ break;
154
160
  case api_call_interface_1.ApiCallTypes.CONTENT_PROPERTY:
155
161
  criteriaMatches.contentProperty.push(apiCall);
156
162
  break;
@@ -6,7 +6,6 @@ export declare class ExternalFetchVerifier extends BaseLintIssueVerifier impleme
6
6
  private egressFilteringService;
7
7
  constructor(environment: string, manifest: Manifest);
8
8
  protected getLintClass(): LintClass;
9
- private extractDomain;
10
9
  process(fetchCalls: ExternalApiCall[]): Promise<LintResultRule[]>;
11
10
  }
12
11
  //# sourceMappingURL=external-fetch-verifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-fetch-verifier.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/verifiers/external-fetch-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,qBAAa,qBAAsB,SAAQ,qBAAsB,YAAW,iBAAiB,CAAC,eAAe,EAAE,CAAC;IAC9G,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IAenD,SAAS,CAAC,YAAY,IAAI,SAAS;IAInC,OAAO,CAAC,aAAa,CAMnB;IAEW,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAc/E"}
1
+ {"version":3,"file":"external-fetch-verifier.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/verifiers/external-fetch-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,qBAAa,qBAAsB,SAAQ,qBAAsB,YAAW,iBAAiB,CAAC,eAAe,EAAE,CAAC;IAC9G,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IAenD,SAAS,CAAC,YAAY,IAAI,SAAS;IAItB,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAc/E"}
@@ -5,19 +5,11 @@ const egress_1 = require("@forge/egress");
5
5
  const linter_interface_1 = require("../../../linter-interface");
6
6
  const verifier_interface_1 = require("../../verifier-interface");
7
7
  const text_1 = require("../../../text");
8
- const url_1 = require("url");
8
+ const utils_1 = require("../../utils");
9
9
  class ExternalFetchVerifier extends verifier_interface_1.BaseLintIssueVerifier {
10
10
  constructor(environment, manifest) {
11
11
  var _a, _b, _c, _d, _e, _f, _g;
12
12
  super(environment, manifest);
13
- this.extractDomain = (fetchCall) => {
14
- try {
15
- return new url_1.URL(fetchCall.url).hostname;
16
- }
17
- catch (e) {
18
- return fetchCall.url;
19
- }
20
- };
21
13
  const allowList = (_e = (_d = (_c = (_b = (_a = this.manifest) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.external) === null || _c === void 0 ? void 0 : _c.fetch) === null || _d === void 0 ? void 0 : _d.backend) !== null && _e !== void 0 ? _e : [];
22
14
  const remoteList = (_g = (_f = this.manifest) === null || _f === void 0 ? void 0 : _f.remotes) !== null && _g !== void 0 ? _g : [];
23
15
  const collectedUrls = allowList.filter((item) => typeof item === 'string');
@@ -39,7 +31,7 @@ class ExternalFetchVerifier extends verifier_interface_1.BaseLintIssueVerifier {
39
31
  column: fetchCall.column,
40
32
  line: fetchCall.line,
41
33
  metadata: {
42
- missingExternalFetchPermission: this.extractDomain(fetchCall)
34
+ missingExternalFetchPermission: (0, utils_1.extractDomain)(fetchCall)
43
35
  }
44
36
  }));
45
37
  }
@@ -0,0 +1,11 @@
1
+ import type { ManifestSchema as Manifest } from '@forge/manifest';
2
+ import { LintClass, LintResultRule } from '../../../linter-interface';
3
+ import { BaseLintIssueVerifier, LintIssueVerifier } from '../../verifier-interface';
4
+ import { ImageUrl } from '../api-call-interface';
5
+ export declare class ImageUrlVerifier extends BaseLintIssueVerifier implements LintIssueVerifier<ImageUrl[]> {
6
+ private egressFilteringService;
7
+ constructor(environment: string, manifest: Manifest);
8
+ protected getLintClass(): LintClass;
9
+ process(imageUrls: ImageUrl[]): Promise<LintResultRule[]>;
10
+ }
11
+ //# sourceMappingURL=image-url-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-url-verifier.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/verifiers/image-url-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAIjD,qBAAa,gBAAiB,SAAQ,qBAAsB,YAAW,iBAAiB,CAAC,QAAQ,EAAE,CAAC;IAClG,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IAUnD,SAAS,CAAC,YAAY,IAAI,SAAS;IAItB,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAcvE"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageUrlVerifier = void 0;
4
+ const egress_1 = require("@forge/egress");
5
+ const linter_interface_1 = require("../../../linter-interface");
6
+ const verifier_interface_1 = require("../../verifier-interface");
7
+ const text_1 = require("../../../text");
8
+ const utils_1 = require("../../utils");
9
+ class ImageUrlVerifier extends verifier_interface_1.BaseLintIssueVerifier {
10
+ constructor(environment, manifest) {
11
+ var _a, _b, _c, _d;
12
+ super(environment, manifest);
13
+ const allowList = (_d = (_c = (_b = (_a = this.manifest) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.external) === null || _c === void 0 ? void 0 : _c.images) !== null && _d !== void 0 ? _d : [];
14
+ const collectedUrls = allowList.filter((item) => typeof item === 'string');
15
+ this.egressFilteringService = new egress_1.EgressFilteringService(collectedUrls);
16
+ }
17
+ getLintClass() {
18
+ return linter_interface_1.LintClass.Error;
19
+ }
20
+ async process(imageUrls) {
21
+ return imageUrls
22
+ .filter(({ url }) => !this.egressFilteringService.isValidUrl(url))
23
+ .map((imageUrl) => ({
24
+ class: this.getLintClass(),
25
+ message: text_1.messages.verifiers.imageUrl.message(imageUrl.url),
26
+ reference: text_1.messages.verifiers.imageUrl.reference,
27
+ column: imageUrl.column,
28
+ line: imageUrl.line,
29
+ metadata: {
30
+ missingExternalImagesPermission: (0, utils_1.extractDomain)(imageUrl)
31
+ }
32
+ }));
33
+ }
34
+ }
35
+ exports.ImageUrlVerifier = ImageUrlVerifier;
@@ -3,4 +3,5 @@ export * from './storage-api-verifier';
3
3
  export * from './ui-hook-verifier';
4
4
  export * from './external-fetch-verifier';
5
5
  export * from './content-property-verifier';
6
+ export * from './image-url-verifier';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/verifiers/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/verifiers/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC"}
@@ -6,3 +6,4 @@ tslib_1.__exportStar(require("./storage-api-verifier"), exports);
6
6
  tslib_1.__exportStar(require("./ui-hook-verifier"), exports);
7
7
  tslib_1.__exportStar(require("./external-fetch-verifier"), exports);
8
8
  tslib_1.__exportStar(require("./content-property-verifier"), exports);
9
+ tslib_1.__exportStar(require("./image-url-verifier"), exports);
@@ -0,0 +1,11 @@
1
+ import { TSESTree } from '@typescript-eslint/typescript-estree';
2
+ import { NodeVisitor } from '../../node-visitor-interface';
3
+ import { ApiCall } from '../api-call-interface';
4
+ export declare class ImageUrlVisitor implements NodeVisitor<ApiCall> {
5
+ static ABSOLUTE_URL_REGEX: RegExp;
6
+ visit(node: TSESTree.Node, _parent: TSESTree.Node | undefined, callback: (apiCall: ApiCall) => void): void;
7
+ private getImageUrlNode;
8
+ private isBundledUri;
9
+ private isAbsoluteUrl;
10
+ }
11
+ //# sourceMappingURL=image-url-visitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-url-visitor.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/visitors/image-url-visitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAA0B,MAAM,uBAAuB,CAAC;AAExE,qBAAa,eAAgB,YAAW,WAAW,CAAC,OAAO,CAAC;IAC1D,MAAM,CAAC,kBAAkB,SAAyB;IAE3C,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAgCjH,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;CAGtB"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageUrlVisitor = void 0;
4
+ const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
5
+ const api_call_interface_1 = require("../api-call-interface");
6
+ class ImageUrlVisitor {
7
+ visit(node, _parent, callback) {
8
+ const imageUrlNode = this.getImageUrlNode(node);
9
+ if (!imageUrlNode) {
10
+ return undefined;
11
+ }
12
+ if ((imageUrlNode === null || imageUrlNode === void 0 ? void 0 : imageUrlNode.type) === typescript_estree_1.AST_NODE_TYPES.JSXAttribute) {
13
+ const imageUrlAttribute = imageUrlNode.value;
14
+ if (imageUrlAttribute &&
15
+ imageUrlAttribute.type === typescript_estree_1.AST_NODE_TYPES.Literal &&
16
+ typeof imageUrlAttribute.value === 'string') {
17
+ if (imageUrlAttribute.value.trim() !== '' &&
18
+ !this.isBundledUri(imageUrlAttribute.value) &&
19
+ this.isAbsoluteUrl(imageUrlAttribute.value)) {
20
+ const imageUrl = {
21
+ type: api_call_interface_1.ApiCallTypes.IMAGE,
22
+ url: imageUrlAttribute.value,
23
+ line: imageUrlAttribute.loc.start.line,
24
+ column: imageUrlAttribute.loc.start.column
25
+ };
26
+ callback(imageUrl);
27
+ }
28
+ }
29
+ }
30
+ }
31
+ getImageUrlNode(node) {
32
+ if (node.type !== typescript_estree_1.AST_NODE_TYPES.JSXOpeningElement) {
33
+ return undefined;
34
+ }
35
+ const { name, attributes } = node;
36
+ if (name.type === typescript_estree_1.AST_NODE_TYPES.JSXIdentifier && name.name === 'Image') {
37
+ return attributes.find((attribute) => {
38
+ if (attribute.type !== typescript_estree_1.AST_NODE_TYPES.JSXAttribute) {
39
+ return false;
40
+ }
41
+ if (attribute.name.type === typescript_estree_1.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === 'src') {
42
+ return true;
43
+ }
44
+ return false;
45
+ });
46
+ }
47
+ return undefined;
48
+ }
49
+ isBundledUri(imageUri) {
50
+ return imageUri.startsWith('resource:') || imageUri.startsWith('data:image');
51
+ }
52
+ isAbsoluteUrl(url) {
53
+ return ImageUrlVisitor.ABSOLUTE_URL_REGEX.test(url);
54
+ }
55
+ }
56
+ exports.ImageUrlVisitor = ImageUrlVisitor;
57
+ ImageUrlVisitor.ABSOLUTE_URL_REGEX = /^(?:[a-z+]+:)?\/\//i;
@@ -3,4 +3,5 @@ export * from './storage-api-node-visitor';
3
3
  export * from './ui-hook-node-visitor';
4
4
  export * from './external-fetch-call-visitor';
5
5
  export * from './content-property-visitor';
6
+ export * from './image-url-visitor';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/visitors/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/permission-linter/visitors/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC"}
@@ -6,3 +6,4 @@ tslib_1.__exportStar(require("./storage-api-node-visitor"), exports);
6
6
  tslib_1.__exportStar(require("./ui-hook-node-visitor"), exports);
7
7
  tslib_1.__exportStar(require("./external-fetch-call-visitor"), exports);
8
8
  tslib_1.__exportStar(require("./content-property-visitor"), exports);
9
+ tslib_1.__exportStar(require("./image-url-visitor"), exports);
@@ -0,0 +1,4 @@
1
+ export declare const extractDomain: (urlAstNode: {
2
+ url: string;
3
+ }) => string;
4
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lint/linters/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,eAAgB;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,WAMxD,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractDomain = void 0;
4
+ const extractDomain = (urlAstNode) => {
5
+ try {
6
+ return new URL(urlAstNode.url).hostname;
7
+ }
8
+ catch (e) {
9
+ return urlAstNode.url;
10
+ }
11
+ };
12
+ exports.extractDomain = extractDomain;
@@ -13,6 +13,10 @@ export declare const messages: {
13
13
  warning: () => string;
14
14
  reference: string;
15
15
  };
16
+ imageUrl: {
17
+ message: (url: string) => string;
18
+ reference: string;
19
+ };
16
20
  handler: {
17
21
  message: (method: string, key: string) => string;
18
22
  reference: string;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/lint/text/messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;+BAGI,MAAM,UAAU,MAAM,SAAS,MAAM,KAAG,MAAM;;;;2BAKlD,MAAM;;;;2BAIN,MAAM;2BAER,MAAM;;;;8BAKD,MAAM,OAAO,MAAM;;;;+BAKlB,MAAM,UAAU,MAAM,QAAQ,MAAM,GAAG,SAAS,SAAS,MAAM;;;;6BAKjE,MAAM;;;;+BAIJ,MAAM,QAAQ,MAAM,SAAS,MAAM;;;;CAK3D,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/lint/text/messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;+BAGI,MAAM,UAAU,MAAM,SAAS,MAAM,KAAG,MAAM;;;;2BAKlD,MAAM;;;;2BAIN,MAAM;2BAER,MAAM;;;;2BAKJ,MAAM;;;;8BAKH,MAAM,OAAO,MAAM;;;;+BAKlB,MAAM,UAAU,MAAM,QAAQ,MAAM,GAAG,SAAS,SAAS,MAAM;;;;6BAKjE,MAAM;;;;+BAIJ,MAAM,QAAQ,MAAM,SAAS,MAAM;;;;CAK3D,CAAC"}
@@ -16,6 +16,10 @@ exports.messages = {
16
16
  warning: () => `When using dynamic content properties along with icons, make sure to add the icon URL into the external images permissions of your app manifest. Otherwise, the icon will not be rendered.`,
17
17
  reference: 'egress-permission-required'
18
18
  },
19
+ imageUrl: {
20
+ message: (url) => `The domain ${url} is not included in the external images permissions of your app manifest`,
21
+ reference: 'egress-permission-required'
22
+ },
19
23
  handler: {
20
24
  message: (method, key) => `Cannot find exported function '${method}', which is required by module '${key}' handler defined in the manifest`,
21
25
  reference: 'valid-module-required'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/lint",
3
- "version": "3.4.1-next.5",
3
+ "version": "3.5.0-experimental-5ec0ed7",
4
4
  "description": "Linting for forge apps",
5
5
  "main": "out/index.js",
6
6
  "license": "UNLICENSED",
@@ -17,9 +17,9 @@
17
17
  "@types/node-fetch": "^2.5.7"
18
18
  },
19
19
  "dependencies": {
20
- "@forge/cli-shared": "3.12.0-next.5",
20
+ "@forge/cli-shared": "3.12.0-experimental-5ec0ed7",
21
21
  "@forge/egress": "1.2.1",
22
- "@forge/manifest": "4.13.0-next.3",
22
+ "@forge/manifest": "4.13.0",
23
23
  "@typescript-eslint/typescript-estree": "^5.40.0",
24
24
  "array.prototype.flatmap": "^1.2.3",
25
25
  "atlassian-openapi": "^1.0.17",