npm package diff

Package: @forge/csp

Versions: 4.2.0-experimental-959d7b9 - 4.2.0-experimental-a6c1d53

Modified: package/out/csp/csp-injection-service.js

Index: package/out/csp/csp-injection-service.js
===================================================================
--- package/out/csp/csp-injection-service.js
+++ package/out/csp/csp-injection-service.js
@@ -2,9 +2,15 @@
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.CSPInjectionService = exports.EXTERNAL_ALLOW_LISTED_IMAGES_HOSTS = exports.getAtlassianImageHost = void 0;
 const types_1 = require("../types");
 const isICEnvKey = (env) => env === 'ic-prod' || env === 'ic-stg';
-const getICDomain = (env, icLabel) => `${icLabel}.${env === 'ic-prod' ? 'atlassian-isolated.net' : 'oasis-stg.com'}`;
+const makeICDomain = (env, icLabel) => `${icLabel}.${env === 'ic-prod' ? 'atlassian-isolated.net' : 'oasis-stg.com'}`;
+const getICDomain = (env, icOptions) => {
+    if ('getICDomain' in icOptions) {
+        return icOptions.getICDomain();
+    }
+    return makeICDomain(env, icOptions.icLabel);
+};
 const makeICHosts = (targetHostFunction) => {
     return {
         'ic-stg': (icOptions) => targetHostFunction('ic-stg', icOptions),
         'ic-prod': (icOptions) => targetHostFunction('ic-prod', icOptions)
@@ -16,17 +22,17 @@
         stg: 'https://api.stg.atlassian.com',
         prod: 'https://api.atlassian.com',
         'fedramp-stg': 'https://api.stg.atlassian-us-gov-mod.com',
         'fedramp-prod': 'https://api.atlassian-us-gov-mod.com',
-        ...makeICHosts((env, { icLabel }) => `https://api.${getICDomain(env, icLabel)}`)
+        ...makeICHosts((env, icOptions) => `https://api.${getICDomain(env, icOptions)}`)
     },
     ATLASSIAN_MEDIA_GATEWAY_HOST: {
         dev: 'https://media.dev.atl-paas.net',
         stg: 'https://media.staging.atl-paas.net',
         prod: 'https://api.media.atlassian.com',
         'fedramp-stg': 'https://api-media.stg.atlassian-us-gov-mod.com',
         'fedramp-prod': 'https://api-media.atlassian-us-gov-mod.com',
-        ...makeICHosts((env, { icLabel }) => `https://media-api.${getICDomain(env, icLabel)}`)
+        ...makeICHosts((env, icOptions) => `https://media-api.${getICDomain(env, icOptions)}`)
     },
     ATLASSIAN_AVATAR_HOST: {
         dev: 'avatar-management--avatars.us-west-2.staging.public.atl-paas.net',
         stg: 'avatar-management--avatars.us-west-2.staging.public.atl-paas.net',
@@ -41,25 +47,25 @@
         stg: 'https://ptc-directory-sited-static.us-east-1.staging.public.atl-paas.net/gradients/',
         prod: 'https://ptc-directory-sited-static.us-east-1.prod.public.atl-paas.net/gradients/',
         'fedramp-stg': 'https://teams-directory-frontend.frontend.cdn.atlassian-us-gov-mod.com/assets/',
         'fedramp-prod': 'https://teams-directory-frontend.frontend.cdn.atlassian-us-gov-mod.com/assets/',
-        ...makeICHosts((env, { icLabel }) => `https://teams-directory-frontend.services.${getICDomain(env, icLabel)}/bfa/`)
+        ...makeICHosts((env, icOptions) => `https://teams-directory-frontend.services.${getICDomain(env, icOptions)}/bfa/`)
     },
     ATLASSIAN_TEAM_AVATAR_HOST: {
         dev: 'https://teams-directory-frontend.stg-east.frontend.public.atl-paas.net/assets/',
         stg: 'https://teams-directory-frontend.stg-east.frontend.public.atl-paas.net/assets/',
         prod: 'https://teams-directory-frontend.prod-east.frontend.public.atl-paas.net/assets/',
         'fedramp-stg': 'https://teams-directory-frontend.frontend.cdn.atlassian-us-gov-mod.com/assets/',
         'fedramp-prod': 'https://teams-directory-frontend.frontend.cdn.atlassian-us-gov-mod.com/assets/',
-        ...makeICHosts((env, { icLabel }) => `https://teams-directory-frontend.services.${getICDomain(env, icLabel)}/bfa/`)
+        ...makeICHosts((env, icOptions) => `https://teams-directory-frontend.services.${getICDomain(env, icOptions)}/bfa/`)
     },
     ATLASSIAN_EMOJIS_HOST: {
         dev: 'https://pf-emoji-service--cdn.ap-southeast-2.dev.public.atl-paas.net',
         stg: 'https://pf-emoji-service--cdn.us-east-1.staging.public.atl-paas.net',
         prod: 'https://pf-emoji-service--cdn.us-east-1.prod.public.atl-paas.net',
         'fedramp-stg': 'https://pf-emoji-service--cdn.us-east-1.staging.cdn.atlassian-us-gov-mod.com',
         'fedramp-prod': 'https://pf-emoji-service--cdn.us-east-1.prod.cdn.atlassian-us-gov-mod.com',
-        ...makeICHosts((env, { icLabel }) => `https://pf-emoji-service.${getICDomain(env, icLabel)}`)
+        ...makeICHosts((env, icOptions) => `https://pf-emoji-service.${getICDomain(env, icOptions)}`)
     }
 };
 const getAtlassianHost = (hostType, microsEnv, icOptions) => {
     const hostMap = ATLASSIAN_HOST[hostType];
@@ -84,30 +90,92 @@
 };
 exports.getAtlassianImageHost = getAtlassianImageHost;
 exports.EXTERNAL_ALLOW_LISTED_IMAGES_HOSTS = ['https://secure.gravatar.com', 'https://images.unsplash.com'];
 class CSPInjectionService {
+    constructor() {
+        this.getInjectableCSP = ({ existingCSPDetails, microsEnv, tunnelCSPReporterUri, hostname, isFedRAMP, icOptions }) => {
+            const reportUri = tunnelCSPReporterUri || this.getCSPReportUri(microsEnv, icOptions);
+            const defaultSrc = `'self'`;
+            const frameAncestors = ["'self'", ...this.getFrameAncestors(microsEnv, hostname, icOptions)].join(' ');
+            const frameSrc = ["'self'", hostname, ...this.getExistingCSPDetails(types_1.ExternalCspType.FRAME_SRC, existingCSPDetails)]
+                .filter((a) => a)
+                .join(' ');
+            const fontSrc = ["'self'", ...this.getExistingCSPDetails(types_1.ExternalCspType.FONT_SRC, existingCSPDetails)].join(' ');
+            const imgSrc = [
+                "'self'",
+                'data:',
+                'blob:',
+                hostname,
+                ...exports.EXTERNAL_ALLOW_LISTED_IMAGES_HOSTS,
+                ...(0, exports.getAtlassianImageHost)(microsEnv, icOptions),
+                ...this.getExistingCSPDetails(types_1.ExternalCspType.IMG_SRC, existingCSPDetails)
+            ]
+                .filter((a) => a)
+                .join(' ');
+            const mediaSrc = [
+                "'self'",
+                'data:',
+                'blob:',
+                hostname,
+                getAtlassianHost('ATLASSIAN_MEDIA_GATEWAY_HOST', microsEnv, icOptions),
+                ...this.getExistingCSPDetails(types_1.ExternalCspType.MEDIA_SRC, existingCSPDetails)
+            ]
+                .filter((a) => a)
+                .join(' ');
+            const connectSrc = [
+                "'self'",
+                ...this.getConnectSrc(microsEnv, !!tunnelCSPReporterUri, icOptions),
+                ...this.getExistingCSPDetails(types_1.ExternalCspType.CONNECT_SRC, existingCSPDetails)
+            ].join(' ');
+            const scriptSrc = [
+                "'self'",
+                this.getForgeGlobalCSP(microsEnv, isFedRAMP, icOptions),
+                ...this.getExistingCSPDetails(types_1.ExternalCspType.SCRIPT_SRC, existingCSPDetails)
+            ].join(' ');
+            const styleSrc = [
+                "'self'",
+                this.getForgeGlobalCSP(microsEnv, isFedRAMP, icOptions),
+                ...this.getExistingCSPDetails(types_1.ExternalCspType.STYLE_SRC, existingCSPDetails)
+            ].join(' ');
+            return [
+                `default-src ${defaultSrc}`,
+                `frame-ancestors ${frameAncestors}`,
+                `frame-src ${frameSrc}`,
+                `font-src ${fontSrc}`,
+                `img-src ${imgSrc}`,
+                `media-src ${mediaSrc}`,
+                `connect-src ${connectSrc}`,
+                `script-src ${scriptSrc}`,
+                `style-src ${styleSrc}`,
+                `form-action 'self'`,
+                `sandbox allow-downloads allow-forms allow-modals allow-pointer-lock allow-same-origin allow-scripts`,
+                `report-uri ${reportUri}`
+            ];
+        };
+    }
     getCSPReportUri(microsEnv, icOptions) {
         const serviceName = isICEnvKey(microsEnv) && icOptions ? icOptions.serviceName : 'forge-cdn';
         if (microsEnv === 'dev' || microsEnv === 'stg')
             return `https://web-security-reports.stg.services.atlassian.com/csp-report/${serviceName}`;
         return `https://web-security-reports.services.atlassian.com/csp-report/${serviceName}`;
     }
     getForgeGlobalCSP(microsEnv, isFedRAMP = false, icOptions) {
         if (isICEnvKey(microsEnv) && icOptions) {
-            return `https://forge.forge-cdn.${getICDomain(microsEnv, icOptions.icLabel)}`;
+            return `https://forge.forge-cdn.${getICDomain(microsEnv, icOptions)}`;
         }
         return isFedRAMP
             ? `https://forge.cdn.${microsEnv.split('-')[1]}.atlassian-dev-us-gov-mod.net`
             : `https://forge.cdn.${microsEnv}.atlassian-dev.net`;
     }
     getMetalClientCSP(microsEnv, icOptions) {
         if (isICEnvKey(microsEnv) && icOptions) {
-            return `https://api.${getICDomain(microsEnv, icOptions.icLabel)}/metal/ingest`;
+            return `https://api.${getICDomain(microsEnv, icOptions)}/metal/ingest`;
         }
         return `https://api.${microsEnv === 'prod' ? '' : 'stg.'}atlassian.com/metal/ingest`;
     }
     getExistingCSPDetails(cspType, cspDetails) {
-        return cspDetails[cspType] ?? [];
+        var _a;
+        return (_a = cspDetails[cspType]) !== null && _a !== void 0 ? _a : [];
     }
     getConnectSrc(microsEnv, isTunnelling, icOptions) {
         const allowed = [];
         if (isTunnelling) {
@@ -141,9 +209,9 @@
                 break;
             case 'ic-stg':
             case 'ic-prod':
                 if (icOptions) {
-                    frameAncestors = [`*.${getICDomain(microsEnv, icOptions.icLabel)}`];
+                    frameAncestors = [`*.${getICDomain(microsEnv, icOptions)}`];
                 }
                 break;
             case 'prod':
             default:
@@ -160,65 +228,6 @@
             frameAncestors.push(hostname);
         }
         return frameAncestors;
     }
-    getInjectableCSP = ({ existingCSPDetails, microsEnv, tunnelCSPReporterUri, hostname, isFedRAMP, icOptions }) => {
-        const reportUri = tunnelCSPReporterUri || this.getCSPReportUri(microsEnv, icOptions);
-        const defaultSrc = `'self'`;
-        const frameAncestors = ["'self'", ...this.getFrameAncestors(microsEnv, hostname, icOptions)].join(' ');
-        const frameSrc = ["'self'", hostname, ...this.getExistingCSPDetails(types_1.ExternalCspType.FRAME_SRC, existingCSPDetails)]
-            .filter((a) => a)
-            .join(' ');
-        const fontSrc = ["'self'", ...this.getExistingCSPDetails(types_1.ExternalCspType.FONT_SRC, existingCSPDetails)].join(' ');
-        const imgSrc = [
-            "'self'",
-            'data:',
-            'blob:',
-            hostname,
-            ...exports.EXTERNAL_ALLOW_LISTED_IMAGES_HOSTS,
-            ...(0, exports.getAtlassianImageHost)(microsEnv, icOptions),
-            ...this.getExistingCSPDetails(types_1.ExternalCspType.IMG_SRC, existingCSPDetails)
-        ]
-            .filter((a) => a)
-            .join(' ');
-        const mediaSrc = [
-            "'self'",
-            'data:',
-            'blob:',
-            hostname,
-            getAtlassianHost('ATLASSIAN_MEDIA_GATEWAY_HOST', microsEnv, icOptions),
-            ...this.getExistingCSPDetails(types_1.ExternalCspType.MEDIA_SRC, existingCSPDetails)
-        ]
-            .filter((a) => a)
-            .join(' ');
-        const connectSrc = [
-            "'self'",
-            ...this.getConnectSrc(microsEnv, !!tunnelCSPReporterUri, icOptions),
-            ...this.getExistingCSPDetails(types_1.ExternalCspType.CONNECT_SRC, existingCSPDetails)
-        ].join(' ');
-        const scriptSrc = [
-            "'self'",
-            this.getForgeGlobalCSP(microsEnv, isFedRAMP, icOptions),
-            ...this.getExistingCSPDetails(types_1.ExternalCspType.SCRIPT_SRC, existingCSPDetails)
-        ].join(' ');
-        const styleSrc = [
-            "'self'",
-            this.getForgeGlobalCSP(microsEnv, isFedRAMP, icOptions),
-            ...this.getExistingCSPDetails(types_1.ExternalCspType.STYLE_SRC, existingCSPDetails)
-        ].join(' ');
-        return [
-            `default-src ${defaultSrc}`,
-            `frame-ancestors ${frameAncestors}`,
-            `frame-src ${frameSrc}`,
-            `font-src ${fontSrc}`,
-            `img-src ${imgSrc}`,
-            `media-src ${mediaSrc}`,
-            `connect-src ${connectSrc}`,
-            `script-src ${scriptSrc}`,
-            `style-src ${styleSrc}`,
-            `form-action 'self'`,
-            `sandbox allow-downloads allow-forms allow-modals allow-pointer-lock allow-same-origin allow-scripts`,
-            `report-uri ${reportUri}`
-        ];
-    };
 }
 exports.CSPInjectionService = CSPInjectionService;

Modified: package/out/csp/csp-processing-service.js

Index: package/out/csp/csp-processing-service.js
===================================================================
--- package/out/csp/csp-processing-service.js
+++ package/out/csp/csp-processing-service.js
@@ -11,24 +11,24 @@
     }
 }
 exports.InvalidConnectSrc = InvalidConnectSrc;
 class CSPProcessingService {
-    logger;
-    STYLE_SRC_ALLOWLIST = [`'unsafe-inline'`];
-    QUOTED_SCRIPT_SRC_ALLOWLIST = ['unsafe-inline', 'unsafe-eval', 'unsafe-hashes'];
-    UNQUOTED_SCRIPT_SRC_ALLOWLIST = ['blob:'];
-    SCRIPT_SRC_ALLOWLIST = [...this.QUOTED_SCRIPT_SRC_ALLOWLIST, ...this.UNQUOTED_SCRIPT_SRC_ALLOWLIST];
-    BASE_64_HASH_PATTERNS = [
-        /^sha256-[a-zA-Z0-9=+/]{44}$/,
-        /^sha384-[a-zA-Z0-9=+/]{64}$/,
-        /^sha512-[a-zA-Z0-9=+/]{88}$/
-    ];
     constructor(logger) {
         this.logger = logger;
+        this.STYLE_SRC_ALLOWLIST = [`'unsafe-inline'`];
+        this.QUOTED_SCRIPT_SRC_ALLOWLIST = ['unsafe-inline', 'unsafe-eval', 'unsafe-hashes'];
+        this.UNQUOTED_SCRIPT_SRC_ALLOWLIST = ['blob:'];
+        this.SCRIPT_SRC_ALLOWLIST = [...this.QUOTED_SCRIPT_SRC_ALLOWLIST, ...this.UNQUOTED_SCRIPT_SRC_ALLOWLIST];
+        this.BASE_64_HASH_PATTERNS = [
+            /^sha256-[a-zA-Z0-9=+/]{44}$/,
+            /^sha384-[a-zA-Z0-9=+/]{64}$/,
+            /^sha512-[a-zA-Z0-9=+/]{88}$/
+        ];
     }
     getCspDetails(body, permissions) {
-        const { scripts, styles } = permissions?.content ?? { scripts: [], styles: [] };
-        const external = permissions?.external ?? {};
+        var _a, _b;
+        const { scripts, styles } = (_a = permissions === null || permissions === void 0 ? void 0 : permissions.content) !== null && _a !== void 0 ? _a : { scripts: [], styles: [] };
+        const external = (_b = permissions === null || permissions === void 0 ? void 0 : permissions.external) !== null && _b !== void 0 ? _b : {};
         const $ = (0, cheerio_1.load)(body, { xml: { xmlMode: false } });
         const { 'script-src': scriptSrc, 'style-src': styleSrc, ...mappedExternalCsp } = this.mapExternalPermissionsToCsp(external);
         return {
             'style-src': [...this.getStyleSrc($, styles), ...styleSrc],
@@ -36,59 +36,64 @@
             ...mappedExternalCsp
         };
     }
     getInvalidCspPermissions(contentPermissions) {
+        var _a, _b;
         const { styles, scripts } = contentPermissions;
-        const invalidStyles = styles?.filter((styleSrc) => !this.isValidUserStyleSrc(`'${styleSrc}'`)) ?? [];
-        const invalidScripts = scripts?.filter((scriptSrc) => !this.isValidUserScriptSrc(scriptSrc)) ?? [];
+        const invalidStyles = (_a = styles === null || styles === void 0 ? void 0 : styles.filter((styleSrc) => !this.isValidUserStyleSrc(`'${styleSrc}'`))) !== null && _a !== void 0 ? _a : [];
+        const invalidScripts = (_b = scripts === null || scripts === void 0 ? void 0 : scripts.filter((scriptSrc) => !this.isValidUserScriptSrc(scriptSrc))) !== null && _b !== void 0 ? _b : [];
         return [...invalidStyles, ...invalidScripts];
     }
     assertValidFetchClient(fetch) {
-        if (fetch?.client) {
-            for (const client of fetch?.client) {
+        if (fetch === null || fetch === void 0 ? void 0 : fetch.client) {
+            for (const client of fetch === null || fetch === void 0 ? void 0 : fetch.client) {
                 if (typeof client !== 'string') {
                     throw new InvalidConnectSrc();
                 }
             }
         }
     }
     egressesToStringMap(externalPermissions) {
-        return externalPermissions?.map((egress) => (typeof egress === 'object' ? egress.address : egress));
+        return externalPermissions === null || externalPermissions === void 0 ? void 0 : externalPermissions.map((egress) => (typeof egress === 'object' ? egress.address : egress));
     }
     mapExternalPermissionsToCsp(externalPermissions) {
+        var _a, _b, _c, _d, _e, _f, _g;
         const { images, media, scripts, fetch, styles, fonts, frames } = externalPermissions;
         this.assertValidFetchClient(fetch);
         return {
-            'img-src': this.egressesToStringMap(images) ?? [],
-            'media-src': this.egressesToStringMap(media) ?? [],
-            'script-src': this.egressesToStringMap(scripts) ?? [],
-            'style-src': this.egressesToStringMap(styles) ?? [],
-            'connect-src': fetch?.client ?? [],
-            'font-src': this.egressesToStringMap(fonts) ?? [],
-            'frame-src': this.egressesToStringMap(frames) ?? []
+            'img-src': (_a = this.egressesToStringMap(images)) !== null && _a !== void 0 ? _a : [],
+            'media-src': (_b = this.egressesToStringMap(media)) !== null && _b !== void 0 ? _b : [],
+            'script-src': (_c = this.egressesToStringMap(scripts)) !== null && _c !== void 0 ? _c : [],
+            'style-src': (_d = this.egressesToStringMap(styles)) !== null && _d !== void 0 ? _d : [],
+            'connect-src': (_e = fetch === null || fetch === void 0 ? void 0 : fetch.client) !== null && _e !== void 0 ? _e : [],
+            'font-src': (_f = this.egressesToStringMap(fonts)) !== null && _f !== void 0 ? _f : [],
+            'frame-src': (_g = this.egressesToStringMap(frames)) !== null && _g !== void 0 ? _g : []
         };
     }
     getStyleSrc($, userStyleSrc) {
-        const quotedUserStyleSrc = userStyleSrc?.map((x) => `'${x}'`) ?? [];
-        const deprecatedUserStyleSrc = this.getDeprecatedUserCsp($)['style-src'] ?? [];
+        var _a, _b;
+        const quotedUserStyleSrc = (_a = userStyleSrc === null || userStyleSrc === void 0 ? void 0 : userStyleSrc.map((x) => `'${x}'`)) !== null && _a !== void 0 ? _a : [];
+        const deprecatedUserStyleSrc = (_b = this.getDeprecatedUserCsp($)['style-src']) !== null && _b !== void 0 ? _b : [];
         const uniqueStyleSrc = [...new Set([...deprecatedUserStyleSrc, ...quotedUserStyleSrc])];
         return uniqueStyleSrc.filter((x) => this.isValidUserStyleSrc(x));
     }
     getScriptSrc($, userScriptSrc) {
-        const validUserScriptSrc = userScriptSrc?.filter((x) => this.isValidUserScriptSrc(x)) ?? [];
+        var _a;
+        const validUserScriptSrc = (_a = userScriptSrc === null || userScriptSrc === void 0 ? void 0 : userScriptSrc.filter((x) => this.isValidUserScriptSrc(x))) !== null && _a !== void 0 ? _a : [];
         const generatedScriptHashes = validUserScriptSrc.includes('unsafe-inline') ? [] : this.getInlineScriptHashes($);
         const { scriptSrc, userScriptHashes } = this.extractUniqueHashes(validUserScriptSrc, generatedScriptHashes);
         return [...scriptSrc, ...generatedScriptHashes, ...userScriptHashes].map((x) => this.formatScriptSrc(x));
     }
     extractUniqueHashes(userScriptSrc, existingScriptHashes) {
+        var _a;
         const userScriptHashes = [];
-        const scriptSrc = userScriptSrc?.filter((scriptSrc) => {
+        const scriptSrc = (_a = userScriptSrc === null || userScriptSrc === void 0 ? void 0 : userScriptSrc.filter((scriptSrc) => {
             const isValidHash = this.isValidHash(scriptSrc);
             if (isValidHash && !existingScriptHashes.includes(scriptSrc)) {
                 userScriptHashes.push(scriptSrc);
             }
             return !isValidHash;
-        }) ?? [];
+        })) !== null && _a !== void 0 ? _a : [];
         return { scriptSrc, userScriptHashes };
     }
     getInlineScriptHashes($) {
         return $('script:not([src])')

Modified: package/package.json

Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@forge/csp",
-  "version": "4.2.0-experimental-959d7b9",
+  "version": "4.2.0-experimental-a6c1d53",
   "description": "Contains the CSP configuration for Custom UI resources in Forge",
   "main": "out/index.js",
   "author": "Atlassian",
   "license": "SEE LICENSE IN LICENSE.txt",

Modified: package/out/csp/csp-injection-service.d.ts.map

Index: package/out/csp/csp-injection-service.d.ts.map
===================================================================
--- package/out/csp/csp-injection-service.d.ts.map
+++ package/out/csp/csp-injection-service.d.ts.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"csp-injection-service.d.ts","sourceRoot":"","sources":["../../src/csp/csp-injection-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAC;AAEvD,aAAK,SAAS,GAAG;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAiGF,eAAO,MAAM,qBAAqB,cAAe,iBAAiB,cAAc,SAAS,KAAG,MAAM,EAUjG,CAAC;AAMF,eAAO,MAAM,kCAAkC,UAAiE,CAAC;AAEjH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,iBAAiB;IAiDlB,gBAAgB;4BAQD,UAAU;mBACnB,iBAAiB;;;;;UAK1B,MAAM,EAAE,CA8DV;CACH"}
\ No newline at end of file
+{"version":3,"file":"csp-injection-service.d.ts","sourceRoot":"","sources":["../../src/csp/csp-injection-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAC;AAEvD,aAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAIF,aAAK,oBAAoB,GAAG;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,MAAM,CAAC;CAC3B,CAAC;AAEF,aAAK,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAyG1D,eAAO,MAAM,qBAAqB,cAAe,iBAAiB,cAAc,SAAS,KAAG,MAAM,EAUjG,CAAC;AAMF,eAAO,MAAM,kCAAkC,UAAiE,CAAC;AAEjH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,iBAAiB;IAiDlB,gBAAgB;4BAQD,UAAU;mBACnB,iBAAiB;;;;;UAK1B,MAAM,EAAE,CA8DV;CACH"}
\ No newline at end of file

Modified: package/CHANGELOG.md

Index: package/CHANGELOG.md
===================================================================
--- package/CHANGELOG.md
+++ package/CHANGELOG.md
@@ -1,11 +1,12 @@
 # @forge/csp
 
-## 4.2.0-experimental-959d7b9
+## 4.2.0-experimental-a6c1d53
 
 ### Patch Changes
 
 - aebd633: Patch @forge/csp IC frame ancestors csp bug
+- abf0bb1: Add support for custom getICDomain option in CSPInjectionService
 
 ## 4.2.0
 
 ### Minor Changes

Modified: package/out/csp/csp-injection-service.d.ts

Index: package/out/csp/csp-injection-service.d.ts
===================================================================
--- package/out/csp/csp-injection-service.d.ts
+++ package/out/csp/csp-injection-service.d.ts
@@ -1,10 +1,15 @@
 import type { LambdaEnvironment } from '@forge/cli-shared';
 import { CSPDetails } from '../types';
-declare type IcOptions = {
+declare type StandardIcOptions = {
     icLabel: string;
     serviceName: string;
 };
+declare type GetICDomainIcOptions = {
+    serviceName?: string;
+    getICDomain: () => string;
+};
+declare type IcOptions = StandardIcOptions | GetICDomainIcOptions;
 export declare const getAtlassianImageHost: (microsEnv: LambdaEnvironment, icOptions?: IcOptions) => string[];
 export declare const EXTERNAL_ALLOW_LISTED_IMAGES_HOSTS: string[];
 export declare class CSPInjectionService {
     private getCSPReportUri;