From bf7ba36fecc532270eafe784fab3fb394b9ca6b4 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Mon, 13 Apr 2026 23:11:01 +0200 Subject: [PATCH 01/17] Build a license map once --- src/utils/get-cipp-license-translation.js | 34 ++++++++++++++--------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/utils/get-cipp-license-translation.js b/src/utils/get-cipp-license-translation.js index 0397585d927a..321379fc6785 100644 --- a/src/utils/get-cipp-license-translation.js +++ b/src/utils/get-cipp-license-translation.js @@ -3,9 +3,18 @@ import M365LicensesAdditional from "../data/M365Licenses-additional.json"; import { getCachedLicense } from "./cipp-license-cache"; import licenseBackfillManager from "./cipp-license-backfill-manager"; +// Create a Map for O(1) lookups of GUID to Product_Display_Name +const licenseByGuid = new Map(); +[...M365LicensesDefault, ...M365LicensesAdditional].forEach((entry) => { + if (entry.GUID) { + const key = entry.GUID.toLowerCase(); + if (!licenseByGuid.has(key)) { + licenseByGuid.set(key, entry.Product_Display_Name); + } + } +}); + export const getCippLicenseTranslation = (licenseArray) => { - //combine M365LicensesDefault and M365LicensesAdditional to one array - const M365Licenses = [...M365LicensesDefault, ...M365LicensesAdditional]; let licenses = []; let missingSkuIds = []; @@ -24,17 +33,16 @@ export const getCippLicenseTranslation = (licenseArray) => { licenseArray?.forEach((licenseAssignment) => { let found = false; - // First, check static JSON files - for (let x = 0; x < M365Licenses.length; x++) { - if (licenseAssignment.skuId === M365Licenses[x].GUID) { - licenses.push( - M365Licenses[x].Product_Display_Name - ? M365Licenses[x].Product_Display_Name - : licenseAssignment.skuPartNumber, - ); - found = true; - break; - } + // First, check static JSON map (O(1) lookup) + const skuLower = licenseAssignment.skuId?.toLowerCase(); + const displayName = skuLower ? licenseByGuid.get(skuLower) : undefined; + if (displayName) { + licenses.push(displayName); + found = true; + } else if (skuLower && licenseByGuid.has(skuLower)) { + // Entry exists but Product_Display_Name is falsy — fall back to skuPartNumber + licenses.push(licenseAssignment.skuPartNumber || licenseAssignment.skuId); + found = true; } // Second, check dynamic cache From 69172aa1aafdcb06140a67a23e6250c53704c24a Mon Sep 17 00:00:00 2001 From: Zacgoose <107489668+Zacgoose@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:25:58 +0800 Subject: [PATCH 02/17] Normalize API function description handling add validation to app manifest templates --- .vscode/launch.json | 7 + .../AppApprovalTemplateForm.jsx | 145 +++++++++++++++--- .../CippAppApprovalTemplateDrawer.jsx | 2 +- .../CippSettings/CippPermissionCheck.jsx | 13 +- .../CippSettings/CippRoleAddEdit.jsx | 24 ++- src/utils/get-cipp-error.js | 2 +- 6 files changed, 170 insertions(+), 23 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 647f3571b4c2..3622dc676b7c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -35,6 +35,13 @@ "cwd": "${cwd}", "script": ". '${cwd}\\Tools\\Start-CIPPDevEmulators.ps1'" }, + { + "type": "PowerShell", + "name": "Launch in Windows Terminal with Offloading Proc and HTTP only workers", + "request": "launch", + "cwd": "${cwd}", + "script": ". '${cwd}\\Tools\\Start-CippOffloadSimulation.ps1'" + }, { "type": "PowerShell", "name": "Launch in Kitty Terminal", diff --git a/src/components/CippComponents/AppApprovalTemplateForm.jsx b/src/components/CippComponents/AppApprovalTemplateForm.jsx index e58add0e6945..20db0c4c48cd 100644 --- a/src/components/CippComponents/AppApprovalTemplateForm.jsx +++ b/src/components/CippComponents/AppApprovalTemplateForm.jsx @@ -19,9 +19,76 @@ const AppApprovalTemplateForm = ({ refetchKey, hideSubmitButton = false, // New prop to hide the submit button when used in a drawer }) => { + const forbiddenManifestProperties = ["keyCredentials", "passwordCredentials"]; const [selectedPermissionSet, setSelectedPermissionSet] = useState(null); const [permissionsLoaded, setPermissionsLoaded] = useState(false); const [permissionSetDrawerVisible, setPermissionSetDrawerVisible] = useState(false); + const [manifestSanitizeMessage, setManifestSanitizeMessage] = useState(null); + + const getManifestValidationError = (manifest) => { + if (!manifest.displayName) { + return "Application manifest must include a 'displayName' property"; + } + + if (manifest.signInAudience && manifest.signInAudience !== "AzureADMyOrg") { + return "signInAudience must be null, undefined, or 'AzureADMyOrg' for security reasons"; + } + + const presentForbiddenProperties = forbiddenManifestProperties.filter( + (propertyName) => Object.prototype.hasOwnProperty.call(manifest, propertyName) + ); + if (presentForbiddenProperties.length > 0) { + return `Remove unsupported manifest properties: ${presentForbiddenProperties.join(", ")}.`; + } + + return null; + }; + + const handleSanitizeManifest = () => { + const currentManifest = formControl.getValues("applicationManifest"); + + if (!currentManifest) { + setManifestSanitizeMessage({ + severity: "warning", + text: "Paste a manifest first, then use cleanup.", + }); + return; + } + + try { + const parsedManifest = JSON.parse(currentManifest); + const removedProperties = forbiddenManifestProperties.filter((propertyName) => + Object.prototype.hasOwnProperty.call(parsedManifest, propertyName) + ); + + if (removedProperties.length === 0) { + setManifestSanitizeMessage({ + severity: "info", + text: "No forbidden sections found. Your manifest is already clean.", + }); + return; + } + + removedProperties.forEach((propertyName) => { + delete parsedManifest[propertyName]; + }); + + formControl.setValue("applicationManifest", JSON.stringify(parsedManifest, null, 2), { + shouldDirty: true, + shouldValidate: true, + }); + + setManifestSanitizeMessage({ + severity: "success", + text: `Removed forbidden sections: ${removedProperties.join(", ")}.`, + }); + } catch (error) { + setManifestSanitizeMessage({ + severity: "error", + text: "Manifest JSON is invalid. Fix the JSON and try cleanup again.", + }); + } + }; // Watch for app type selection changes const selectedAppType = useWatch({ @@ -40,6 +107,28 @@ const AppApprovalTemplateForm = ({ name: "applicationManifest", }); + const getForbiddenManifestPropertiesPresent = (manifestValue) => { + if (!manifestValue) { + return []; + } + + try { + const manifest = JSON.parse(manifestValue); + return forbiddenManifestProperties.filter((propertyName) => + Object.prototype.hasOwnProperty.call(manifest, propertyName) + ); + } catch { + return []; + } + }; + + const forbiddenPropertiesInCurrentManifest = + selectedAppType === "ApplicationManifest" + ? getForbiddenManifestPropertiesPresent(selectedApplicationManifest) + : []; + const showSanitizeManifestButton = forbiddenPropertiesInCurrentManifest.length > 0; + const isTemplateFormValid = formControl?.formState?.isValid ?? false; + // Watch for app selection changes to update template name const selectedApp = useWatch({ control: formControl?.control, @@ -236,6 +325,22 @@ const AppApprovalTemplateForm = ({ } }, [isEditing, isCopy, templateData]); + useEffect(() => { + if (!formControl) { + return; + } + + formControl.trigger(); + }, [ + formControl, + selectedAppType, + selectedApplicationManifest, + selectedApp, + selectedGalleryTemplate, + selectedPermissionSetValue, + templateData, + ]); + // Handle form submission const handleSubmit = (data) => { let appDisplayName, appId, galleryTemplateId, applicationManifest; @@ -249,11 +354,12 @@ const AppApprovalTemplateForm = ({ try { applicationManifest = JSON.parse(data.applicationManifest); - // Validate signInAudience - only allow null/undefined or "AzureADMyOrg" - if ( - applicationManifest.signInAudience && - applicationManifest.signInAudience !== "AzureADMyOrg" - ) { + const manifestValidationError = getManifestValidationError(applicationManifest); + if (manifestValidationError) { + setManifestSanitizeMessage({ + severity: "error", + text: manifestValidationError, + }); return; // Don't submit if validation fails } @@ -481,24 +587,27 @@ const AppApprovalTemplateForm = ({ validate: (value) => { try { const manifest = JSON.parse(value); - - // Check for minimum required property - if (!manifest.displayName) { - return "Application manifest must include a 'displayName' property"; - } - - // Validate signInAudience if present - if (manifest.signInAudience && manifest.signInAudience !== "AzureADMyOrg") { - return "signInAudience must be null, undefined, or 'AzureADMyOrg' for security reasons"; - } - - return true; + return getManifestValidationError(manifest) ?? true; } catch (e) { return "Invalid JSON format"; } }, }} /> + + {showSanitizeManifestButton && ( + + + + )} + {manifestSanitizeMessage && ( + + {manifestSanitizeMessage.text} + + )} + {isEditing ? "Update Template" : "Create Template"} diff --git a/src/components/CippComponents/CippAppApprovalTemplateDrawer.jsx b/src/components/CippComponents/CippAppApprovalTemplateDrawer.jsx index 95526d194495..5315e080eb5a 100644 --- a/src/components/CippComponents/CippAppApprovalTemplateDrawer.jsx +++ b/src/components/CippComponents/CippAppApprovalTemplateDrawer.jsx @@ -144,7 +144,7 @@ export const CippAppApprovalTemplateDrawer = ({ variant="contained" color="primary" onClick={formControl.handleSubmit(handleSubmit)} - disabled={updatePermissions.isPending} + disabled={updatePermissions.isPending || !formControl.formState.isValid} > {updatePermissions.isPending ? isEditMode diff --git a/src/components/CippSettings/CippPermissionCheck.jsx b/src/components/CippSettings/CippPermissionCheck.jsx index 575f95cae5e1..ea5e20b8acc9 100644 --- a/src/components/CippSettings/CippPermissionCheck.jsx +++ b/src/components/CippSettings/CippPermissionCheck.jsx @@ -112,6 +112,17 @@ const CippPermissionCheck = (props) => { ); }; + const responseData = executeCheck?.error?.response?.data; + const responseText = + typeof responseData === "string" ? responseData : responseData ? JSON.stringify(responseData) : ""; + const shouldShowApiResponse = responseText.includes( + "Access to this CIPP API endpoint is not allowed", + ); + const checkErrorMessage = + shouldShowApiResponse + ? responseText + : `Failed to load ${type} check. Please try refreshing the page.`; + return ( <> { > {executeCheck.isError && !importReport && ( - Failed to load {type} check. Please try refreshing the page. + {checkErrorMessage} )} {(executeCheck.isSuccess || executeCheck.isLoading) && ( diff --git a/src/components/CippSettings/CippRoleAddEdit.jsx b/src/components/CippSettings/CippRoleAddEdit.jsx index 4c02bf71e673..757215cd0f49 100644 --- a/src/components/CippSettings/CippRoleAddEdit.jsx +++ b/src/components/CippSettings/CippRoleAddEdit.jsx @@ -103,6 +103,24 @@ export const CippRoleAddEdit = ({ selectedRole }) => { return regex.test(value); }; + const getFunctionDescriptionText = (description) => { + if (!description) return null; + + if (Array.isArray(description)) { + return description?.[0]?.Text || description?.[0]?.text || null; + } + + if (typeof description === "string") { + return description; + } + + if (typeof description === "object") { + return description?.Text || description?.text || null; + } + + return null; + }; + const getBaseRolePermissions = (role) => { const roleConfig = cippRoles[role]; if (!roleConfig) return {}; @@ -434,7 +452,7 @@ export const CippRoleAddEdit = ({ selectedRole }) => { const apiFunction = apiPermissions[cat][obj][type][api]; items.push({ name: apiFunction.Name, - description: apiFunction.Description?.[0]?.Text || null, + description: getFunctionDescriptionText(apiFunction.Description), }); } return ( @@ -593,7 +611,9 @@ export const CippRoleAddEdit = ({ selectedRole }) => { Object.keys(apiPermissions[cat][obj][type]).forEach( (apiKey) => { const apiFunction = apiPermissions[cat][obj][type][apiKey]; - const descriptionText = apiFunction.Description?.[0]?.Text; + const descriptionText = getFunctionDescriptionText( + apiFunction.Description + ); allEndpoints.push({ label: descriptionText ? `${apiFunction.Name} - ${descriptionText}` diff --git a/src/utils/get-cipp-error.js b/src/utils/get-cipp-error.js index 4b38df2af676..105ced73caf2 100644 --- a/src/utils/get-cipp-error.js +++ b/src/utils/get-cipp-error.js @@ -16,7 +16,7 @@ export const getCippError = (data) => { if (data.response?.data?.Results) { return data.response.data.Results; } - + if (data.response?.data) { return data.response.data; } From 3b7ad085d6268d3d42f99ac897d7067bcbd7c8c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:44:11 +0000 Subject: [PATCH 03/17] chore(deps): bump react-virtuoso from 4.18.3 to 4.18.5 Bumps [react-virtuoso](https://github.com/petyosi/react-virtuoso/tree/HEAD/packages/react-virtuoso) from 4.18.3 to 4.18.5. - [Release notes](https://github.com/petyosi/react-virtuoso/releases) - [Changelog](https://github.com/petyosi/react-virtuoso/blob/master/packages/react-virtuoso/CHANGELOG.md) - [Commits](https://github.com/petyosi/react-virtuoso/commits/react-virtuoso@4.18.5/packages/react-virtuoso) --- updated-dependencies: - dependency-name: react-virtuoso dependency-version: 4.18.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 35da2539bbdb..de3e62aacbe5 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "react-redux": "9.2.0", "react-syntax-highlighter": "^16.1.0", "react-time-ago": "^7.3.3", - "react-virtuoso": "^4.18.3", + "react-virtuoso": "^4.18.5", "react-window": "^2.2.7", "recharts": "^3.7.0", "redux": "5.0.1", diff --git a/yarn.lock b/yarn.lock index 052eb57111f7..ec2d2cfe536b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7130,10 +7130,10 @@ react-virtualized-auto-sizer@^1.0.26: resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.26.tgz#e9470ef6a778dc4f1d5fd76305fa2d8b610c357a" integrity sha512-CblNyiNVw2o+hsa5/49NH2ogGxZ+t+3aweRvNSq7TVjDIlwk7ir4lencEg5HxHeSzwNarSkNkiu0qJSOXtxm5A== -react-virtuoso@^4.18.3: - version "4.18.3" - resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.18.3.tgz#12e69600c258bc6e6bd31c2516942ef08700deac" - integrity sha512-fLz/peHAx4Eu0DLHurFEEI7Y6n5CqEoxBh04rgJM9yMuOJah2a9zWg/MUOmZLcp7zuWYorXq5+5bf3IRgkNvWg== +react-virtuoso@^4.18.5: + version "4.18.5" + resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.18.5.tgz#450108e585c7a1124b995c7ea3cf367ed4857631" + integrity sha512-QDyNjyNEuurZG67SOmzYyxEkQYSyGmAMixOI6M15L/Q4CF39EgG+88y6DgZRo0q7rmy0HPx3Fj90I8/tPdnRCQ== react-window@^2.2.7: version "2.2.7" From e3529a6c3dfdd3b90be8128cf7595c7ee20d7348 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:44:28 +0000 Subject: [PATCH 04/17] chore(deps): bump @tiptap/react from 3.20.4 to 3.20.5 Bumps [@tiptap/react](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/react) from 3.20.4 to 3.20.5. - [Release notes](https://github.com/ueberdosis/tiptap/releases) - [Changelog](https://github.com/ueberdosis/tiptap/blob/main/packages/react/CHANGELOG.md) - [Commits](https://github.com/ueberdosis/tiptap/commits/v3.20.5/packages/react) --- updated-dependencies: - dependency-name: "@tiptap/react" dependency-version: 3.20.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 35da2539bbdb..e0cea990c819 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@tiptap/extension-image": "^3.20.5", "@tiptap/extension-table": "^3.19.0", "@tiptap/pm": "^3.22.3", - "@tiptap/react": "^3.4.1", + "@tiptap/react": "^3.20.5", "@tiptap/starter-kit": "^3.20.5", "@uiw/react-json-view": "^2.0.0-alpha.41", "@vvo/tzdb": "^6.198.0", diff --git a/yarn.lock b/yarn.lock index 052eb57111f7..81dc3170d087 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2147,10 +2147,10 @@ resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-3.20.5.tgz#b40e8e43db3123c5dee9864931f7f9ad1b1e07dc" integrity sha512-hraiiWkF58n8Jy0Wl3OGwjCTrGWwZZxez/IlexrzKQ/nMFdjDpensZucWwu59zhAM9fqZwGSLDtCFuak03WKnA== -"@tiptap/extension-bubble-menu@^3.20.4": - version "3.20.4" - resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.20.4.tgz#e7e3c033a74d5dc67b1dac84346ee12e07d81b86" - integrity sha512-EXywPlI8wjPcAb8ozymgVhjtMjFrnhtoyNTy8ZcObdpUi5CdO9j892Y7aPbKe5hLhlDpvJk7rMfir4FFKEmfng== +"@tiptap/extension-bubble-menu@^3.20.5": + version "3.22.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.22.3.tgz#f94a3ac119b8576d040dc458d44b4200ad03e27b" + integrity sha512-Y6zQjh0ypDg32HWgICEvmPSKjGLr39k3aDxxt/H0uQEZSfw4smT0hxUyyyjVjx68C6t6MTnwdfz0hPI5lL68vQ== dependencies: "@floating-ui/dom" "^1.0.0" @@ -2179,10 +2179,10 @@ resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-3.20.5.tgz#ea810297825b009c357559e66f5fd76e91e8c940" integrity sha512-/lDG9OjvAv0ynmgFH17mt/GUeGT5bqu0iPW8JMgaRqlKawk+uUIv5SF5WkXS4SwxXih+hXdPEQD3PWZnxlQxAQ== -"@tiptap/extension-floating-menu@^3.20.4": - version "3.20.4" - resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-3.20.4.tgz#5b082cf500330f0a66f91a49c3a1a232038662a7" - integrity sha512-AaPTFhoO8DBIElJyd/RTVJjkctvJuL+GHURX0npbtTxXq5HXbebVwf2ARNR7jMd/GThsmBaNJiGxZg4A2oeDqQ== +"@tiptap/extension-floating-menu@^3.20.5": + version "3.22.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-3.22.3.tgz#c9a911b7784cb45d6f8e7260d77bf2015066e5a4" + integrity sha512-0f8b4KZ3XKai8GXWseIYJGdOfQr3evtFbBo3U08zy2aYzMMXWG0zEF7qe5/oiYp2aZ95edjjITnEceviTsZkIg== "@tiptap/extension-gapcursor@^3.20.5": version "3.20.5" @@ -2295,17 +2295,17 @@ prosemirror-transform "^1.10.2" prosemirror-view "^1.38.1" -"@tiptap/react@^3.4.1": - version "3.20.4" - resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-3.20.4.tgz#b313ff5051e30de4476138e47802a67bfda8ca2e" - integrity sha512-1B8iWsHWwb5TeyVaUs8BRPzwWo4PsLQcl03urHaz0zTJ8DauopqvxzV3+lem1OkzRHn7wnrapDvwmIGoROCaQw== +"@tiptap/react@^3.20.5": + version "3.20.5" + resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-3.20.5.tgz#6b2bd999470d9037fd9741ba598c9b3dc12f7759" + integrity sha512-in37o1Eo7JCflcHyK/SDfgkJBgX0LRN3LMk+NdLPTerRnC0zhGLQlpfBL4591TLTOUQde7QIrLv98smYO2mj+w== dependencies: "@types/use-sync-external-store" "^0.0.6" fast-equals "^5.3.3" use-sync-external-store "^1.4.0" optionalDependencies: - "@tiptap/extension-bubble-menu" "^3.20.4" - "@tiptap/extension-floating-menu" "^3.20.4" + "@tiptap/extension-bubble-menu" "^3.20.5" + "@tiptap/extension-floating-menu" "^3.20.5" "@tiptap/starter-kit@^3.20.5": version "3.20.5" From 9f68bf09d1795ce3965c3604b4e19767eef7f325 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:44:44 +0000 Subject: [PATCH 05/17] chore(deps): bump axios from 1.14.0 to 1.15.0 Bumps [axios](https://github.com/axios/axios) from 1.14.0 to 1.15.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.14.0...v1.15.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 35da2539bbdb..d3437e124bad 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@uiw/react-json-view": "^2.0.0-alpha.41", "@vvo/tzdb": "^6.198.0", "apexcharts": "5.10.4", - "axios": "1.14.0", + "axios": "1.15.0", "date-fns": "4.1.0", "diff": "^8.0.3", "eml-parse-js": "^1.2.0-beta.0", diff --git a/yarn.lock b/yarn.lock index 052eb57111f7..e6d9782a43a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3041,10 +3041,10 @@ axe-core@^4.10.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.1.tgz#052ff9b2cbf543f5595028b583e4763b40c78ea7" integrity sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A== -axios@1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.14.0.tgz#7c29f4cf2ea91ef05018d5aa5399bf23ed3120eb" - integrity sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ== +axios@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.15.0.tgz#0fcee91ef03d386514474904b27863b2c683bf4f" + integrity sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q== dependencies: follow-redirects "^1.15.11" form-data "^4.0.5" From 17183631108d2c9a3c97fb538047c6ed85e4ab00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:44:54 +0000 Subject: [PATCH 06/17] chore(deps): bump @mui/x-date-pickers from 8.27.2 to 9.0.2 Bumps [@mui/x-date-pickers](https://github.com/mui/mui-x/tree/HEAD/packages/x-date-pickers) from 8.27.2 to 9.0.2. - [Release notes](https://github.com/mui/mui-x/releases) - [Changelog](https://github.com/mui/mui-x/blob/master/CHANGELOG.md) - [Commits](https://github.com/mui/mui-x/commits/v9.0.2/packages/x-date-pickers) --- updated-dependencies: - dependency-name: "@mui/x-date-pickers" dependency-version: 9.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 52 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 35da2539bbdb..a9beba99fde7 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@mui/lab": "7.0.0-beta.17", "@mui/material": "7.3.7", "@mui/system": "7.3.2", - "@mui/x-date-pickers": "^8.27.2", + "@mui/x-date-pickers": "^9.0.2", "@musement/iso-duration": "^1.0.0", "@nivo/core": "^0.99.0", "@nivo/sankey": "^0.99.0", diff --git a/yarn.lock b/yarn.lock index 052eb57111f7..977fffa6f8d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1466,7 +1466,26 @@ dependencies: "@babel/runtime" "^7.28.6" -"@mui/utils@^7.3.2", "@mui/utils@^7.3.5", "@mui/utils@^7.3.7", "@mui/utils@^7.3.9": +"@mui/types@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-9.0.0.tgz#92d8c64e72cb863ee59108cb20cc476d648a3ab9" + integrity sha512-i1cuFCAWN44b3AJWO7mh7tuh1sqbQSeVr/94oG0TX5uXivac8XalgE4/6fQZcmGZigzbQ35IXxj/4jLpRIBYZg== + dependencies: + "@babel/runtime" "^7.29.2" + +"@mui/utils@9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-9.0.0.tgz#25b563ccbf537feba5f89c37a00cb8e6eea45ad0" + integrity sha512-bQcqyg/gjULUqTuyUjSAFr6LQGLvtkNtDbJerAtoUn9kGZ0hg5QJiN1PLHMLbeFpe3te1831uq7GFl2ITokGdg== + dependencies: + "@babel/runtime" "^7.29.2" + "@mui/types" "^9.0.0" + "@types/prop-types" "^15.7.15" + clsx "^2.1.1" + prop-types "^15.8.1" + react-is "^19.2.4" + +"@mui/utils@^7.3.2", "@mui/utils@^7.3.7", "@mui/utils@^7.3.9": version "7.3.9" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.3.9.tgz#8af5093fc93c2e582fa3d047f561c7b690509bc2" integrity sha512-U6SdZaGbfb65fqTsH3V5oJdFj9uYwyLE2WVuNvmbggTSDBb8QHrFsqY8BN3taK9t3yJ8/BPHD/kNvLNyjwM7Yw== @@ -1478,26 +1497,26 @@ prop-types "^15.8.1" react-is "^19.2.3" -"@mui/x-date-pickers@^8.27.2": - version "8.27.2" - resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-8.27.2.tgz#5ada1fb3adffff3e0fd0fee7702fba7f770dca68" - integrity sha512-06LFkHFRXJ2O9DMXtWAA3kY0jpbL7XH8iqa8L5cBlN+8bRx/UVLKlZYlhGv06C88jF9kuZWY1bUgrv/EoY/2Ww== +"@mui/x-date-pickers@^9.0.2": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-9.0.2.tgz#ac601e4655ce3017185d652f9f91a2914bb6e63a" + integrity sha512-rnyc2wFPnprTS5i8Lq9aX2Rlx+ZRvNZERTd7sPMErf/8HnMCYzxwErITbd+TuImlvo2vaLF1gNynqT8AJMusYw== dependencies: - "@babel/runtime" "^7.28.4" - "@mui/utils" "^7.3.5" - "@mui/x-internals" "8.26.0" + "@babel/runtime" "^7.28.6" + "@mui/utils" "9.0.0" + "@mui/x-internals" "^9.0.0" "@types/react-transition-group" "^4.4.12" clsx "^2.1.1" prop-types "^15.8.1" react-transition-group "^4.4.5" -"@mui/x-internals@8.26.0": - version "8.26.0" - resolved "https://registry.yarnpkg.com/@mui/x-internals/-/x-internals-8.26.0.tgz#49caacac954c29a1b10425c67418310ceb9c8cfa" - integrity sha512-B9OZau5IQUvIxwpJZhoFJKqRpmWf5r0yMmSXjQuqb5WuqM755EuzWJOenY48denGoENzMLT8hQpA0hRTeU2IPA== +"@mui/x-internals@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@mui/x-internals/-/x-internals-9.0.0.tgz#8851a058e09b719690b4f398319805239e923855" + integrity sha512-E/4rdg69JjhyybpPGypCjAKSKLLnSdCFM+O6P/nkUg47+qt3uftxQEhjQO53rcn6ahHl6du/uNZ9BLgeY6kYxQ== dependencies: - "@babel/runtime" "^7.28.4" - "@mui/utils" "^7.3.5" + "@babel/runtime" "^7.28.6" + "@mui/utils" "9.0.0" reselect "^5.1.1" use-sync-external-store "^1.6.0" @@ -7010,6 +7029,11 @@ react-is@^19.2.3: resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.4.tgz#a080758243c572ccd4a63386537654298c99d135" integrity sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA== +react-is@^19.2.4: + version "19.2.5" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.5.tgz#7e7b54143e9313fed787b23fd4295d5a23872ad9" + integrity sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ== + react-leaflet-markercluster@^5.0.0-rc.0: version "5.0.0-rc.0" resolved "https://registry.yarnpkg.com/react-leaflet-markercluster/-/react-leaflet-markercluster-5.0.0-rc.0.tgz#42b1b9786de565fe69ec95abc6ff3232713f5300" From 9ce58d67df423b54a630a06b4c2b388becd29930 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:45:02 +0000 Subject: [PATCH 07/17] chore(deps): bump actions/github-script from 8 to 9 Bumps [actions/github-script](https://github.com/actions/github-script) from 8 to 9. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v8...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/auto_comments.yml | 2 +- .github/workflows/pr_check.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto_comments.yml b/.github/workflows/auto_comments.yml index 9a7664c9007c..89a9908a6748 100644 --- a/.github/workflows/auto_comments.yml +++ b/.github/workflows/auto_comments.yml @@ -17,7 +17,7 @@ jobs: # 1) If the comment includes '!notasponsor', delete it using GitHub Script - name: Delete !notasponsor comment if: contains(github.event.comment.body, '!notasponsor') - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml index 15b52ecd4e82..ea36ac1e82f7 100644 --- a/.github/workflows/pr_check.yml +++ b/.github/workflows/pr_check.yml @@ -25,7 +25,7 @@ jobs: github.event.pull_request.head.repo.fork == true && ((github.event.pull_request.head.ref == 'main' || github.event.pull_request.head.ref == 'master') || (github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'master')) - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | From aa62533e51a0b2d81434dc3614fcc1425b6ae850 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:02:48 +0200 Subject: [PATCH 08/17] fixes frontend loop if 500 is outside of app bounds --- src/pages/500.js | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/src/pages/500.js b/src/pages/500.js index d25c3b9e761d..14f36c54343b 100644 --- a/src/pages/500.js +++ b/src/pages/500.js @@ -1,10 +1,58 @@ -import { Box, Container, Stack, Typography } from "@mui/material"; +import { Box, Button, Container, Stack, Typography } from "@mui/material"; import { Grid } from "@mui/system"; import Head from "next/head"; import { CippImageCard } from "../components/CippCards/CippImageCard.jsx"; import { Layout as DashboardLayout } from "../layouts/index.js"; import { useEffect } from "react"; import { useRouter } from "next/router.js"; +import { ErrorBoundary } from "react-error-boundary"; + +// Minimal fallback if DashboardLayout itself crashes — breaks the infinite loop +const MinimalErrorFallback = ({ error, resetErrorBoundary, outerError }) => { + const handleClearCacheAndReload = () => { + if (typeof window !== "undefined") { + Object.keys(localStorage).forEach((key) => { + if (key.startsWith("REACT_QUERY_OFFLINE_CACHE")) { + localStorage.removeItem(key); + } + }); + } + window.location.reload(true); + }; + + return ( + + + + Error 500 - Something went wrong + Oh no! It seems something went wrong. + + {outerError?.message || error?.message} + + + + + + + + + ); +}; const Error500 = (props) => { //when we browse away from the page we want to reset the error boundary @@ -17,7 +65,11 @@ const Error500 = (props) => { }, [router]); return ( - <> + ( + + )} + > 500 - Error @@ -45,7 +97,7 @@ const Error500 = (props) => { text={ <> Oh no! It seems something went wrong. -
{props.error.message}
+
{props.error?.message}
You can use the button below to try again. } @@ -59,7 +111,7 @@ const Error500 = (props) => {
- +
); }; From c4cba3acd5fda1b640ea5f4455a7ccb9ebfcd714 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:02:54 +0200 Subject: [PATCH 09/17] fixes frontend loop if 500 is outside of app bounds --- src/pages/500.js | 64 ++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/pages/500.js b/src/pages/500.js index 14f36c54343b..623609b2d974 100644 --- a/src/pages/500.js +++ b/src/pages/500.js @@ -1,33 +1,33 @@ -import { Box, Button, Container, Stack, Typography } from "@mui/material"; -import { Grid } from "@mui/system"; -import Head from "next/head"; -import { CippImageCard } from "../components/CippCards/CippImageCard.jsx"; -import { Layout as DashboardLayout } from "../layouts/index.js"; -import { useEffect } from "react"; -import { useRouter } from "next/router.js"; -import { ErrorBoundary } from "react-error-boundary"; +import { Box, Button, Container, Stack, Typography } from '@mui/material' +import { Grid } from '@mui/system' +import Head from 'next/head' +import { CippImageCard } from '../components/CippCards/CippImageCard.jsx' +import { Layout as DashboardLayout } from '../layouts/index.js' +import { useEffect } from 'react' +import { useRouter } from 'next/router.js' +import { ErrorBoundary } from 'react-error-boundary' // Minimal fallback if DashboardLayout itself crashes — breaks the infinite loop const MinimalErrorFallback = ({ error, resetErrorBoundary, outerError }) => { const handleClearCacheAndReload = () => { - if (typeof window !== "undefined") { + if (typeof window !== 'undefined') { Object.keys(localStorage).forEach((key) => { - if (key.startsWith("REACT_QUERY_OFFLINE_CACHE")) { - localStorage.removeItem(key); + if (key.startsWith('REACT_QUERY_OFFLINE_CACHE')) { + localStorage.removeItem(key) } - }); + }) } - window.location.reload(true); - }; + window.location.reload(true) + } return ( @@ -36,7 +36,7 @@ const MinimalErrorFallback = ({ error, resetErrorBoundary, outerError }) => { Oh no! It seems something went wrong. {outerError?.message || error?.message} @@ -51,18 +51,18 @@ const MinimalErrorFallback = ({ error, resetErrorBoundary, outerError }) => { - ); -}; + ) +} const Error500 = (props) => { //when we browse away from the page we want to reset the error boundary //this will prevent the error from showing on other pages - const router = useRouter(); + const router = useRouter() useEffect(() => { return () => { - props.resetErrorBoundary(); - }; - }, [router]); + props.resetErrorBoundary() + } + }, [router]) return ( { sx={{ flexGrow: 1, py: 4, - height: "80vh", + height: '80vh', }} > - + { } title="Error 500 - Something went wrong" - linkText={"Try again"} + linkText={'Try again'} onButtonClick={() => props.resetErrorBoundary()} /> @@ -112,7 +112,7 @@ const Error500 = (props) => { - ); -}; + ) +} -export default Error500; +export default Error500 From 1760b59e05bbc28931cdc32aa3c6179e766c6cd1 Mon Sep 17 00:00:00 2001 From: "Simon K. Hansen" <40685882+zenturash@users.noreply.github.com> Date: Thu, 16 Apr 2026 12:14:20 +0200 Subject: [PATCH 10/17] feat: add AI Administrator role to GDAPRoles Add AI Administrator role to GDAPRoles Adds the AI Administrator privileged role (d2562ede-74db-457e-a7b6-544e236ebb61) for managing Microsoft 365 Copilot, AI-related enterprise services, and copilot agents. Signed-off-by: Simon K. Hansen <40685882+zenturash@users.noreply.github.com> --- src/data/GDAPRoles.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/data/GDAPRoles.json b/src/data/GDAPRoles.json index 7a92b58f95bc..df827501cdeb 100644 --- a/src/data/GDAPRoles.json +++ b/src/data/GDAPRoles.json @@ -814,5 +814,13 @@ "IsSystem": true, "Name": "Customer Delegated Admin Relationship Administrator", "ObjectId": "fc8ad4e2-40e4-4724-8317-bcda7503ecbf" + }, + { + "ExtensionData": {}, + "Description": "Assign the AI Administrator role to users who need to manage all aspects of Microsoft 365 Copilot, AI-related enterprise services, copilot agents, and view usage reports and service health dashboards.", + "IsEnabled": true, + "IsSystem": true, + "Name": "AI Administrator", + "ObjectId": "d2562ede-74db-457e-a7b6-544e236ebb61" } ] From 8cd33c87a34a16b14d9117862dbc5fe26adec232 Mon Sep 17 00:00:00 2001 From: Zacgoose <107489668+Zacgoose@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:41:33 +0800 Subject: [PATCH 11/17] Add custom scripts to backup --- src/components/CippComponents/CippRestoreWizard.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/CippComponents/CippRestoreWizard.jsx b/src/components/CippComponents/CippRestoreWizard.jsx index e2218d4d7e88..a539ccf16770 100644 --- a/src/components/CippComponents/CippRestoreWizard.jsx +++ b/src/components/CippComponents/CippRestoreWizard.jsx @@ -44,6 +44,7 @@ const TABLE_LABELS = { AppPermissions: "App Permissions", CommunityRepos: "Community Repositories", Config: "CIPP Configuration", + CustomPowershellScripts: "Custom PowerShell/Test Scripts", CustomData: "Custom Data", CustomRoles: "Custom Roles", Domains: "Domains", From 37a54d4eab1d96cbd724a4dee0a691e675724a3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:24:58 +0000 Subject: [PATCH 12/17] chore(deps): bump @mui/system from 7.3.2 to 7.3.10 Bumps [@mui/system](https://github.com/mui/material-ui/tree/HEAD/packages/mui-system) from 7.3.2 to 7.3.10. - [Release notes](https://github.com/mui/material-ui/releases) - [Changelog](https://github.com/mui/material-ui/blob/v7.3.10/CHANGELOG.md) - [Commits](https://github.com/mui/material-ui/commits/v7.3.10/packages/mui-system) --- updated-dependencies: - dependency-name: "@mui/system" dependency-version: 7.3.10 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 47 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 17691311015a..8ffb0e3bc1cc 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@mui/icons-material": "7.3.7", "@mui/lab": "7.0.0-beta.17", "@mui/material": "7.3.7", - "@mui/system": "7.3.2", + "@mui/system": "9.0.0", "@mui/x-date-pickers": "^9.0.2", "@musement/iso-duration": "^1.0.0", "@nivo/core": "^0.99.0", diff --git a/yarn.lock b/yarn.lock index a6d5289e57ce..7b54ea378494 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1410,7 +1410,7 @@ react-is "^19.2.3" react-transition-group "^4.4.5" -"@mui/private-theming@^7.3.2", "@mui/private-theming@^7.3.9": +"@mui/private-theming@^7.3.9": version "7.3.9" resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-7.3.9.tgz#c785dc429b7ed62cf3952140be703cbe95704a13" integrity sha512-ErIyRQvsiQEq7Yvcvfw9UDHngaqjMy9P3JDPnRAaKG5qhpl2C4tX/W1S4zJvpu+feihmZJStjIyvnv6KDbIrlw== @@ -1419,7 +1419,16 @@ "@mui/utils" "^7.3.9" prop-types "^15.8.1" -"@mui/styled-engine@^7.3.2", "@mui/styled-engine@^7.3.9": +"@mui/private-theming@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-9.0.0.tgz#2617a4fa2045e0644429556afebe87aeaa0ea966" + integrity sha512-JtuZoaiCqwD6vjgYu6Xp3T7DZkrxJlgtDz5yESzhI34fEX5hHMh2VJUbuL9UOg8xrfIFMrq6dcYoH/7Zi4G0RA== + dependencies: + "@babel/runtime" "^7.29.2" + "@mui/utils" "^9.0.0" + prop-types "^15.8.1" + +"@mui/styled-engine@^7.3.9": version "7.3.9" resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-7.3.9.tgz#e425ca7b5cb559bde01b8fa4a7a842e9b5916f53" integrity sha512-JqujWt5bX4okjUPGpVof/7pvgClqh7HvIbsIBIOOlCh2u3wG/Bwp4+E1bc1dXSwkrkp9WUAoNdI5HEC+5HKvMw== @@ -1431,18 +1440,30 @@ csstype "^3.2.3" prop-types "^15.8.1" -"@mui/system@7.3.2": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-7.3.2.tgz#e838097fc6cb0a2e4c1822478950db89affb116a" - integrity sha512-9d8JEvZW+H6cVkaZ+FK56R53vkJe3HsTpcjMUtH8v1xK6Y1TjzHdZ7Jck02mGXJsE6MQGWVs3ogRHTQmS9Q/rA== +"@mui/styled-engine@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-9.0.0.tgz#ab7b1c25c0193a796ced29da3662191d53ae339b" + integrity sha512-9RLGdX4Jg0aQPRuvqh/OLzYSPlgd5zyEw5/1HIRfdavSiOd03WtUaGZH9/w1RoTYuRKwpgy0hpIFaMHIqPVIWg== dependencies: - "@babel/runtime" "^7.28.3" - "@mui/private-theming" "^7.3.2" - "@mui/styled-engine" "^7.3.2" - "@mui/types" "^7.4.6" - "@mui/utils" "^7.3.2" + "@babel/runtime" "^7.29.2" + "@emotion/cache" "^11.14.0" + "@emotion/serialize" "^1.3.3" + "@emotion/sheet" "^1.4.0" + csstype "^3.2.3" + prop-types "^15.8.1" + +"@mui/system@9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-9.0.0.tgz#a95509127a7df264692105abebaf5a4a965401d5" + integrity sha512-YnC5Zg6j04IxiLc/boAKs0464jfZlLFVa7mf5E8lF0XOtZVUvG6R6gJK50lgUYdaaLdyLfxF6xR7LaPuEpeT/g== + dependencies: + "@babel/runtime" "^7.29.2" + "@mui/private-theming" "^9.0.0" + "@mui/styled-engine" "^9.0.0" + "@mui/types" "^9.0.0" + "@mui/utils" "^9.0.0" clsx "^2.1.1" - csstype "^3.1.3" + csstype "^3.2.3" prop-types "^15.8.1" "@mui/system@^7.3.2", "@mui/system@^7.3.7": @@ -1473,7 +1494,7 @@ dependencies: "@babel/runtime" "^7.29.2" -"@mui/utils@9.0.0": +"@mui/utils@9.0.0", "@mui/utils@^9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-9.0.0.tgz#25b563ccbf537feba5f89c37a00cb8e6eea45ad0" integrity sha512-bQcqyg/gjULUqTuyUjSAFr6LQGLvtkNtDbJerAtoUn9kGZ0hg5QJiN1PLHMLbeFpe3te1831uq7GFl2ITokGdg== From 6da156f17d9adefc6c2eef1da8236ddd9aa6e56f Mon Sep 17 00:00:00 2001 From: Zacgoose <107489668+Zacgoose@users.noreply.github.com> Date: Sat, 18 Apr 2026 03:05:02 +0800 Subject: [PATCH 13/17] Endpoint changes --- .../CippWizard/CippGDAPTenantOnboarding.jsx | 6 +- src/pages/onboardingv2.js | 85 +++++++++++-------- src/pages/tenant/gdap-management/index.js | 82 +++++++++--------- .../tenant/gdap-management/offboarding.js | 55 ++++-------- .../gdap-management/onboarding/start.js | 11 +-- .../gdap-management/relationships/index.js | 14 +-- .../relationships/relationship/index.js | 2 +- .../relationships/relationship/mappings.js | 2 +- 8 files changed, 116 insertions(+), 141 deletions(-) diff --git a/src/components/CippWizard/CippGDAPTenantOnboarding.jsx b/src/components/CippWizard/CippGDAPTenantOnboarding.jsx index 4c5dc48a77cc..6357c5642eb5 100644 --- a/src/components/CippWizard/CippGDAPTenantOnboarding.jsx +++ b/src/components/CippWizard/CippGDAPTenantOnboarding.jsx @@ -45,11 +45,7 @@ export const CippGDAPTenantOnboarding = (props) => { }); const relationshipList = ApiGetCall({ - url: "/api/ListGraphRequest", - data: { - TenantFilter: "", - Endpoint: "tenantRelationships/delegatedAdminRelationships", - }, + url: "/api/ListGDAPRelationships", queryKey: "GDAPRelationshipOnboarding-wizard", }); diff --git a/src/pages/onboardingv2.js b/src/pages/onboardingv2.js index 59f101d6f8f8..3046798627ac 100644 --- a/src/pages/onboardingv2.js +++ b/src/pages/onboardingv2.js @@ -13,52 +13,64 @@ import { CippDirectTenantDeploy } from "../components/CippWizard/CippDirectTenan import { CippGDAPTenantSetup } from "../components/CippWizard/CippGDAPTenantSetup.jsx"; import { CippGDAPTenantOnboarding } from "../components/CippWizard/CippGDAPTenantOnboarding.jsx"; import { BuildingOfficeIcon, CloudIcon, CpuChipIcon } from "@heroicons/react/24/outline"; +import { useRouter } from "next/router"; const Page = () => { + const router = useRouter(); + const selectedOptionQuery = router.query?.selectedOption; + const deepLinkedOption = Array.isArray(selectedOptionQuery) + ? selectedOptionQuery[0] + : selectedOptionQuery; + const setupOptions = [ + { + description: + "Choose this option if this is your first setup, or if you'd like to redo the previous setup.", + icon: , + label: "First Setup", + value: "FirstSetup", + }, + { + description: "Choose this option if you would like to add a tenant to your environment.", + icon: , + label: "Add a tenant", + value: "AddTenant", + }, + { + description: + "Choose this option if you want to setup which application registration is used to connect to your tenants.", + icon: , + label: "Create a new application registration for me and connect to my tenants", + value: "CreateApp", + }, + { + description: "I would like to refresh my token or replace the account I've used.", + icon: , + label: "Refresh Tokens for existing application registration", + value: "UpdateTokens", + }, + { + description: + "I have an existing application and would like to manually enter my token, or update them. This is only recommended for advanced users.", + icon: , + label: "Manually enter credentials", + value: "Manual", + }, + ]; + + const hasDeepLinkedOption = + typeof deepLinkedOption === "string" && + setupOptions.some((option) => option.value === deepLinkedOption); + const steps = [ { description: "Onboarding", component: CippWizardOptionsList, + hideStepWhen: () => hasDeepLinkedOption, componentProps: { title: "Select your setup method", subtext: `This wizard will guide you through setting up CIPPs access to your client tenants. If this is your first time setting up CIPP you will want to choose the option "Create application for me and connect to my tenants",`, valuesKey: "SyncTool", - options: [ - { - description: - "Choose this option if this is your first setup, or if you'd like to redo the previous setup.", - icon: , - label: "First Setup", - value: "FirstSetup", - }, - { - description: - "Choose this option if you would like to add a tenant to your environment.", - icon: , - label: "Add a tenant", - value: "AddTenant", - }, - { - description: - "Choose this option if you want to setup which application registration is used to connect to your tenants.", - icon: , - label: "Create a new application registration for me and connect to my tenants", - value: "CreateApp", - }, - { - description: "I would like to refresh my token or replace the account I've used.", - icon: , - label: "Refresh Tokens for existing application registration", - value: "UpdateTokens", - }, - { - description: - "I have an existing application and would like to manually enter my token, or update them. This is only recommended for advanced users.", - icon: , - label: "Manually enter credentials", - value: "Manual", - }, - ], + options: setupOptions, }, }, { @@ -137,6 +149,7 @@ const Page = () => { steps={steps} wizardTitle="Setup Wizard" postUrl={"/api/ExecCombinedSetup"} + initialState={hasDeepLinkedOption ? { selectedOption: deepLinkedOption } : undefined} /> ); diff --git a/src/pages/tenant/gdap-management/index.js b/src/pages/tenant/gdap-management/index.js index 9aafd4a40531..25e1a1308489 100644 --- a/src/pages/tenant/gdap-management/index.js +++ b/src/pages/tenant/gdap-management/index.js @@ -19,18 +19,16 @@ import CippButtonCard from "../../../components/CippCards/CippButtonCard"; import { WizardSteps } from "../../../components/CippWizard/wizard-steps"; import Link from "next/link"; import { CippHead } from "../../../components/CippComponents/CippHead"; +import { usePermissions } from "../../../hooks/use-permissions"; const Page = () => { const [createDefaults, setCreateDefaults] = useState(false); const [activeStep, setActiveStep] = useState(0); + const { checkRoles } = usePermissions(); + const canViewGdapChecks = checkRoles(["CIPP.AppSettings.Read"]); const relationships = ApiGetCallWithPagination({ - url: "/api/ListGraphRequest", - data: { - Endpoint: "tenantRelationships/delegatedAdminRelationships", - tenantFilter: "", - $top: 300, - }, + url: "/api/ListGDAPRelationships", queryKey: "ListGDAPRelationships", }); @@ -167,46 +165,50 @@ const Page = () => { - - - - - - - - + {canViewGdapChecks && ( + <> + + + + + + + + + + )} ); diff --git a/src/pages/tenant/gdap-management/offboarding.js b/src/pages/tenant/gdap-management/offboarding.js index d9486f775c25..aa6cddc87d0d 100644 --- a/src/pages/tenant/gdap-management/offboarding.js +++ b/src/pages/tenant/gdap-management/offboarding.js @@ -22,60 +22,46 @@ const Page = () => { return vendor.vendorTenantId; }) .join(","); - const vendorGraphFilter = `appOwnerOrganizationId in (${vendorFilter})`; const tenantId = useWatch({ control: formControl.control, name: "tenantFilter", }); const gdapRelationships = ApiGetCall({ - url: "/api/ListGraphRequest", - data: { - Endpoint: "tenantRelationships/delegatedAdminRelationships", - tenantFilter: "", - $top: 300, - }, + url: "/api/ListGDAPRelationships", queryKey: "ListGDAPRelationship", }); const cspContracts = ApiGetCall({ - url: "/api/ListGraphRequest", - data: { - Endpoint: "contracts", - tenantFilter: "", - $top: 300, - }, + url: "/api/ListGDAPContracts", queryKey: "ListContracts", }); const mspApps = ApiGetCall({ - url: "/api/ListGraphRequest", + url: "/api/ListGDAPServicePrincipals", data: { - Endpoint: "servicePrincipals", - TenantFilter: tenantId?.value, - $filter: `appOwnerOrganizationId eq %partnertenantid%`, - $select: "id,displayName,appId,appOwnerOrganizationId", - $count: true, + tenantFilter: tenantId?.value, + ownerType: "partner", }, queryKey: "ListMSPApps-" + tenantId?.value, + waiting: Boolean(tenantId?.value), }); const vendorApps = ApiGetCallWithPagination({ - url: "/api/ListGraphRequest", + url: "/api/ListGDAPServicePrincipals", data: { - Endpoint: "servicePrincipals", - TenantFilter: tenantId?.value, - $filter: vendorGraphFilter, - $select: "id,displayName,appId,appOwnerOrganizationId", - $count: true, + tenantFilter: tenantId?.value, + ownerType: "vendor", + vendorTenantIds: vendorFilter, }, queryKey: "ListVendorApps-" + tenantId?.value, + waiting: Boolean(tenantId?.value), }); return ( <> { label="Select Tenant to Offboard" type="autoComplete" api={{ - url: "/api/ExecExcludeTenant", - data: { - ListAll: true, - }, - queryKey: "ListAllTenants", + url: "/api/ListOffboardTenants", + queryKey: "ListOffboardTenants", labelField: (tenant) => { return `${tenant.displayName} (${tenant.defaultDomainName})`; }, @@ -205,13 +188,11 @@ const Page = () => { label="Vendor Applications to Remove" type="autoComplete" api={{ - url: "/api/ListGraphRequest", + url: "/api/ListGDAPServicePrincipals", data: { - Endpoint: "servicePrincipals", - TenantFilter: tenantId.value, - $filter: vendorGraphFilter, - $select: "id,displayName,appId,appOwnerOrganizationId", - $count: true, + tenantFilter: tenantId.value, + ownerType: "vendor", + vendorTenantIds: vendorFilter, }, dataKey: "Results", queryKey: "ListVendorApps-" + tenantId.value, diff --git a/src/pages/tenant/gdap-management/onboarding/start.js b/src/pages/tenant/gdap-management/onboarding/start.js index c2908d22a467..c5cf9cf5da3a 100644 --- a/src/pages/tenant/gdap-management/onboarding/start.js +++ b/src/pages/tenant/gdap-management/onboarding/start.js @@ -49,11 +49,7 @@ const Page = () => { }); const relationshipList = ApiGetCall({ - url: "/api/ListGraphRequest", - data: { - TenantFilter: "", - Endpoint: "tenantRelationships/delegatedAdminRelationships", - }, + url: "/api/ListGDAPRelationships", queryKey: "GDAPRelationshipOnboarding", }); const onboardingList = ApiGetCallWithPagination({ @@ -317,10 +313,7 @@ const Page = () => { label="Select GDAP Relationship" type="autoComplete" api={{ - url: "/api/ListGraphRequest", - data: { - Endpoint: "tenantRelationships/delegatedAdminRelationships", - }, + url: "/api/ListGDAPRelationships", excludeTenantFilter: true, queryKey: "GDAPRelationships", dataKey: "Results", diff --git a/src/pages/tenant/gdap-management/relationships/index.js b/src/pages/tenant/gdap-management/relationships/index.js index 8c3c3da01bc0..f3a3e4f441a7 100644 --- a/src/pages/tenant/gdap-management/relationships/index.js +++ b/src/pages/tenant/gdap-management/relationships/index.js @@ -4,8 +4,6 @@ import tabOptions from "../tabOptions"; import CippTablePage from "../../../../components/CippComponents/CippTablePage"; import CippGdapActions from "../../../../components/CippComponents/CippGdapActions"; -const pageTitle = "GDAP Relationships"; - const actions = CippGdapActions(); const simpleColumns = [ @@ -47,20 +45,12 @@ const offCanvas = { extendedInfoFields: simpleColumns, }; -const apiUrl = "/api/ListGraphRequest"; -const apiData = { - Endpoint: "tenantRelationships/delegatedAdminRelationships", - tenantFilter: "", - $top: 300, -}; - const Page = () => { return ( { const [relationshipData, setRelationshipData] = useState({}); const relationshipRequest = ApiGetCall({ - url: `/api/ListGraphRequest?Endpoint=tenantRelationships/delegatedAdminRelationships/${id}`, + url: `/api/ListGDAPRelationships?id=${id}`, queryKey: `ListRelationships-${id}`, }); diff --git a/src/pages/tenant/gdap-management/relationships/relationship/mappings.js b/src/pages/tenant/gdap-management/relationships/relationship/mappings.js index 3ec708b70c66..b9669e3f725f 100644 --- a/src/pages/tenant/gdap-management/relationships/relationship/mappings.js +++ b/src/pages/tenant/gdap-management/relationships/relationship/mappings.js @@ -12,7 +12,7 @@ const Page = () => { const { id } = router.query; const relationshipRequest = ApiGetCall({ - url: `/api/ListGraphRequest?Endpoint=tenantRelationships/delegatedAdminRelationships/${id}`, + url: `/api/ListGDAPRelationships?id=${id}`, queryKey: `ListRelationships-${id}`, }); From 007ab7132e8d36168ceccb32f36797c1bf1e6e10 Mon Sep 17 00:00:00 2001 From: Bobby <31723128+kris6673@users.noreply.github.com> Date: Sun, 19 Apr 2026 14:10:09 +0200 Subject: [PATCH 14/17] chore(deps): update/downgrade @mui packages to version 7.3.10 --- package.json | 6 +-- yarn.lock | 110 ++++++++++++++++++++++++++++----------------------- 2 files changed, 64 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 8ffb0e3bc1cc..07dae7f34412 100644 --- a/package.json +++ b/package.json @@ -31,10 +31,10 @@ "@emotion/styled": "11.14.1", "@heroicons/react": "2.2.0", "@monaco-editor/react": "^4.6.0", - "@mui/icons-material": "7.3.7", + "@mui/icons-material": "7.3.10", "@mui/lab": "7.0.0-beta.17", - "@mui/material": "7.3.7", - "@mui/system": "9.0.0", + "@mui/material": "7.3.10", + "@mui/system": "7.3.10", "@mui/x-date-pickers": "^9.0.2", "@musement/iso-duration": "^1.0.0", "@nivo/core": "^0.99.0", diff --git a/yarn.lock b/yarn.lock index 7b54ea378494..717cf1e70089 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1368,17 +1368,17 @@ dependencies: "@monaco-editor/loader" "^1.5.0" -"@mui/core-downloads-tracker@^7.3.7": - version "7.3.9" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.9.tgz#d944e385f8f7f5e680e5ba479b39ff8602bd4939" - integrity sha512-MOkOCTfbMJwLshlBCKJ59V2F/uaLYfmKnN76kksj6jlGUVdI25A9Hzs08m+zjBRdLv+sK7Rqdsefe8X7h/6PCw== +"@mui/core-downloads-tracker@^7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.10.tgz#f6af0bbfa825f11849f5f190d984d6f8d5c0d961" + integrity sha512-vrOpWRmPJSuwLo23J62wggEm/jvGdzqctej+UOCtgDUz6nZJQuj3ByPccVyaa7eQmwAzUwKN56FQPMKkqbj1GA== -"@mui/icons-material@7.3.7": - version "7.3.7" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-7.3.7.tgz#01a6019c552e27c7f8a3451bcb47171ede8b34ac" - integrity sha512-3Q+ulAqG+A1+R4ebgoIs7AccaJhIGy+Xi/9OnvX376jQ6wcy+rz4geDGrxQxCGzdjOQr4Z3NgyFSZCz4T999lA== +"@mui/icons-material@7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-7.3.10.tgz#f0d232ebe007b3a125a52c5c9e1bece43a83b57c" + integrity sha512-Au0ma4NSKGKNiimukj8UT/W1x2Qx6Qwn2RvFGykiSqVLYBNlIOPbjnIMvrwLGLu89EEpTVdu/ys/OduZR+tWqw== dependencies: - "@babel/runtime" "^7.28.4" + "@babel/runtime" "^7.28.6" "@mui/lab@7.0.0-beta.17": version "7.0.0-beta.17" @@ -1392,16 +1392,16 @@ clsx "^2.1.1" prop-types "^15.8.1" -"@mui/material@7.3.7": - version "7.3.7" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-7.3.7.tgz#50fc9b9f8645a4d26a48d7c5f7fa0c9876a8c679" - integrity sha512-6bdIxqzeOtBAj2wAsfhWCYyMKPLkRO9u/2o5yexcL0C3APqyy91iGSWgT3H7hg+zR2XgE61+WAu12wXPON8b6A== +"@mui/material@7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-7.3.10.tgz#1c954b0e7aba220703afe07594388a69383c7363" + integrity sha512-cHvGOk2ZEfbQt3LnGe0ZKd/ETs9gsUpkW66DCO+GSjMZhpdKU4XsuIr7zJ/B/2XaN8ihxuzHfYAR4zPtCN4RYg== dependencies: - "@babel/runtime" "^7.28.4" - "@mui/core-downloads-tracker" "^7.3.7" - "@mui/system" "^7.3.7" - "@mui/types" "^7.4.10" - "@mui/utils" "^7.3.7" + "@babel/runtime" "^7.28.6" + "@mui/core-downloads-tracker" "^7.3.10" + "@mui/system" "^7.3.10" + "@mui/types" "^7.4.12" + "@mui/utils" "^7.3.10" "@popperjs/core" "^2.11.8" "@types/react-transition-group" "^4.4.12" clsx "^2.1.1" @@ -1410,6 +1410,15 @@ react-is "^19.2.3" react-transition-group "^4.4.5" +"@mui/private-theming@^7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-7.3.10.tgz#2e500959f39c7b305a30ff3f947f47dea9e8eac1" + integrity sha512-j3EZN+zOctxUISvJSmsEPo5o2F8zse4l5vRkBY+ps6UtnL6J7o14kUaI4w7gwo73id9e3cDNMVQK/9BVaMHVBw== + dependencies: + "@babel/runtime" "^7.28.6" + "@mui/utils" "^7.3.10" + prop-types "^15.8.1" + "@mui/private-theming@^7.3.9": version "7.3.9" resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-7.3.9.tgz#c785dc429b7ed62cf3952140be703cbe95704a13" @@ -1419,19 +1428,10 @@ "@mui/utils" "^7.3.9" prop-types "^15.8.1" -"@mui/private-theming@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-9.0.0.tgz#2617a4fa2045e0644429556afebe87aeaa0ea966" - integrity sha512-JtuZoaiCqwD6vjgYu6Xp3T7DZkrxJlgtDz5yESzhI34fEX5hHMh2VJUbuL9UOg8xrfIFMrq6dcYoH/7Zi4G0RA== - dependencies: - "@babel/runtime" "^7.29.2" - "@mui/utils" "^9.0.0" - prop-types "^15.8.1" - -"@mui/styled-engine@^7.3.9": - version "7.3.9" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-7.3.9.tgz#e425ca7b5cb559bde01b8fa4a7a842e9b5916f53" - integrity sha512-JqujWt5bX4okjUPGpVof/7pvgClqh7HvIbsIBIOOlCh2u3wG/Bwp4+E1bc1dXSwkrkp9WUAoNdI5HEC+5HKvMw== +"@mui/styled-engine@^7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-7.3.10.tgz#53e98c1fdeda972b5932c76f6a2a29faf33f0d11" + integrity sha512-WxE9SiF8xskAQqGjsp0poXCkCqsoXFEsSr0HBXfApmGHR+DBnXRp+z46Vsltg4gpPM4Z96DeAQRpeAOnhNg7Ng== dependencies: "@babel/runtime" "^7.28.6" "@emotion/cache" "^11.14.0" @@ -1440,33 +1440,33 @@ csstype "^3.2.3" prop-types "^15.8.1" -"@mui/styled-engine@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-9.0.0.tgz#ab7b1c25c0193a796ced29da3662191d53ae339b" - integrity sha512-9RLGdX4Jg0aQPRuvqh/OLzYSPlgd5zyEw5/1HIRfdavSiOd03WtUaGZH9/w1RoTYuRKwpgy0hpIFaMHIqPVIWg== +"@mui/styled-engine@^7.3.9": + version "7.3.9" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-7.3.9.tgz#e425ca7b5cb559bde01b8fa4a7a842e9b5916f53" + integrity sha512-JqujWt5bX4okjUPGpVof/7pvgClqh7HvIbsIBIOOlCh2u3wG/Bwp4+E1bc1dXSwkrkp9WUAoNdI5HEC+5HKvMw== dependencies: - "@babel/runtime" "^7.29.2" + "@babel/runtime" "^7.28.6" "@emotion/cache" "^11.14.0" "@emotion/serialize" "^1.3.3" "@emotion/sheet" "^1.4.0" csstype "^3.2.3" prop-types "^15.8.1" -"@mui/system@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-9.0.0.tgz#a95509127a7df264692105abebaf5a4a965401d5" - integrity sha512-YnC5Zg6j04IxiLc/boAKs0464jfZlLFVa7mf5E8lF0XOtZVUvG6R6gJK50lgUYdaaLdyLfxF6xR7LaPuEpeT/g== +"@mui/system@7.3.10", "@mui/system@^7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-7.3.10.tgz#b8e668537605413be168a865d4e980c7d6747320" + integrity sha512-/sfPpdpJaQn7BSF+avjIdHSYmxHp0UOBYNxSG9QGKfMOD6sLANCpRPCnanq1Pe0lFf0NHkO2iUk0TNzdWC1USQ== dependencies: - "@babel/runtime" "^7.29.2" - "@mui/private-theming" "^9.0.0" - "@mui/styled-engine" "^9.0.0" - "@mui/types" "^9.0.0" - "@mui/utils" "^9.0.0" + "@babel/runtime" "^7.28.6" + "@mui/private-theming" "^7.3.10" + "@mui/styled-engine" "^7.3.10" + "@mui/types" "^7.4.12" + "@mui/utils" "^7.3.10" clsx "^2.1.1" csstype "^3.2.3" prop-types "^15.8.1" -"@mui/system@^7.3.2", "@mui/system@^7.3.7": +"@mui/system@^7.3.2": version "7.3.9" resolved "https://registry.yarnpkg.com/@mui/system/-/system-7.3.9.tgz#d8181dd9ad8c5e9afdf50eb7009062c506976ab1" integrity sha512-aL1q9am8XpRrSabv9qWf5RHhJICJql34wnrc1nz0MuOglPRYF/liN+c8VqZdTvUn9qg+ZjRVbKf4sJVFfIDtmg== @@ -1480,7 +1480,7 @@ csstype "^3.2.3" prop-types "^15.8.1" -"@mui/types@^7.4.10", "@mui/types@^7.4.12", "@mui/types@^7.4.6": +"@mui/types@^7.4.12", "@mui/types@^7.4.6": version "7.4.12" resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.4.12.tgz#e4eba37a7506419ea5c5e0604322ba82b271bf46" integrity sha512-iKNAF2u9PzSIj40CjvKJWxFXJo122jXVdrmdh0hMYd+FR+NuJMkr/L88XwWLCRiJ5P1j+uyac25+Kp6YC4hu6w== @@ -1494,7 +1494,7 @@ dependencies: "@babel/runtime" "^7.29.2" -"@mui/utils@9.0.0", "@mui/utils@^9.0.0": +"@mui/utils@9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-9.0.0.tgz#25b563ccbf537feba5f89c37a00cb8e6eea45ad0" integrity sha512-bQcqyg/gjULUqTuyUjSAFr6LQGLvtkNtDbJerAtoUn9kGZ0hg5QJiN1PLHMLbeFpe3te1831uq7GFl2ITokGdg== @@ -1506,7 +1506,19 @@ prop-types "^15.8.1" react-is "^19.2.4" -"@mui/utils@^7.3.2", "@mui/utils@^7.3.7", "@mui/utils@^7.3.9": +"@mui/utils@^7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.3.10.tgz#b74050131ca9022c0815d16f54f1a6d757ab343d" + integrity sha512-7y2eIfy0h7JPz+Yy4pS+wgV68d46PuuxDqKBN4Q8VlPQSsCAGwroMCV6xWyc7g9dvEp8ZNFsknc59GHWO+r6Ow== + dependencies: + "@babel/runtime" "^7.28.6" + "@mui/types" "^7.4.12" + "@types/prop-types" "^15.7.15" + clsx "^2.1.1" + prop-types "^15.8.1" + react-is "^19.2.3" + +"@mui/utils@^7.3.2", "@mui/utils@^7.3.9": version "7.3.9" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.3.9.tgz#8af5093fc93c2e582fa3d047f561c7b690509bc2" integrity sha512-U6SdZaGbfb65fqTsH3V5oJdFj9uYwyLE2WVuNvmbggTSDBb8QHrFsqY8BN3taK9t3yJ8/BPHD/kNvLNyjwM7Yw== From 4520067ddaf02d506209e9e0a6e079e8ece0ffd3 Mon Sep 17 00:00:00 2001 From: Zacgoose <107489668+Zacgoose@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:59:37 +0800 Subject: [PATCH 15/17] change domain validation to only 1 domain segment --- src/utils/get-cipp-validator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/get-cipp-validator.js b/src/utils/get-cipp-validator.js index e1db092ae1ad..f5541e0dc25c 100644 --- a/src/utils/get-cipp-validator.js +++ b/src/utils/get-cipp-validator.js @@ -41,7 +41,7 @@ export const getCippValidator = (value, type) => { case "wildcardDomain": return /^(\*\.)?([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.\*)?$/.test(value) || /^(\*)?[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\*)?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/.test(value) || "This is not a valid domain pattern"; case "wildcardUrl": - return /^(https?:\/\/)?(\*\.)?([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.\*)?([\/\?\*][a-zA-Z0-9\-\.\~\*\/\?=&%]*)?$/.test(value) || "This is not a valid URL pattern"; + return /^(https?:\/\/)?(\*\.)?([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.\*)?([\/\?\*][a-zA-Z0-9\-\.\~\*\/\?=&%]*)?$/.test(value) || "This is not a valid URL pattern"; case "senderEntry": return ( /^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$/.test(value) || From 552757246e0a4268e8792a4bb8944d29b9136d30 Mon Sep 17 00:00:00 2001 From: Zacgoose <107489668+Zacgoose@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:22:49 +0800 Subject: [PATCH 16/17] fixes launching emulator --- Tools/Start-CippDevEmulators.ps1 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Tools/Start-CippDevEmulators.ps1 b/Tools/Start-CippDevEmulators.ps1 index 2b5d4a4a7ac6..45ac7598e959 100644 --- a/Tools/Start-CippDevEmulators.ps1 +++ b/Tools/Start-CippDevEmulators.ps1 @@ -42,5 +42,11 @@ try { $frontendCommand = 'try { npm run dev } catch { Write-Error $_.Exception.Message } finally { Read-Host "Press Enter to exit" }' $swaCommand = 'try { npm run start-swa } catch { Write-Error $_.Exception.Message } finally { Read-Host "Press Enter to exit" }' +# Encode commands to avoid parsing issues with multi-line strings +$azuriteEncoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($azuriteCommand)) +$apiEncoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($apiCommand)) +$frontendEncoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($frontendCommand)) +$swaEncoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($swaCommand)) + # Start Windows Terminal with all tabs -wt --title CIPP`; new-tab --title 'Azurite' -d $Path pwsh -c $azuriteCommand`; new-tab --title 'FunctionApp' -d $ApiPath pwsh -c $apiCommand`; new-tab --title 'CIPP Frontend' -d $FrontendPath pwsh -c $frontendCommand`; new-tab --title 'SWA' -d $FrontendPath pwsh -c $swaCommand +wt --title CIPP`; new-tab --title 'Azurite' -d $Path pwsh -EncodedCommand $azuriteEncoded`; new-tab --title 'FunctionApp' -d $ApiPath pwsh -EncodedCommand $apiEncoded`; new-tab --title 'CIPP Frontend' -d $FrontendPath pwsh -EncodedCommand $frontendEncoded`; new-tab --title 'SWA' -d $FrontendPath pwsh -EncodedCommand $swaEncoded From 0bf17bd67c720dab499f9134958ac9083d864822 Mon Sep 17 00:00:00 2001 From: Zacgoose <107489668+Zacgoose@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:37:55 +0800 Subject: [PATCH 17/17] Update Start-CippDevEmulators.ps1 --- Tools/Start-CippDevEmulators.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/Start-CippDevEmulators.ps1 b/Tools/Start-CippDevEmulators.ps1 index 45ac7598e959..ecf6855fe1e5 100644 --- a/Tools/Start-CippDevEmulators.ps1 +++ b/Tools/Start-CippDevEmulators.ps1 @@ -22,7 +22,7 @@ $apiCommand = @' try { # Use a stable local identity so timer node selection treats this as the catch-all host. $env:WEBSITE_SITE_NAME = "cipp" - $env:CIPP_PROCESSOR = "true" + $env:CIPP_PROCESSOR = "false" $env:AzureFunctionsWebHost__hostid = "cipp-single" # Ensure prior offload simulation env overrides do not disable triggers in this shell.