@forge/egress 2.3.0 → 2.3.1-next.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @forge/egress
2
2
 
3
+ ## 2.3.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 16e7d61: Fixed bug when doing checking for CSPs
8
+
3
9
  ## 2.3.0
4
10
 
5
11
  ### Minor Changes
@@ -6,7 +6,12 @@ export declare class EgressFilteringService {
6
6
  private parseUrl;
7
7
  containsWildCardEgress(): boolean;
8
8
  isValidUrl(url: string): boolean;
9
+ isValidUrlCSP(url: string): boolean;
9
10
  private allowedDomainExact;
11
+ private allowedDomainExactAndPath;
10
12
  private allowedDomainPattern;
13
+ private allowedDomainPatternAndPath;
14
+ private protocolMatchesCSP;
15
+ private pathMatches;
11
16
  }
12
17
  //# sourceMappingURL=egress-filtering-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"egress-filtering-service.d.ts","sourceRoot":"","sources":["../../src/egress/egress-filtering-service.ts"],"names":[],"mappings":"AAOA,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAE/B,SAAS,EAAE,MAAM,EAAE;IAc/B,OAAO,CAAC,QAAQ;IAIT,sBAAsB,IAAI,OAAO;IAKjC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASvC,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,oBAAoB;CAK7B"}
1
+ {"version":3,"file":"egress-filtering-service.d.ts","sourceRoot":"","sources":["../../src/egress/egress-filtering-service.ts"],"names":[],"mappings":"AAOA,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAE/B,SAAS,EAAE,MAAM,EAAE;IAc/B,OAAO,CAAC,QAAQ;IAIT,sBAAsB,IAAI,OAAO;IAKjC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAahC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAW1C,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,2BAA2B;IAenC,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,WAAW;CAYpB"}
@@ -29,15 +29,56 @@ class EgressFilteringService {
29
29
  const parsedUrl = this.parseUrl(url);
30
30
  return this.allowedDomainExact(parsedUrl, this.URLs) || this.allowedDomainPattern(parsedUrl, this.wildcardDomains);
31
31
  }
32
+ isValidUrlCSP(url) {
33
+ if (this.allowsEverything) {
34
+ return true;
35
+ }
36
+ const parsedUrl = this.parseUrl(url);
37
+ return (this.allowedDomainExactAndPath(parsedUrl, this.URLs) ||
38
+ this.allowedDomainPatternAndPath(parsedUrl, this.wildcardDomains));
39
+ }
32
40
  allowedDomainExact(domain, allowList) {
33
41
  return allowList
34
42
  .filter((allowed) => allowed.protocol === domain.protocol)
35
43
  .some((url) => url.hostname === domain.hostname);
36
44
  }
45
+ allowedDomainExactAndPath(domain, allowList) {
46
+ return allowList
47
+ .filter((allowed) => this.protocolMatchesCSP(allowed.protocol, domain.protocol))
48
+ .filter((allowed) => allowed.hostname === domain.hostname)
49
+ .some((allowed) => this.pathMatches(allowed.pathname, domain.pathname));
50
+ }
37
51
  allowedDomainPattern(domain, allowList) {
38
52
  return allowList
39
53
  .filter((allowed) => allowed.protocol === domain.protocol)
40
54
  .some((pattern) => pattern.regex.test(domain.hostname));
41
55
  }
56
+ allowedDomainPatternAndPath(domain, allowList) {
57
+ return allowList
58
+ .filter((pattern) => this.protocolMatchesCSP(pattern.protocol, domain.protocol))
59
+ .filter((pattern) => pattern.regex.test(domain.hostname))
60
+ .some((allowed) => this.pathMatches(allowed.pathname, domain.pathname));
61
+ }
62
+ protocolMatchesCSP(allowedProtocol, requestProtocol) {
63
+ if (allowedProtocol === requestProtocol) {
64
+ return true;
65
+ }
66
+ if (allowedProtocol === 'http:' && requestProtocol === 'https:') {
67
+ return true;
68
+ }
69
+ if (allowedProtocol === 'ws:' && requestProtocol === 'wss:') {
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ pathMatches(allowedPath, requestPath) {
75
+ if (allowedPath === '/') {
76
+ return true;
77
+ }
78
+ if (allowedPath.endsWith('/')) {
79
+ return requestPath.startsWith(allowedPath);
80
+ }
81
+ return requestPath === allowedPath;
82
+ }
42
83
  }
43
84
  exports.EgressFilteringService = EgressFilteringService;
@@ -1,3 +1,5 @@
1
- export declare type URLLike = Pick<URL, 'hostname' | 'protocol'>;
1
+ export declare type URLLike = Pick<URL, 'hostname' | 'protocol'> & {
2
+ pathname: string;
3
+ };
2
4
  export declare function parseUrl(url: string): URLLike;
3
5
  //# sourceMappingURL=url-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-parser.d.ts","sourceRoot":"","sources":["../../src/egress/url-parser.ts"],"names":[],"mappings":"AAAA,oBAAY,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,CAAC,CAAC;AAKzD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAS7C"}
1
+ {"version":3,"file":"url-parser.d.ts","sourceRoot":"","sources":["../../src/egress/url-parser.ts"],"names":[],"mappings":"AAAA,oBAAY,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAKhF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO7C"}
@@ -4,11 +4,9 @@ exports.parseUrl = void 0;
4
4
  function parseUrl(url) {
5
5
  var _a, _b;
6
6
  const protocol = (_b = (_a = url.match(/^(.*?:)/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : 'https:';
7
- const hostname = url
8
- .replace(protocol, '')
9
- .replace(/^\/*/, '')
10
- .replace(/^\\*/, '')
11
- .split(/[\?\/]/)[0];
12
- return { protocol, hostname };
7
+ const hostAndPath = url.replace(protocol, '').replace(/^\/*/, '').replace(/^\\*/, '').split('?')[0].split('#')[0];
8
+ const hostname = hostAndPath.split('/')[0];
9
+ const pathname = hostAndPath.slice(hostname.length) || '/';
10
+ return { protocol, hostname, pathname };
13
11
  }
14
12
  exports.parseUrl = parseUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/egress",
3
- "version": "2.3.0",
3
+ "version": "2.3.1-next.0",
4
4
  "description": "Helpers and utils for egress implementation in Forge apps",
5
5
  "main": "out/index.js",
6
6
  "author": "Atlassian",