@forge/api

6.4.2-next.0-experimental-0c74a4b6.4.2-next.1
out/api/permissions.js
out/api/permissions.js
+10−14
Index: package/out/api/permissions.js
===================================================================
--- package/out/api/permissions.js
+++ package/out/api/permissions.js
@@ -2,9 +2,8 @@
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.permissions = exports.canLoadResource = exports.canFetchFrom = exports.hasScope = exports.hasPermission = exports.extractUrlString = void 0;
 const runtime_1 = require("./runtime");
 const errors_1 = require("./errors");
-const minimatch_1 = require("minimatch");
 const egress_1 = require("@forge/egress");
 function extractUrlString(url) {
     if (typeof url === 'string') {
         return url;
@@ -14,12 +13,8 @@
     }
     return url.remote;
 }
 exports.extractUrlString = extractUrlString;
-function normalizeUrl(url) {
-    const { protocol, hostname } = (0, egress_1.parseUrl)(url);
-    return `${protocol}//${hostname}`;
-}
 function wrapInSyncMetrics(options, cb) {
     const metrics = (0, runtime_1.__getRuntime)().metrics;
     metrics.counter(options.name, options.tags).incr();
     return cb();
@@ -36,16 +31,17 @@
         }
     }
     return undefined;
 };
-const getMissingUrls = (requiredUrls, currentlyGrantedUrls) => {
+const getMissingUrls = (requiredUrls, currentlyGrantedUrls, useCSP) => {
+    const allowList = currentlyGrantedUrls.map((url) => extractUrlString(url));
+    const egressFilter = new egress_1.EgressFilteringService(allowList);
     const missingUrls = requiredUrls.filter((requiredUrl) => {
-        const normalizedRequiredUrl = normalizeUrl(extractUrlString(requiredUrl));
-        const isUrlAlreadyGranted = currentlyGrantedUrls.some((currentGrantedUrl) => {
-            const normalizedGrantedUrl = normalizeUrl(extractUrlString(currentGrantedUrl));
-            return (0, minimatch_1.minimatch)(normalizedRequiredUrl, normalizedGrantedUrl);
-        });
-        return !isUrlAlreadyGranted;
+        const urlString = extractUrlString(requiredUrl);
+        if (useCSP) {
+            return !egressFilter.isValidUrlCSP(urlString);
+        }
+        return !egressFilter.isValidUrl(urlString);
     });
     return missingUrls;
 };
 const VALID_REQUIREMENT_KEYS = ['scopes', 'external'];
@@ -85,9 +81,9 @@
     Object.keys(requiredFetch).forEach((fetchType) => {
         const requiredUrls = requiredFetch[fetchType];
         if (!requiredUrls || !Array.isArray(requiredUrls) || requiredUrls.length === 0)
             return;
-        const missingUrls = getMissingUrls(requiredUrls, currentlyGrantedFetch?.[fetchType] ?? []);
+        const missingUrls = getMissingUrls(requiredUrls, currentlyGrantedFetch?.[fetchType] ?? [], fetchType === 'client');
         if (missingUrls.length) {
             missingFetch[fetchType] = missingUrls.map(extractUrlString);
         }
     });
@@ -109,9 +105,9 @@
         const externalUrls = requiredExternal[type];
         if (!externalUrls || !Array.isArray(externalUrls) || externalUrls.length === 0) {
             return;
         }
-        const missingUrls = getMissingUrls(externalUrls, currentGrantedExternal[type] || []);
+        const missingUrls = getMissingUrls(externalUrls, currentGrantedExternal[type] || [], true);
         if (missingUrls.length > 0) {
             if (!missingExternal) {
                 missingExternal = {};
             }