@forge/egress

2.3.02.3.1-next.0
~

Modified (8 files)

Index: package/out/egress/egress-filtering-service.js
===================================================================
--- package/out/egress/egress-filtering-service.js
+++ package/out/egress/egress-filtering-service.js
@@ -28,16 +28,57 @@
         }
         const parsedUrl = this.parseUrl(url);
         return this.allowedDomainExact(parsedUrl, this.URLs) || this.allowedDomainPattern(parsedUrl, this.wildcardDomains);
     }
+    isValidUrlCSP(url) {
+        if (this.allowsEverything) {
+            return true;
+        }
+        const parsedUrl = this.parseUrl(url);
+        return (this.allowedDomainExactAndPath(parsedUrl, this.URLs) ||
+            this.allowedDomainPatternAndPath(parsedUrl, this.wildcardDomains));
+    }
     allowedDomainExact(domain, allowList) {
         return allowList
             .filter((allowed) => allowed.protocol === domain.protocol)
             .some((url) => url.hostname === domain.hostname);
     }
+    allowedDomainExactAndPath(domain, allowList) {
+        return allowList
+            .filter((allowed) => this.protocolMatchesCSP(allowed.protocol, domain.protocol))
+            .filter((allowed) => allowed.hostname === domain.hostname)
+            .some((allowed) => this.pathMatches(allowed.pathname, domain.pathname));
+    }
     allowedDomainPattern(domain, allowList) {
         return allowList
             .filter((allowed) => allowed.protocol === domain.protocol)
             .some((pattern) => pattern.regex.test(domain.hostname));
     }
+    allowedDomainPatternAndPath(domain, allowList) {
+        return allowList
+            .filter((pattern) => this.protocolMatchesCSP(pattern.protocol, domain.protocol))
+            .filter((pattern) => pattern.regex.test(domain.hostname))
+            .some((allowed) => this.pathMatches(allowed.pathname, domain.pathname));
+    }
+    protocolMatchesCSP(allowedProtocol, requestProtocol) {
+        if (allowedProtocol === requestProtocol) {
+            return true;
+        }
+        if (allowedProtocol === 'http:' && requestProtocol === 'https:') {
+            return true;
+        }
+        if (allowedProtocol === 'ws:' && requestProtocol === 'wss:') {
+            return true;
+        }
+        return false;
+    }
+    pathMatches(allowedPath, requestPath) {
+        if (allowedPath === '/') {
+            return true;
+        }
+        if (allowedPath.endsWith('/')) {
+            return requestPath.startsWith(allowedPath);
+        }
+        return requestPath === allowedPath;
+    }
 }
 exports.EgressFilteringService = EgressFilteringService;
Index: package/out/egress/url-parser.js
===================================================================
--- package/out/egress/url-parser.js
+++ package/out/egress/url-parser.js
@@ -3,12 +3,10 @@
 exports.parseUrl = void 0;
 function parseUrl(url) {
     var _a, _b;
     const protocol = (_b = (_a = url.match(/^(.*?:)/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : 'https:';
-    const hostname = url
-        .replace(protocol, '')
-        .replace(/^\/*/, '')
-        .replace(/^\\*/, '')
-        .split(/[\?\/]/)[0];
-    return { protocol, hostname };
+    const hostAndPath = url.replace(protocol, '').replace(/^\/*/, '').replace(/^\\*/, '').split('?')[0].split('#')[0];
+    const hostname = hostAndPath.split('/')[0];
+    const pathname = hostAndPath.slice(hostname.length) || '/';
+    return { protocol, hostname, pathname };
 }
 exports.parseUrl = parseUrl;
Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@forge/egress",
-  "version": "2.3.0",
+  "version": "2.3.1-next.0",
   "description": "Helpers and utils for egress implementation in Forge apps",
   "main": "out/index.js",
   "author": "Atlassian",
   "license": "SEE LICENSE IN LICENSE.txt",
Index: package/out/egress/egress-filtering-service.d.ts.map
===================================================================
--- package/out/egress/egress-filtering-service.d.ts.map
+++ package/out/egress/egress-filtering-service.d.ts.map
@@ -1,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"}
\ No newline at end of file
+{"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"}
\ No newline at end of file
Index: package/out/egress/url-parser.d.ts.map
===================================================================
--- package/out/egress/url-parser.d.ts.map
+++ package/out/egress/url-parser.d.ts.map
@@ -1,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"}
\ No newline at end of file
+{"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"}
\ No newline at end of file
Index: package/CHANGELOG.md
===================================================================
--- package/CHANGELOG.md
+++ package/CHANGELOG.md
@@ -1,6 +1,12 @@
 # @forge/egress
 
+## 2.3.1-next.0
+
+### Patch Changes
+
+- 16e7d61: Fixed bug when doing checking for CSPs
+
 ## 2.3.0
 
 ### Minor Changes
Index: package/out/egress/egress-filtering-service.d.ts
===================================================================
--- package/out/egress/egress-filtering-service.d.ts
+++ package/out/egress/egress-filtering-service.d.ts
@@ -5,8 +5,13 @@
     constructor(allowList: string[]);
     private parseUrl;
     containsWildCardEgress(): boolean;
     isValidUrl(url: string): boolean;
+    isValidUrlCSP(url: string): boolean;
     private allowedDomainExact;
+    private allowedDomainExactAndPath;
     private allowedDomainPattern;
+    private allowedDomainPatternAndPath;
+    private protocolMatchesCSP;
+    private pathMatches;
 }
 //# sourceMappingURL=egress-filtering-service.d.ts.map
\ No newline at end of file
Index: package/out/egress/url-parser.d.ts
===================================================================
--- package/out/egress/url-parser.d.ts
+++ package/out/egress/url-parser.d.ts
@@ -1,3 +1,5 @@
-export declare type URLLike = Pick<URL, 'hostname' | 'protocol'>;
+export declare type URLLike = Pick<URL, 'hostname' | 'protocol'> & {
+    pathname: string;
+};
 export declare function parseUrl(url: string): URLLike;
 //# sourceMappingURL=url-parser.d.ts.map
\ No newline at end of file