diff --git a/public/version.json b/public/version.json index fb57e409303d..d18f79dee972 100644 --- a/public/version.json +++ b/public/version.json @@ -1,3 +1,3 @@ { - "version": "8.0.0" + "version": "8.0.1" } diff --git a/src/components/CippCards/CippDomainCards.jsx b/src/components/CippCards/CippDomainCards.jsx index 93bcc3cd7104..3aa81e3019fe 100644 --- a/src/components/CippCards/CippDomainCards.jsx +++ b/src/components/CippCards/CippDomainCards.jsx @@ -152,7 +152,7 @@ function DomainResultCard({ title, data, isFetching, info, type }) { ? { children: ( - + {info} @@ -182,7 +182,7 @@ function DomainResultCard({ title, data, isFetching, info, type }) { ? { children: ( //4 headers, "Record" and then under it. - (<> + <> Record: @@ -237,7 +237,7 @@ function DomainResultCard({ title, data, isFetching, info, type }) { value: email, }))} /> - ) + ), } : type === "SPF" @@ -361,7 +361,7 @@ function DomainResultCard({ title, data, isFetching, info, type }) { } isFetching={isFetching} > - + {info} setVisible(false)} {...offCanvasData} /> @@ -483,7 +483,7 @@ export const CippDomainCards = ({ domain: propDomain = "", fullwidth = false }) return (
- + - + - + @@ -562,7 +562,7 @@ export const CippDomainCards = ({ domain: propDomain = "", fullwidth = false }) {domain && ( <> - + - + - + - + - + - + - + - + {enableHttps && ( - + { if (Array.isArray(obj)) { @@ -37,7 +42,29 @@ const cleanObject = (obj) => { } }; -const renderListItems = (data, onItemClick) => { +// Function to check if a string is a GUID +const isGuid = (str) => { + if (typeof str !== "string") return false; + const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return guidRegex.test(str); +}; + +// Function to recursively scan an object for GUIDs +const findGuids = (obj, guidsSet = new Set()) => { + if (!obj) return guidsSet; + + if (typeof obj === "string" && isGuid(obj)) { + guidsSet.add(obj); + } else if (Array.isArray(obj)) { + obj.forEach((item) => findGuids(item, guidsSet)); + } else if (typeof obj === "object") { + Object.values(obj).forEach((value) => findGuids(value, guidsSet)); + } + + return guidsSet; +}; + +const renderListItems = (data, onItemClick, guidMapping = {}, isLoadingGuids = false) => { return Object.entries(data).map(([key, value]) => { if (Array.isArray(value)) { return ( @@ -64,6 +91,31 @@ const renderListItems = (data, onItemClick) => { } /> ); + } else if (typeof value === "string" && isGuid(value) && guidMapping[value]) { + return ( + +
{guidMapping[value]}
+ + } + /> + ); + } else if (typeof value === "string" && isGuid(value) && isLoadingGuids) { + return ( + + + {getCippFormatting(value, key)} + + } + /> + ); } else { return ( { + if (data && Array.isArray(data.value)) { + const newMapping = {}; + + // Process the returned results + data.value.forEach((item) => { + if (item.id && (item.displayName || item.userPrincipalName || item.mail)) { + // Prefer displayName, fallback to UPN or mail if available + newMapping[item.id] = item.displayName || item.userPrincipalName || item.mail; + } + }); + + // Find GUIDs that were sent but not returned in the response + const processedGuids = new Set(pendingGuids); + const returnedGuids = new Set(data.value.map((item) => item.id)); + const notReturned = [...processedGuids].filter((guid) => !returnedGuids.has(guid)); + + // Add them to the notFoundGuids set + if (notReturned.length > 0) { + setNotFoundGuids((prev) => { + const newSet = new Set(prev); + notReturned.forEach((guid) => newSet.add(guid)); + return newSet; + }); + } + + setGuidMapping((prevMapping) => ({ ...prevMapping, ...newMapping })); + setPendingGuids([]); + setIsLoadingGuids(false); + } + }, + }); + + // Function to handle resolving GUIDs - used in both useEffect and handleItemClick + const resolveGuids = (objectToScan) => { + const guidsSet = findGuids(objectToScan); + + if (guidsSet.size === 0) return; + + const guidsArray = Array.from(guidsSet); + // Filter out GUIDs that are already resolved or known to not be resolvable + const notResolvedGuids = guidsArray.filter( + (guid) => !guidMapping[guid] && !notFoundGuids.has(guid) + ); + + if (notResolvedGuids.length === 0) return; + + // Merge with any pending GUIDs to avoid duplicate requests + const allPendingGuids = [...new Set([...pendingGuids, ...notResolvedGuids])]; + setPendingGuids(allPendingGuids); + setIsLoadingGuids(true); + + // Implement throttling - only send a new request every 2 seconds + const now = Date.now(); + if (now - lastRequestTime < 2000) { + return; + } + + setLastRequestTime(now); + + // Only send a maximum of 1000 GUIDs per request + const batchSize = 1000; + const guidsToSend = allPendingGuids.slice(0, batchSize); + + if (guidsToSend.length > 0) { + directoryObjectsMutation.mutate({ + url: "/api/ListDirectoryObjects", + data: { + tenantFilter: tenantFilter, + ids: guidsToSend, + $select: "id,displayName,userPrincipalName,mail", + }, + }); + } else { + setIsLoadingGuids(false); + } + }; const renderIntuneItems = (data) => { const items = []; @@ -96,11 +235,31 @@ function CippJsonView({ if (data.omaSettings) { data.omaSettings.forEach((omaSetting, index) => { + // Check if value is a GUID that we've resolved + const value = + typeof omaSetting.value === "string" && + isGuid(omaSetting.value) && + guidMapping[omaSetting.value] ? ( + +
+ {guidMapping[omaSetting.value]} + + (GUID) + +
+
+ ) : ( + omaSetting.value + ); + items.push( ); }); @@ -144,13 +303,50 @@ function CippJsonView({ } else if (settingInstance?.simpleSettingValue?.value) { const label = intuneObj?.displayName || settingInstance.settingDefinitionId; const value = settingInstance.simpleSettingValue.value; - items.push(); + // Check if value is a GUID that we've resolved + const displayValue = + typeof value === "string" && isGuid(value) && guidMapping[value] ? ( + +
+ {guidMapping[value]} + + (GUID) + +
+
+ ) : ( + value + ); + + items.push( + + ); } else if (settingInstance?.choiceSettingValue?.value) { const label = intuneObj?.displayName || settingInstance.settingDefinitionId; - const optionValue = - intuneObj?.options?.find( - (option) => option.id === settingInstance.choiceSettingValue.value - )?.displayName || settingInstance.choiceSettingValue.value; + const rawValue = settingInstance.choiceSettingValue.value; + let optionValue = + intuneObj?.options?.find((option) => option.id === rawValue)?.displayName || rawValue; + + // Check if optionValue is a GUID that we've resolved + if (typeof optionValue === "string" && isGuid(optionValue) && guidMapping[optionValue]) { + optionValue = ( + +
+ {guidMapping[optionValue]} + + (GUID) + +
+
+ ); + } + items.push( ); @@ -175,13 +371,49 @@ function CippJsonView({ ); } else { Object.entries(data).forEach(([key, value]) => { - items.push( - - ); + // Check if value is a GUID that we've resolved + if (typeof value === "string" && isGuid(value) && guidMapping[value]) { + items.push( + +
+ {guidMapping[value]} + + (GUID) + +
+ + } + /> + ); + } else if (typeof value === "string" && isGuid(value) && isLoadingGuids) { + items.push( + + + {getCippFormatting(value, key)} + + } + /> + ); + } else { + items.push( + + ); + } }); } @@ -206,7 +438,42 @@ function CippJsonView({ Object.entries(cleanedObj).filter(([key]) => !blacklist.includes(key)) ); setDrilldownData([filteredObj]); - }, [object]); + + // Using the centralized resolveGuids function to handle GUID resolution + resolveGuids(cleanedObj); + }, [object, tenantFilter]); + + // Effect to reprocess any pending GUIDs when the guidMapping changes or throttling window passes + useEffect(() => { + if (pendingGuids.length > 0 && !isLoadingGuids) { + const now = Date.now(); + if (now - lastRequestTime >= 2000) { + // Only send a maximum of 1000 GUIDs per request + const batchSize = 1000; + const guidsToSend = pendingGuids.slice(0, batchSize); + + setLastRequestTime(now); + setIsLoadingGuids(true); + + directoryObjectsMutation.mutate({ + url: "/api/ListDirectoryObjects", + data: { + tenantFilter: tenantFilter, + ids: guidsToSend, + $select: "id,displayName,userPrincipalName,mail", + }, + }); + } + } + }, [ + guidMapping, + notFoundGuids, + pendingGuids, + lastRequestTime, + isLoadingGuids, + directoryObjectsMutation, + tenantFilter, + ]); const toggleView = () => setViewJson(!viewJson); @@ -214,6 +481,9 @@ function CippJsonView({ const updatedData = drilldownData.slice(0, level + 1); updatedData[level + 1] = itemData; setDrilldownData(updatedData); + + // Use the centralized resolveGuids function to handle GUID resolution for drill-down data + resolveGuids(itemData); }; return ( @@ -226,9 +496,16 @@ function CippJsonView({ expandIcon={} sx={{ display: "flex", alignItems: "center" }} > - - Policy Details - + + + Policy Details + + {isLoadingGuids && ( + + Resolving object identifiers... + + )} + @@ -238,29 +515,36 @@ function CippJsonView({ ) : ( - {drilldownData?.map((data, index) => ( - 4, and add spacing between the top and bottom items - paddingTop: index === 0 ? 0 : 2, - borderTop: index >= 4 && type !== "intune" ? "1px solid lightgrey" : "none", - borderRight: index < drilldownData.length - 1 ? "1px solid lightgrey" : "none", - overflowWrap: "anywhere", - whiteSpace: "pre-line", - paddingRight: 2, - }} - > - {type !== "intune" && ( - - {renderListItems(data, (itemData) => handleItemClick(itemData, index))} - - )} - {type === "intune" && {renderIntuneItems(data)}} - - ))} + {drilldownData + ?.filter((data) => data !== null && data !== undefined) + .map((data, index) => ( + 4, and add spacing between the top and bottom items + paddingTop: index === 0 ? 0 : 2, + borderTop: index >= 4 && type !== "intune" ? "1px solid lightgrey" : "none", + borderRight: index < drilldownData.length - 1 ? "1px solid lightgrey" : "none", + overflowWrap: "anywhere", + whiteSpace: "pre-line", + paddingRight: 2, + }} + > + {type !== "intune" && ( + + {renderListItems( + data, + (itemData) => handleItemClick(itemData, index), + guidMapping, + isLoadingGuids + )} + + )} + {type === "intune" && {renderIntuneItems(data)}} + + ))} )} diff --git a/src/components/CippIntegrations/CippApiClientManagement.jsx b/src/components/CippIntegrations/CippApiClientManagement.jsx index 5e7db0b495d5..65914ea19dd0 100644 --- a/src/components/CippIntegrations/CippApiClientManagement.jsx +++ b/src/components/CippIntegrations/CippApiClientManagement.jsx @@ -78,12 +78,12 @@ const CippApiClientManagement = () => { multiple: false, creatable: false, label: "Select Role", - placeholder: "Choose a role from the Custom Role list.", + placeholder: "Choose a role from the CIPP Role list.", api: { url: "/api/ListCustomRole", queryKey: "CustomRoleList", - labelField: "RowKey", - valueField: "RowKey", + labelField: "RoleName", + valueField: "RoleName", showRefresh: true, }, }, @@ -316,11 +316,11 @@ const CippApiClientManagement = () => { api: { url: "/api/ListCustomRole", queryKey: "CustomRoleList", - labelField: "RowKey", - valueField: "RowKey", + labelField: "RoleName", + valueField: "RoleName", showRefresh: true, }, - placeholder: "Choose a role from the Custom Role list.", + placeholder: "Choose a role from the CIPP Role list.", }, { type: "autoComplete", @@ -380,12 +380,12 @@ const CippApiClientManagement = () => { multiple: false, creatable: false, label: "Select Role", - placeholder: "Choose a role from the Custom Role list.", + placeholder: "Choose a role from the CIPP Role list.", api: { url: "/api/ListCustomRole", queryKey: "CustomRoleList", - labelField: "RowKey", - valueField: "RowKey", + labelField: "RoleName", + valueField: "RoleName", showRefresh: true, }, }, diff --git a/src/components/PrivateRoute.js b/src/components/PrivateRoute.js index 3541eeda2d96..d08c03a7fbf6 100644 --- a/src/components/PrivateRoute.js +++ b/src/components/PrivateRoute.js @@ -1,17 +1,13 @@ import { ApiGetCall } from "../api/ApiCall.jsx"; import UnauthenticatedPage from "../pages/unauthenticated.js"; import LoadingPage from "../pages/loading.js"; +import ApiOfflinePage from "../pages/api-offline.js"; export const PrivateRoute = ({ children, routeType }) => { - const { - data: profile, - error, - isLoading, - isSuccess, - refetch, - } = ApiGetCall({ + const apiRoles = ApiGetCall({ url: "/api/me", queryKey: "authmecipp", + retry: 2, // Reduced retry count to show offline message sooner }); const session = ApiGetCall({ @@ -22,10 +18,20 @@ export const PrivateRoute = ({ children, routeType }) => { }); // Check if the session is still loading before determining authentication status - if (session.isLoading || isLoading) { + if (session.isLoading || apiRoles.isLoading) { return ; } + // Check if the API is offline (404 error from /api/me endpoint) + // Or other network errors that would indicate API is unavailable + if ( + apiRoles?.error?.response?.status === 404 || // API endpoint not found + apiRoles?.error?.response?.status === 502 || // Service unavailable + (apiRoles?.isSuccess && !apiRoles?.data?.clientPrincipal) // No client principal data, indicating API might be offline + ) { + return ; + } + // if not logged into swa if (null === session?.data?.clientPrincipal || session?.data === undefined) { return ; @@ -35,19 +41,19 @@ export const PrivateRoute = ({ children, routeType }) => { if ( session?.isSuccess && - isSuccess && - undefined !== profile && + apiRoles?.isSuccess && + undefined !== apiRoles?.data?.clientPrincipal && session?.data?.clientPrincipal?.userDetails && - profile?.userDetails && - session?.data?.clientPrincipal?.userDetails !== profile?.userDetails + apiRoles?.data?.clientPrincipal?.userDetails && + session?.data?.clientPrincipal?.userDetails !== apiRoles?.data?.clientPrincipal?.userDetails ) { // refetch the profile if the user details are different refetch(); } - if (null !== profile?.clientPrincipal && undefined !== profile) { - roles = profile?.clientPrincipal?.userRoles; - } else if (null === profile?.clientPrincipal || undefined === profile) { + if (null !== apiRoles?.data?.clientPrincipal && undefined !== apiRoles?.data) { + roles = apiRoles?.data?.clientPrincipal?.userRoles ?? []; + } else if (null === apiRoles?.data?.clientPrincipal || undefined === apiRoles?.data) { return ; } if (null === roles) { @@ -55,8 +61,8 @@ export const PrivateRoute = ({ children, routeType }) => { } else { const blockedRoles = ["anonymous", "authenticated"]; const userRoles = roles?.filter((role) => !blockedRoles.includes(role)) ?? []; - const isAuthenticated = userRoles.length > 0 && !error; - const isAdmin = roles.includes("admin") || roles.includes("superadmin"); + const isAuthenticated = userRoles.length > 0 && !apiRoles?.error; + const isAdmin = roles?.includes("admin") || roles?.includes("superadmin"); if (routeType === "admin") { return !isAdmin ? : children; } else { diff --git a/src/data/Extensions.json b/src/data/Extensions.json index badbfc046cf9..4d8bcc01386c 100644 --- a/src/data/Extensions.json +++ b/src/data/Extensions.json @@ -81,12 +81,12 @@ { "type": "autoComplete", "name": "Sherweb.AllowedCustomRoles", - "label": "Select custom roles that are allowed to purchase licenses", + "label": "Select CIPP roles that are allowed to purchase licenses", "api": { "url": "/api/ListCustomRole", "queryKey": "CustomRoles", - "labelField": "RowKey", - "valueField": "RowKey" + "labelField": "RoleName", + "valueField": "RoleName" }, "multiple": true, "condition": { diff --git a/src/data/M365Licenses.json b/src/data/M365Licenses.json index aa7ef62fb439..d206d18e2f67 100644 --- a/src/data/M365Licenses.json +++ b/src/data/M365Licenses.json @@ -1,4 +1,20 @@ [ + { + "Product_Display_Name": "10-Year Audit Log Retention Add On", + "String_Id": "10_ALR_ADDON", + "GUID": "c2e41e49-e2a2-4c55-832a-cf13ffba1d6a", + "Service_Plan_Name": "Auditing_10Year_ Retention_ Add_On", + "Service_Plan_Id": "7d16094b-4db8-41ff-a182-372a90a85407", + "Service_Plans_Included_Friendly_Names": "Auditing 10Year Retention Add On" + }, + { + "Product_Display_Name": "Advanced Communications", + "String_Id": "ADV_COMMS", + "GUID": "e4654015-5daf-4a48-9b37-4f309dddd88b", + "Service_Plan_Name": "TEAMS_ADVCOMMS", + "Service_Plan_Id": "604ec28a-ae18-4bc6-91b0-11da94504ba9", + "Service_Plans_Included_Friendly_Names": "Microsoft 365 Advanced Communications" + }, { "Product_Display_Name": "AI Builder Capacity add-on", "String_Id": "CDSAICAPACITY", @@ -55,6 +71,30 @@ "Service_Plan_Id": "2e6ffd72-52d1-4541-8f6c-938f9a8d4cdc", "Service_Plans_Included_Friendly_Names": "Microsoft Application Protection and Governance (D)" }, + { + "Product_Display_Name": "Azure Information Protection Premium P1 for Government", + "String_Id": "RIGHTSMANAGEMENT_CE_GOV\t", + "GUID": "78362de1-6942-4bb8-83a1-a32aa67e6e2c", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION_GOV", + "Service_Plan_Id": "922ba911-5694-4e99-a794-73aed9bfeec8", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation for Government" + }, + { + "Product_Display_Name": "Azure Information Protection Premium P1 for Government", + "String_Id": "RIGHTSMANAGEMENT_CE_GOV\t", + "GUID": "78362de1-6942-4bb8-83a1-a32aa67e6e2c", + "Service_Plan_Name": "RMS_S_PREMIUM_GOV", + "Service_Plan_Id": "1b66aedf-8ca1-4f73-af76-ec76c6180f98", + "Service_Plans_Included_Friendly_Names": "Azure Information Protection Premium P1 for GCC" + }, + { + "Product_Display_Name": "Azure Information Protection Premium P1 for Government", + "String_Id": "RIGHTSMANAGEMENT_CE_GOV\t", + "GUID": "78362de1-6942-4bb8-83a1-a32aa67e6e2c", + "Service_Plan_Name": "RMS_S_ENTERPRISE_GOV", + "Service_Plan_Id": "6a76346d-5d6e-4051-9fe3-ed3f312b5597", + "Service_Plans_Included_Friendly_Names": "Azure Rights Management" + }, { "Product_Display_Name": "Career Coach for faculty", "String_Id": "CAREERCOACH_FACULTY", @@ -1279,6 +1319,30 @@ "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" }, + { + "Product_Display_Name": "Dynamics 365 Customer Service Voice Channel Add-in", + "String_Id": "DYN365_CS_VOICE", + "GUID": "dadd2312-b5b1-4fa0-8c15-0903de3e2303", + "Service_Plan_Name": "DYN365_CS_VOICE", + "Service_Plan_Id": "f6ec6dfa-2402-468d-a455-89be11116d43", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Customer Service Voice Add-in" + }, + { + "Product_Display_Name": "Dynamics 365 Customer Service Voice Channel Add-in", + "String_Id": "DYN365_CS_VOICE", + "GUID": "dadd2312-b5b1-4fa0-8c15-0903de3e2303", + "Service_Plan_Name": "POWER_VIRTUAL_AGENTS_D365_CS_VOICE", + "Service_Plan_Id": "a3dce1be-e9ca-453a-9483-e69a5b46ce98", + "Service_Plans_Included_Friendly_Names": "Power Virtual Agents for Customer Service Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Customer Service Voice Channel Add-in", + "String_Id": "DYN365_CS_VOICE", + "GUID": "dadd2312-b5b1-4fa0-8c15-0903de3e2303", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, { "Product_Display_Name": "Dynamics 365 Customer Insights Standalone", "String_Id": "DYN365_CUSTOMER_INSIGHTS_BASE", @@ -1967,6 +2031,118 @@ "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" }, + { + "Product_Display_Name": "Dynamics 365 for Finance Attach to Qualifying Dynamics 365 Base Offer", + "String_Id": "DYN365_FINANCE_ATTACH", + "GUID": "d721f2e4-099b-4105-b40e-872e46cad402", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 for Finance Attach to Qualifying Dynamics 365 Base Offer", + "String_Id": "DYN365_FINANCE_ATTACH", + "GUID": "d721f2e4-099b-4105-b40e-872e46cad402", + "Service_Plan_Name": "CDS_AI_Capacity_FI", + "Service_Plan_Id": "5d85ec34-44e5-43b6-a9aa-d1b4c1d3aa3b", + "Service_Plans_Included_Friendly_Names": "AI Builder Capacity Add-on" + }, + { + "Product_Display_Name": "Dynamics 365 for Finance Attach to Qualifying Dynamics 365 Base Offer", + "String_Id": "DYN365_FINANCE_ATTACH", + "GUID": "d721f2e4-099b-4105-b40e-872e46cad402", + "Service_Plan_Name": "DYN365_CDS_FINANCE", + "Service_Plan_Id": "e95d7060-d4d9-400a-a2bd-a244bf0b609e", + "Service_Plans_Included_Friendly_Names": "Common Data Service for Dynamics 365 Finance" + }, + { + "Product_Display_Name": "Dynamics 365 for Finance Attach to Qualifying Dynamics 365 Base Offer", + "String_Id": "DYN365_FINANCE_ATTACH", + "GUID": "d721f2e4-099b-4105-b40e-872e46cad402", + "Service_Plan_Name": "DYN365_REGULATORY_SERVICE", + "Service_Plan_Id": "c7657ae3-c0b0-4eed-8c1d-6a7967bd9c65", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Finance and Operations, Enterprise edition - Regulatory Service" + }, + { + "Product_Display_Name": "Dynamics 365 for Finance Attach to Qualifying Dynamics 365 Base Offer", + "String_Id": "DYN365_FINANCE_ATTACH", + "GUID": "d721f2e4-099b-4105-b40e-872e46cad402", + "Service_Plan_Name": "D365_Finance_Attach", + "Service_Plan_Id": "223e33cb-eee0-462d-b1bd-e9a5febf8e85", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Finance Attach" + }, + { + "Product_Display_Name": "Dynamics 365 for Finance Attach to Qualifying Dynamics 365 Base Offer", + "String_Id": "DYN365_FINANCE_ATTACH", + "GUID": "d721f2e4-099b-4105-b40e-872e46cad402", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "D365_ProjectOperationsCDSAttach", + "Service_Plan_Id": "e564d403-7eaf-4c91-b92f-bb0dc62026e1", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Project Operations CDS Attach" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "CDS_AI_Capacity_FI", + "Service_Plan_Id": "5d85ec34-44e5-43b6-a9aa-d1b4c1d3aa3b", + "Service_Plans_Included_Friendly_Names": "AI Builder Capacity Add-on" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "D365_Finance_Attach", + "Service_Plan_Id": "223e33cb-eee0-462d-b1bd-e9a5febf8e85", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Finance Attach" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "D365_ProjectOperationsAttach", + "Service_Plan_Id": "fa7675bd-6717-40e7-8172-d0bbcbe1ab12", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Project Operations Attach" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "PROJECT_FOR_PROJECT_OPERATIONS_ATTACH", + "Service_Plan_Id": "6d8e07c6-9613-484f-8cc1-a66c5c3979bb", + "Service_Plans_Included_Friendly_Names": "Project for Project Operations Attach" + }, + { + "Product_Display_Name": "Dynamics 365 Finance Attach to Qualifying Base Offer Embedded with Project Management & Accounting", + "String_Id": "DYN365_FINANCE_ATTACH_ISVEMB_PROJOPS", + "GUID": "db5bd06c-b99a-4c54-98e9-90fea5164c88", + "Service_Plan_Name": "SHAREPOINTSTANDARD", + "Service_Plan_Id": "c7699d2e-19aa-44de-8edf-1736da088ca1", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 1)" + }, { "Product_Display_Name": "Dynamics 365 for Case Management Enterprise Edition", "String_Id": "DYN365_ENTERPRISE_CASE_MANAGEMENT", @@ -2263,6 +2439,454 @@ "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "DYN365_CC", + "Service_Plan_Id": "2a9d72b3-1714-440f-babf-bf92bf9683d8", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Contact Center" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "DYN365_CS_MESSAGING_TPS", + "Service_Plan_Id": "47c2b191-a5fb-4129-b690-00c474d2f623", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Customer Service Digital Messaging add-on" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "DYN365_CS_VOICE", + "Service_Plan_Id": "f6ec6dfa-2402-468d-a455-89be11116d43", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Customer Service Voice Add-in" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "POWER_VIRTUAL_AGENTS_D365_CS_VOICE", + "Service_Plan_Id": "a3dce1be-e9ca-453a-9483-e69a5b46ce98", + "Service_Plans_Included_Friendly_Names": "Power Virtual Agents for Customer Service Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "SHAREPOINTWAC", + "Service_Plan_Id": "e95bec33-7c88-4a70-8e19-b10bd9d0c014", + "Service_Plans_Included_Friendly_Names": "Office for the Web" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "SHAREPOINTENTERPRISE", + "Service_Plan_Id": "5dbe027f-2339-4123-9542-606e4d348a72", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 2)" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center", + "String_Id": "DYNAMICS_365_CONTACT_CENTER", + "GUID": "dfb1700c-013e-4132-8bce-0d319c43a95d", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "DYN365_CC", + "Service_Plan_Id": "2a9d72b3-1714-440f-babf-bf92bf9683d8", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Contact Center" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "DYN365_CS_MESSAGING_TPS", + "Service_Plan_Id": "47c2b191-a5fb-4129-b690-00c474d2f623", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Customer Service Digital Messaging add-on" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "DYN365_CS_VOICE", + "Service_Plan_Id": "f6ec6dfa-2402-468d-a455-89be11116d43", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Customer Service Voice Add-in" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "POWER_VIRTUAL_AGENTS_D365_CS_VOICE", + "Service_Plan_Id": "a3dce1be-e9ca-453a-9483-e69a5b46ce98", + "Service_Plans_Included_Friendly_Names": "Power Virtual Agents for Customer Service Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "SHAREPOINTWAC", + "Service_Plan_Id": "e95bec33-7c88-4a70-8e19-b10bd9d0c014", + "Service_Plans_Included_Friendly_Names": "Office for the Web" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "SHAREPOINTENTERPRISE", + "Service_Plan_Id": "5dbe027f-2339-4123-9542-606e4d348a72", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 2)" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "39a78eb6-3a8a-4e1e-878a-575a5c8984e7", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "DYN365_CC_DIGITAL", + "Service_Plan_Id": "0ef2b4e3-0a2b-450d-8c5f-a52203c40f50", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Contact Center Digital" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "DYN365_CS_MESSAGING_TPS", + "Service_Plan_Id": "47c2b191-a5fb-4129-b690-00c474d2f623", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Customer Service Digital Messaging add-on" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "DYN365_CS_MESSAGING", + "Service_Plan_Id": "43b076f2-1123-45ba-a339-2e170ee58c53", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Customer Service Digital Messaging Application Integration" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "SHAREPOINTWAC", + "Service_Plan_Id": "e95bec33-7c88-4a70-8e19-b10bd9d0c014", + "Service_Plans_Included_Friendly_Names": "Office for the Web" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "SHAREPOINTENTERPRISE", + "Service_Plan_Id": "5dbe027f-2339-4123-9542-606e4d348a72", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 2)" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL", + "GUID": "59d3d0bf-df39-4b8b-8601-ea6c09a7fd66", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "DYN365_CC_DIGITAL", + "Service_Plan_Id": "0ef2b4e3-0a2b-450d-8c5f-a52203c40f50", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Contact Center Digital" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "DYN365_CS_MESSAGING_TPS", + "Service_Plan_Id": "47c2b191-a5fb-4129-b690-00c474d2f623", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Customer Service Digital Messaging add-on" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "DYN365_CS_MESSAGING", + "Service_Plan_Id": "43b076f2-1123-45ba-a339-2e170ee58c53", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Customer Service Digital Messaging Application Integration" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "SHAREPOINTWAC", + "Service_Plan_Id": "e95bec33-7c88-4a70-8e19-b10bd9d0c014", + "Service_Plans_Included_Friendly_Names": "Office for the Web" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "SHAREPOINTENTERPRISE", + "Service_Plan_Id": "5dbe027f-2339-4123-9542-606e4d348a72", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 2)" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Digital Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_DIGITAL_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "7e6e6091-1680-4532-9370-6cd4598483ac", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "DYN365_CC_VOICE", + "Service_Plan_Id": "57517633-b4ad-4db8-8c1a-65f443424490", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Contact Center Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "DYN365_CS_VOICE", + "Service_Plan_Id": "f6ec6dfa-2402-468d-a455-89be11116d43", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Customer Service Voice Add-in" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "POWER_VIRTUAL_AGENTS_D365_CS_VOICE", + "Service_Plan_Id": "a3dce1be-e9ca-453a-9483-e69a5b46ce98", + "Service_Plans_Included_Friendly_Names": "Power Virtual Agents for Customer Service Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "SHAREPOINTWAC", + "Service_Plan_Id": "e95bec33-7c88-4a70-8e19-b10bd9d0c014", + "Service_Plans_Included_Friendly_Names": "Office for the Web" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "SHAREPOINTENTERPRISE", + "Service_Plan_Id": "5dbe027f-2339-4123-9542-606e4d348a72", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 2)" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE", + "GUID": "79e2368c-4568-48d5-a352-b0344afabcf8", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "DYN365_CC_VOICE", + "Service_Plan_Id": "57517633-b4ad-4db8-8c1a-65f443424490", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Contact Center Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "DYN365_CS_VOICE", + "Service_Plan_Id": "f6ec6dfa-2402-468d-a455-89be11116d43", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Customer Service Voice Add-in" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "POWER_VIRTUAL_AGENTS_D365_CS_VOICE", + "Service_Plan_Id": "a3dce1be-e9ca-453a-9483-e69a5b46ce98", + "Service_Plans_Included_Friendly_Names": "Power Virtual Agents for Customer Service Voice" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "SHAREPOINTWAC", + "Service_Plan_Id": "e95bec33-7c88-4a70-8e19-b10bd9d0c014", + "Service_Plans_Included_Friendly_Names": "Office for the Web" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "SHAREPOINTENTERPRISE", + "Service_Plan_Id": "5dbe027f-2339-4123-9542-606e4d348a72", + "Service_Plans_Included_Friendly_Names": "SharePoint (Plan 2)" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Contact Center Voice Add-on for Customer Service Enterprise", + "String_Id": "DYNAMICS_365_CONTACT_CENTER_VOICE_ADD_ON_FOR_CUSTOMER_SERVICE_ENTERPRISE", + "GUID": "73e8b747-20bf-463d-8ffd-274a7d65d0bc", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, { "Product_Display_Name": "Dynamics 365 for Customer Service Chat", "String_Id": "DYN365_CS_CHAT", @@ -3215,6 +3839,78 @@ "Service_Plan_Id": "3089c02b-e533-4b73-96a5-01fa648c3c3c", "Service_Plans_Included_Friendly_Names": "PowerApps for Dynamics 365 for Government" }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "DYN365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "Service_Plan_Id": "1d8c8e0e-4308-4db5-8a41-b129dbdaea20", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Project Service Automation for Government" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "Forms_Pro_PS_GCC", + "Service_Plan_Id": "e98256c5-17d0-4987-becc-e991c52d55c6", + "Service_Plans_Included_Friendly_Names": "Microsoft Dynamics 365 Customer Voice for Project Service Automation for GCC" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION_GOV", + "Service_Plan_Id": "922ba911-5694-4e99-a794-73aed9bfeec8", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation for Government" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "SHAREPOINTWAC_GOV", + "Service_Plan_Id": "8f9f0f3b-ca90-406c-a842-95579171f8ec", + "Service_Plans_Included_Friendly_Names": "Office for the Web for Government" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "PROJECT_CLIENT_SUBSCRIPTION_GOV", + "Service_Plan_Id": "45c6831b-ad74-4c7f-bd03-7c2b3fa39067", + "Service_Plans_Included_Friendly_Names": "Project Online Desktop Client" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "SHAREPOINT_PROJECT_GOV", + "Service_Plan_Id": "e57afa78-1f19-4542-ba13-b32cd4d8f472", + "Service_Plans_Included_Friendly_Names": "Project Online Service for Government" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "SHAREPOINTENTERPRISE_GOV", + "Service_Plan_Id": "153f85dd-d912-4762-af6c-d6e0fb4f6692", + "Service_Plans_Included_Friendly_Names": "SharePoint Plan 2G" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "FLOW_DYN_APPS_GOV", + "Service_Plan_Id": "2c6af4f1-e7b6-4d59-bbc8-eaa884f42d69", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365 for Government" + }, + { + "Product_Display_Name": "Dynamics 365 for Project Service Automation for Government", + "String_Id": "D365_ENTERPRISE_PROJECT_SERVICE_AUTOMATION_GOV", + "GUID": "6c827f0a-42cb-4cff-b1cd-f4104c16ede3", + "Service_Plan_Name": "POWERAPPS_DYN_APPS_GOV", + "Service_Plan_Id": "3089c02b-e533-4b73-96a5-01fa648c3c3c", + "Service_Plans_Included_Friendly_Names": "PowerApps for Dynamics 365 for Government" + }, { "Product_Display_Name": "Dynamics 365 for Sales and Customer Service Enterprise Edition", "String_Id": "DYN365_ENTERPRISE_SALES_CUSTOMERSERVICE", @@ -3927,6 +4623,110 @@ "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", "Service_Plans_Included_Friendly_Names": "POWERAPPS FOR DYNAMICS 365" }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "Power_Pages_Internal_User", + "Service_Plan_Id": "60bf28f9-2b70-4522-96f7-335f5e06c941", + "Service_Plans_Included_Friendly_Names": "Power Pages Internal User" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "DYN365_CDS_SUPPLYCHAINMANAGEMENT", + "Service_Plan_Id": "b6a8b974-2956-4e14-ae81-f0384c363528", + "Service_Plans_Included_Friendly_Names": "Common Data Service for Dynamics 365 Supply Chain Management" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "FLOW_FOR_IOM_USL", + "Service_Plan_Id": "9e6d1620-dce9-4655-8933-af8fa5bccc9c", + "Service_Plans_Included_Friendly_Names": "Data Integration for IOM with Power Automate USL" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "CDS_FOR_IOM", + "Service_Plan_Id": "2bb89402-51e9-4c5a-be33-e954a9dd1ba6", + "Service_Plans_Included_Friendly_Names": "Dataverse for IOM" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "D365_DemandPlanning", + "Service_Plan_Id": "e8b616eb-1a6d-42b4-84c7-b63870791349", + "Service_Plans_Included_Friendly_Names": "DO NOT USE - Dynamics 365 Supply Chain Management Premium" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "DYN365_REGULATORY_SERVICE", + "Service_Plan_Id": "c7657ae3-c0b0-4eed-8c1d-6a7967bd9c65", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Finance and Operations, Enterprise edition - Regulatory Service" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "D365_SCM", + "Service_Plan_Id": "1224eae4-0d91-474a-8a52-27ec96a63fe7", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 for Supply Chain Management" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "DYN365_IOM", + "Service_Plan_Id": "616cf6e2-f52f-4738-b463-10003061fcd3", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Intelligent Order Management" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "DYN365_IOM_USER", + "Service_Plan_Id": "81375e2f-5ef7-4773-96aa-e3279f50bd21", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Intelligent Order Management USL" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "D365_SCM_Premium", + "Service_Plan_Id": "0363c8e5-c30d-4d7c-a621-7b6cab5e0482", + "Service_Plans_Included_Friendly_Names": "Dynamics 365 Supply Chain Management Premium" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "POWERAPPS_DYN_APPS", + "Service_Plan_Id": "874fc546-6efe-4d22-90b8-5c4e7aa59f4b", + "Service_Plans_Included_Friendly_Names": "Power Apps for Dynamics 365" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION", + "Service_Plan_Id": "113feb6c-3fe4-4440-bddc-54d774bf0318", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation" + }, + { + "Product_Display_Name": "Dynamics 365 Supply Chain Management Premium", + "String_Id": "Dynamics_365_Supply_Chain_Management_Premium", + "GUID": "9467fd84-2758-4287-b1fa-6a908c441b8a", + "Service_Plan_Name": "FLOW_DYN_APPS", + "Service_Plan_Id": "7e6d7d78-73de-46ba-83b1-6d25117334ba", + "Service_Plans_Included_Friendly_Names": "Power Automate for Dynamics 365" + }, { "Product_Display_Name": "Dynamics 365 for Talent", "String_Id": "SKU_Dynamics_365_for_HCM_Trial", @@ -5263,6 +6063,22 @@ "Service_Plan_Id": "882e1d05-acd1-4ccb-8708-6ee03664b117", "Service_Plans_Included_Friendly_Names": "Mobile Device Management for Office 365" }, + { + "Product_Display_Name": "Exchange Online (Plan 2) for GCC", + "String_Id": "EXCHANGEENTERPRISE_GOV", + "GUID": "7be8dc28-4da4-4e6d-b9b9-c60f2806df8a", + "Service_Plan_Name": "EXCHANGE_S_ENTERPRISE_GOV", + "Service_Plan_Id": "8c3069c0-ccdb-44be-ab77-986203a67df2", + "Service_Plans_Included_Friendly_Names": "Exchange Online (Plan 2) for Government" + }, + { + "Product_Display_Name": "Exchange Online (Plan 2) for GCC", + "String_Id": "EXCHANGEENTERPRISE_GOV", + "GUID": "7be8dc28-4da4-4e6d-b9b9-c60f2806df8a", + "Service_Plan_Name": "INTUNE_O365", + "Service_Plan_Id": "882e1d05-acd1-4ccb-8708-6ee03664b117", + "Service_Plans_Included_Friendly_Names": "Mobile Device Management for Office 365" + }, { "Product_Display_Name": "Exchange Online (Plan 2)", "String_Id": "EXCHANGEENTERPRISE", @@ -5367,6 +6183,30 @@ "Service_Plan_Id": "326e2b78-9d27-42c9-8509-46c827743a17", "Service_Plans_Included_Friendly_Names": "Exchange Online Protection" }, + { + "Product_Display_Name": "Flow Plan 1 for Government", + "String_Id": "FLOW_P1_GOV", + "GUID": "2b3b0c87-36af-4d15-8124-04a691cc2546", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION_GOV", + "Service_Plan_Id": "922ba911-5694-4e99-a794-73aed9bfeec8", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation for Government" + }, + { + "Product_Display_Name": "Flow Plan 1 for Government", + "String_Id": "FLOW_P1_GOV", + "GUID": "2b3b0c87-36af-4d15-8124-04a691cc2546", + "Service_Plan_Name": "DYN365_CDS_P1_GOV", + "Service_Plan_Id": "ce361df2-f2a5-4713-953f-4050ba09aad8", + "Service_Plans_Included_Friendly_Names": "Common Data Service for Government" + }, + { + "Product_Display_Name": "Flow Plan 1 for Government", + "String_Id": "FLOW_P1_GOV", + "GUID": "2b3b0c87-36af-4d15-8124-04a691cc2546", + "Service_Plan_Name": "FLOW_P1_GOV", + "Service_Plan_Id": "774da41c-a8b3-47c1-8322-b9c1ab68be9f", + "Service_Plans_Included_Friendly_Names": "Power Automate (Plan 1) for Government" + }, { "Product_Display_Name": "Intune", "String_Id": "INTUNE_A", @@ -13079,6 +13919,102 @@ "Service_Plan_Id": "89f1c4c8-0878-40f7-804d-869c9128ab5d", "Service_Plans_Included_Friendly_Names": "Power Platform Connectors in Microsoft 365 Copilot" }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "COPILOT_STUDIO_IN_COPILOT_FOR_M365", + "Service_Plan_Id": "fe6c28b3-d468-44ea-bbd0-a10a5167435c", + "Service_Plans_Included_Friendly_Names": "Copilot Studio in Copilot for M365" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "GRAPH_CONNECTORS_COPILOT", + "Service_Plan_Id": "82d30987-df9b-4486-b146-198b21d164c7", + "Service_Plans_Included_Friendly_Names": "Graph Connectors in Microsoft 365 Copilot" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "M365_COPILOT_INTELLIGENT_SEARCH", + "Service_Plan_Id": "931e4a88-a67f-48b5-814f-16a5f1e6028d", + "Service_Plans_Included_Friendly_Names": "Intelligent Search" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "M365_COPILOT_SHAREPOINT", + "Service_Plan_Id": "0aedf20c-091d-420b-aadf-30c042609612", + "Service_Plans_Included_Friendly_Names": "Microsoft 365 Copilot for SharePoint" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "M365_COPILOT_TEAMS", + "Service_Plan_Id": "b95945de-b3bd-46db-8437-f2beb6ea2347", + "Service_Plans_Included_Friendly_Names": "Microsoft 365 Copilot in Microsoft Teams" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "M365_COPILOT_APPS", + "Service_Plan_Id": "a62f8878-de10-42f3-b68f-6149a25ceb97", + "Service_Plans_Included_Friendly_Names": "Microsoft 365 Copilot in Productivity Apps" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "Microsoft_Copilot_for_Sales", + "Service_Plan_Id": "a2194428-ead1-4fc1-bb81-ab8675125f42", + "Service_Plans_Included_Friendly_Names": "Microsoft Copilot for Sales" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "Microsoft_Copilot_for_Sales_PowerAutomate", + "Service_Plan_Id": "0c1c2af2-6c51-43c7-9c55-fa487ac147ff", + "Service_Plans_Included_Friendly_Names": "Microsoft Copilot for Sales with Power Automate" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "M365_COPILOT_BUSINESS_CHAT", + "Service_Plan_Id": "3f30311c-6b1e-48a4-ab79-725b469da960", + "Service_Plans_Included_Friendly_Names": "Microsoft Copilot with Graph-grounded chat" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "WORKPLACE_ANALYTICS_INSIGHTS_USER", + "Service_Plan_Id": "b622badb-1b45-48d5-920f-4b27a2c0996c", + "Service_Plans_Included_Friendly_Names": "Microsoft Viva Insights" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "WORKPLACE_ANALYTICS_INSIGHTS_BACKEND", + "Service_Plan_Id": "ff7b261f-d98b-415b-827c-42a3fdf015af", + "Service_Plans_Included_Friendly_Names": "Microsoft Viva Insights Backend" + }, + { + "Product_Display_Name": "Microsoft 365 Copilot for Sales", + "String_Id": "Microsoft_Copilot_for_Sales", + "GUID": "15f2e9fc-b782-4f73-bf51-81d8b7fff6f4", + "Service_Plan_Name": "M365_COPILOT_CONNECTORS", + "Service_Plan_Id": "89f1c4c8-0878-40f7-804d-869c9128ab5d", + "Service_Plans_Included_Friendly_Names": "Power Platform Connectors in Microsoft 365 Copilot" + }, { "Product_Display_Name": "Microsoft Copilot for Microsoft 365", "String_Id": "M365_Copilot", @@ -28743,6 +29679,22 @@ "Service_Plan_Id": "346d83bf-6fe6-42ca-b424-b9300d2e21bf", "Service_Plans_Included_Friendly_Names": "Microsoft 365 Domestic Calling Plan (240 min)" }, + { + "Product_Display_Name": "Microsoft Teams Domestic Calling Plan for GCC", + "String_Id": "MCOPSTN_1_GOV", + "GUID": "923f58ab-fca1-46a1-92f9-89fda21238a8", + "Service_Plan_Name": "MCOPSTN1_GOV", + "Service_Plan_Id": "3c8a8792-7866-409b-bb61-1b20ace0368b", + "Service_Plans_Included_Friendly_Names": "Domestic Calling Plan for Government" + }, + { + "Product_Display_Name": "Microsoft Teams Domestic Calling Plan for GCC", + "String_Id": "MCOPSTN_1_GOV", + "GUID": "923f58ab-fca1-46a1-92f9-89fda21238a8", + "Service_Plan_Name": "EXCHANGE_S_FOUNDATION_GOV", + "Service_Plan_Id": "922ba911-5694-4e99-a794-73aed9bfeec8", + "Service_Plans_Included_Friendly_Names": "Exchange Foundation for Government" + }, { "Product_Display_Name": "Microsoft Teams Essentials", "String_Id": "Teams_Ess", @@ -39109,7 +40061,7 @@ "GUID": "0f13a262-dc6f-4800-8dc6-a62f72c95fad", "Service_Plan_Name": "CDSAICAPACITY_PERUSER", "Service_Plan_Id": "91f50f7b-2204-4803-acac-5cf5668b8b39", - "Service_Plans_Included_Friendly_Names": "DO NOT USE - AI Builder capacity Per User add-on" + "Service_Plans_Included_Friendly_Names": "AI Builder capacity Per User add-on" }, { "Product_Display_Name": "PowerApps & Flow GCC Test - O365 & Dyn365 Plans", @@ -40311,6 +41263,22 @@ "Service_Plan_Id": "18e74ca2-b5f0-4802-9a8b-00d2ff1e8322", "Service_Plans_Included_Friendly_Names": "Power Pages Authenticated Users per site monthly capacity GCCH" }, + { + "Product_Display_Name": "Power Pages authenticated users T1 100 users/per site/month capacity pack CN_CN", + "String_Id": "Power Pages authenticated users T1_CN_CN", + "GUID": "9a3c2a19-06c0-41b1-b2ea-13528d7b2e17", + "Service_Plan_Name": "DV_PowerPages_Authenticated_User", + "Service_Plan_Id": "7aae746a-3463-4737-b295-3c1a16c31438", + "Service_Plans_Included_Friendly_Names": "Dataverse for Power Pages Authenticated users per site" + }, + { + "Product_Display_Name": "Power Pages authenticated users T1 100 users/per site/month capacity pack CN_CN", + "String_Id": "Power Pages authenticated users T1_CN_CN", + "GUID": "9a3c2a19-06c0-41b1-b2ea-13528d7b2e17", + "Service_Plan_Name": "PowerPages_Authenticated_User_CN", + "Service_Plan_Id": "967d9574-a076-4bb7-ab89-f41f64bc142e", + "Service_Plans_Included_Friendly_Names": "Power Pages Authenticated Users per site monthly capacity China" + }, { "Product_Display_Name": "Power Pages authenticated users T1 100 users/per site/month capacity pack_GCC", "String_Id": "Power_Pages_authenticated_users_T1_100_users/per_site/month_capacity_pack_GCC", diff --git a/src/data/alerts.json b/src/data/alerts.json index e71be4e1547f..a691815fa9bc 100644 --- a/src/data/alerts.json +++ b/src/data/alerts.json @@ -153,6 +153,10 @@ "name": "HuntressRogueApps", "label": "Alert on Huntress Rogue Apps detected", "recommendedRunInterval": "4h", - "description": "Huntress has provided a repository of known rogue apps that are commonly used in BEC, data exfiltration and other Microsoft 365 attacks. This alert will notify you if any of these apps are detected in the selected tenant(s). For more information, see https://huntresslabs.github.io/rogueapps/." + "description": "Huntress has provided a repository of known rogue apps that are commonly used in BEC, data exfiltration and other Microsoft 365 attacks. This alert will notify you if any of these apps are detected in the selected tenant(s). For more information, see https://huntresslabs.github.io/rogueapps/.", + "requiresInput": true, + "inputType": "switch", + "inputLabel": "Ignore Disabled Apps?", + "inputName": "IgnoreDisabledApps" } ] diff --git a/src/data/standards.json b/src/data/standards.json index 4dba29061348..a211c4a2cd13 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -1612,6 +1612,38 @@ "powershellEquivalent": "Set-OrganizationConfig -BookingsEnabled", "recommendedBy": [] }, + { + "name": "standards.EXODirectSend", + "cat": "Exchange Standards", + "tag": [], + "helpText": "Sets the state of Direct Send in Exchange Online. Direct Send allows applications to send emails directly to Exchange Online mailboxes as the tenants domains, without requiring authentication.", + "docsDescription": "Controls whether applications can use Direct Send to send emails directly to Exchange Online mailboxes as the tenants domains, without requiring authentication. A detailed explanation from Microsoft can be found [here.](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365)", + "addedComponent": [ + { + "type": "autoComplete", + "multiple": false, + "creatable": false, + "label": "Select value", + "name": "standards.EXODirectSend.state", + "options": [ + { + "label": "Enabled", + "value": "enabled" + }, + { + "label": "Disabled", + "value": "disabled" + } + ] + } + ], + "label": "Set Direct Send state", + "impact": "Medium Impact", + "impactColour": "warning", + "addedDate": "2025-05-28", + "powershellEquivalent": "Set-OrganizationConfig -RejectDirectSend $true/$false", + "recommendedBy": [] + }, { "name": "standards.DisableOutlookAddins", "cat": "Exchange Standards", @@ -4060,6 +4092,7 @@ { "name": "standards.ExchangeConnectorTemplate", "label": "Exchange Connector Template", + "cat": "Templates", "disabledFeatures": { "report": true, "warn": true, diff --git a/src/pages/_app.js b/src/pages/_app.js index 5b544487c04d..2f0a405111d9 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -34,8 +34,13 @@ import { usePathname } from "next/navigation"; import { useRouter } from "next/router"; import { persistQueryClient } from "@tanstack/react-query-persist-client"; import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; + +const ReactQueryDevtoolsProduction = React.lazy(() => + import("@tanstack/react-query-devtools/build/modern/production.js").then((d) => ({ + default: d.ReactQueryDevtools, + })) +); TimeAgo.addDefaultLocale(en); -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; const queryClient = new QueryClient(); const clientSideEmotionCache = createEmotionCache(); @@ -70,7 +75,7 @@ const App = (props) => { if (!queryKey || !queryKey.length) { return false; } - const queryKeyString = String(queryKey[0] || ''); + const queryKeyString = String(queryKey[0] || ""); const excludeFromPersisting = excludeQueryKeys.some((key) => queryKeyString.includes(key) ); @@ -178,7 +183,7 @@ const App = (props) => { {settings.isInitialized && settings?.showDevtools === true ? ( - + ) : null} diff --git a/src/pages/api-offline.js b/src/pages/api-offline.js new file mode 100644 index 000000000000..5870d6d4aaf6 --- /dev/null +++ b/src/pages/api-offline.js @@ -0,0 +1,168 @@ +import { + Box, + Button, + Container, + Stack, + Alert, + CircularProgress, + Typography, + SvgIcon, +} from "@mui/material"; +import { Grid } from "@mui/system"; +import Head from "next/head"; +import { useState, useEffect } from "react"; +import axios from "axios"; +import { CippImageCard } from "../components/CippCards/CippImageCard"; +import { XMarkIcon } from "@heroicons/react/24/outline"; +import { ErrorOutlineOutlined } from "@mui/icons-material"; + +const ApiOfflinePage = () => { + const [testingConnection, setTestingConnection] = useState(false); + const [testResult, setTestResult] = useState(null); + const [apiVersion, setApiVersion] = useState(null); + + // Check API version when component mounts + useEffect(() => { + const checkApiVersion = async () => { + try { + const response = await axios.get("/version.json", { timeout: 5000 }); + setApiVersion(response.data?.version || "Unknown"); + } catch (error) { + console.error("Failed to fetch API version:", error); + } + }; + + checkApiVersion(); + }, []); + + const handleTestConnection = async () => { + setTestingConnection(true); + setTestResult(null); + + try { + // Try to ping the API + const testCall = await axios.get("/api/me", { timeout: 45000 }); + console.log("API Test Call Response:", testCall); + if (!testCall.headers["content-type"]?.includes("application/json")) { + throw new Error("API did not return the expected response."); + } + setTestResult({ success: true, message: "Connection successful! Try refreshing the page." }); + } catch (error) { + let errorMessage = "Connection failed."; + + if (error.response) { + // Request was made and server responded with a status code outside of 2xx range + errorMessage = `API responded with status: ${error.response.status}`; + if (error.response.status === 404) { + errorMessage += + " (API endpoint not found, this can be the case if your Function App is on Version 7 or below)"; + } + } else if (error.request) { + // Request was made but no response received + errorMessage = "No response received from API. Check if your Function App is running."; + } else { + // Error in setting up the request + errorMessage = `Error: ${error.message}`; + } + + setTestResult({ success: false, message: errorMessage }); + } finally { + setTestingConnection(false); + } + }; + + // We're now using Typography components directly in the JSX + // instead of generating a help text string + + return ( + <> + + API Offline + + + + + + + + + + + CIPP API Unreachable + + } + text={ + + + The CIPP API appears to be offline or out of date. + {apiVersion && ( + + Frontend Version: {apiVersion} + + )} + + + + If you are self-hosting CIPP, please ensure your Function App is running and + up to date. If you are using the hosted version, please check your + subscription in GitHub. + + + } + linkText={testingConnection ? "Testing Connection..." : "Test API Connection"} + onButtonClick={handleTestConnection} + /> + + {testResult && ( + + + {testResult.message} + {testResult.success && ( + + )} + + + )} + + {testingConnection && ( + + + + )} + + + + + + + ); +}; + +export default ApiOfflinePage; diff --git a/src/pages/cipp/super-admin/cipp-roles/index.js b/src/pages/cipp/super-admin/cipp-roles/index.js index 9f2ea69fbfa5..5f0585c956d6 100644 --- a/src/pages/cipp/super-admin/cipp-roles/index.js +++ b/src/pages/cipp/super-admin/cipp-roles/index.js @@ -12,14 +12,10 @@ const Page = () => { - CIPP roles can be used to restrict permissions for users with the 'editor' or - 'readonly' roles in CIPP. They can be limited to a subset of tenants and API - permissions. To restrict direct API access, create a role with the name 'CIPP-API'. + CIPP roles can be used to restrict permissions for users with the 'editor' or 'readonly' + roles in CIPP. They can be limited to a subset of tenants and API permissions. To + restrict direct API access, create a role with the name 'CIPP-API'. - }> - This functionality is in beta and should be treated as such. The custom role must be - added to the user in SWA in conjunction with the base role. (e.g. editor,mycustomrole) - diff --git a/src/pages/email/spamfilter/list-quarantine-policies/index.js b/src/pages/email/spamfilter/list-quarantine-policies/index.js index 29be070c7f1f..fa301cb631f4 100644 --- a/src/pages/email/spamfilter/list-quarantine-policies/index.js +++ b/src/pages/email/spamfilter/list-quarantine-policies/index.js @@ -30,7 +30,7 @@ const Page = () => { const GlobalQuarantinePolicy = ApiGetCall({ url: "/api/ListQuarantinePolicy", data: { tenantFilter: currentTenant, type: "GlobalQuarantinePolicy" }, - queryKey: "GlobalQuarantinePolicy", + queryKey: `GlobalQuarantinePolicy-${currentTenant}`, }); // Get the policy data regardless of array or object @@ -304,7 +304,7 @@ const Page = () => { const infoBarData = [ { icon: , - data: globalQuarantineData?.EndUserSpamNotificationFrequency, + data: globalQuarantineData?.EndUserSpamNotificationFrequency ?? "n/a", name: "Notification Frequency", }, { @@ -390,7 +390,7 @@ const Page = () => { Name: "Name", Identity: "Guid", }, - relatedQueryKeys: ["GlobalQuarantinePolicy"], + relatedQueryKeys: [`GlobalQuarantinePolicy-${currentTenant}`], confirmText: "Are you sure you want to update Global Quarantine settings?", }} diff --git a/src/pages/endpoint/autopilot/list-profiles/add.jsx b/src/pages/endpoint/autopilot/list-profiles/add.jsx index 364e3fb19835..26fd85204b24 100644 --- a/src/pages/endpoint/autopilot/list-profiles/add.jsx +++ b/src/pages/endpoint/autopilot/list-profiles/add.jsx @@ -68,9 +68,9 @@ const AutopilotProfileForm = () => { type="autoComplete" label="Language" name="languages" - options={languageList.map(({ language, tag }) => ({ + options={languageList.map(({ language, tag, "Geographic area": geographicArea }) => ({ value: tag, - label: language, + label: `${language} - ${geographicArea}`, // Format as "language - geographic area" for display }))} formControl={formControl} multiple={false} diff --git a/src/pages/identity/administration/users/user/exchange.jsx b/src/pages/identity/administration/users/user/exchange.jsx index 2ce3578fa876..9f938ee29e7c 100644 --- a/src/pages/identity/administration/users/user/exchange.jsx +++ b/src/pages/identity/administration/users/user/exchange.jsx @@ -4,7 +4,7 @@ import { useRouter } from "next/router"; import { ApiGetCall } from "/src/api/ApiCall"; import CippFormSkeleton from "/src/components/CippFormPages/CippFormSkeleton"; import CalendarIcon from "@heroicons/react/24/outline/CalendarIcon"; -import { Check, Error, Mail, Fingerprint, Launch } from "@mui/icons-material"; +import { Check, Error, Mail, Fingerprint, Launch, Delete, Star, Close } from "@mui/icons-material"; import { HeaderedTabbedLayout } from "../../../../../layouts/HeaderedTabbedLayout"; import tabOptions from "./tabOptions"; import { CippTimeAgo } from "../../../../../components/CippComponents/CippTimeAgo"; @@ -16,18 +16,26 @@ import { CippExchangeInfoCard } from "../../../../../components/CippCards/CippEx import { useEffect, useState } from "react"; import CippExchangeSettingsForm from "../../../../../components/CippFormPages/CippExchangeSettingsForm"; import { useForm } from "react-hook-form"; -import { Alert, Button, Collapse, CircularProgress, Typography } from "@mui/material"; +import { Alert, Button, Collapse, CircularProgress, Typography, TextField, Dialog, DialogTitle, DialogContent, DialogActions, IconButton } from "@mui/material"; import { CippApiResults } from "../../../../../components/CippComponents/CippApiResults"; -import { Block, PlayArrow, DeleteForever } from "@mui/icons-material"; +import { Block, PlayArrow } from "@mui/icons-material"; import { CippPropertyListCard } from "../../../../../components/CippCards/CippPropertyListCard"; import { getCippTranslation } from "../../../../../utils/get-cipp-translation"; import { getCippFormatting } from "../../../../../utils/get-cipp-formatting"; import CippExchangeActions from "../../../../../components/CippComponents/CippExchangeActions"; +import { CippApiDialog } from "../../../../../components/CippComponents/CippApiDialog"; +import { useDialog } from "../../../../../hooks/use-dialog"; const Page = () => { const userSettingsDefaults = useSettings(); const [waiting, setWaiting] = useState(false); const [showDetails, setShowDetails] = useState(false); + const [actionData, setActionData] = useState({ ready: false }); + const [showAddAliasDialog, setShowAddAliasDialog] = useState(false); + const [newAliases, setNewAliases] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [submitResult, setSubmitResult] = useState(null); + const createDialog = useDialog(); const router = useRouter(); const { userId } = router.query; @@ -221,7 +229,7 @@ const Page = () => { { label: "Remove Mailbox Rule", type: "POST", - icon: , + icon: , url: "/api/ExecRemoveMailboxRule", data: { ruleId: "Identity", @@ -287,6 +295,142 @@ const Page = () => { }, ]; + const proxyAddressActions = [ + { + label: "Make Primary", + type: "POST", + icon: , + url: "/api/SetUserAliases", + data: { + id: userId, + tenantFilter: userSettingsDefaults.currentTenant, + MakePrimary: "Address", + }, + confirmText: "Are you sure you want to make this the primary proxy address?", + multiPost: false, + relatedQueryKeys: `ListUsers-${userId}`, + }, + { + label: "Remove Proxy Address", + type: "POST", + icon: , + url: "/api/SetUserAliases", + data: { + id: userId, + tenantFilter: userSettingsDefaults.currentTenant, + RemovedAliases: "Address", + }, + confirmText: "Are you sure you want to remove this proxy address?", + multiPost: false, + relatedQueryKeys: `ListUsers-${userId}`, + }, + ]; + + const handleAddAliases = () => { + const aliases = newAliases + .split('\n') + .map(alias => alias.trim()) + .filter(alias => alias); + if (aliases.length > 0) { + setIsSubmitting(true); + setSubmitResult(null); + fetch('/api/SetUserAliases', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: userId, + tenantFilter: userSettingsDefaults.currentTenant, + AddedAliases: aliases.join(','), + userPrincipalName: graphUserRequest.data?.[0]?.userPrincipalName, + }), + }) + .then(response => response.json()) + .then(data => { + setSubmitResult({ success: true, message: 'Aliases added successfully' }); + graphUserRequest.refetch(); + setTimeout(() => { + setShowAddAliasDialog(false); + setNewAliases(''); + setSubmitResult(null); + }, 1500); + }) + .catch(error => { + setSubmitResult({ success: false, message: 'Failed to add aliases' }); + }) + .finally(() => { + setIsSubmitting(false); + }); + } + }; + + const proxyAddressesCard = [ + { + id: 1, + cardLabelBox: { + cardLabelBoxHeader: graphUserRequest.isFetching ? ( + + ) : graphUserRequest.data?.[0]?.proxyAddresses?.length > 1 ? ( + + ) : ( + + ), + }, + text: "Current Proxy Addresses", + subtext: graphUserRequest.data?.[0]?.proxyAddresses?.length > 1 + ? "Proxy addresses are configured for this user" + : "No proxy addresses configured for this user", + statusColor: "green.main", + table: { + title: "Proxy Addresses", + hideTitle: true, + data: graphUserRequest.data?.[0]?.proxyAddresses?.map(address => ({ + Address: address, + Type: address.startsWith('SMTP:') ? 'Primary' : 'Alias', + })) || [], + refreshFunction: () => graphUserRequest.refetch(), + isFetching: graphUserRequest.isFetching, + simpleColumns: ["Address", "Type"], + actions: proxyAddressActions, + offCanvas: { + children: (data) => { + return ( + + ); + }, + }, + }, + children: ( + + + + ), + }, + ]; + return ( {
+ { )} + {actionData.ready && ( + + )} + setShowAddAliasDialog(false)} + maxWidth="sm" + fullWidth + > + + + Add Proxy Addresses + setShowAddAliasDialog(false)} size="small"> + + + + + + + setNewAliases(e.target.value)} + placeholder="One alias per line" + variant="outlined" + disabled={isSubmitting} + /> + {submitResult && ( + + {submitResult.message} + + )} + + + + + + + ); }; diff --git a/src/pages/loading.js b/src/pages/loading.js index a77fef84904a..930702aadc53 100644 --- a/src/pages/loading.js +++ b/src/pages/loading.js @@ -2,7 +2,7 @@ import { Box, Container, Stack } from "@mui/material"; import { Grid } from "@mui/system"; import Head from "next/head"; import { CippImageCard } from "../components/CippCards/CippImageCard"; -import { Layout as DashboardLayout } from "../layouts/index.js"; + import { ApiGetCall } from "../api/ApiCall"; import { useState, useEffect } from "react"; @@ -32,39 +32,37 @@ const Page = () => { return ( <> - - - Loading - - - - - - - - + + Loading + + + + + + + - - - - +
+ + + ); }; diff --git a/src/pages/teams-share/teams/list-team/add.jsx b/src/pages/teams-share/teams/list-team/add.jsx index 3d78e515ee0a..28a92cc6df65 100644 --- a/src/pages/teams-share/teams/list-team/add.jsx +++ b/src/pages/teams-share/teams/list-team/add.jsx @@ -28,6 +28,7 @@ const TeamsAddTeamForm = () => { title="Add Team" backButtonTitle="Teams Overview" postUrl="/api/AddTeam" + resetForm={true} customDataformatter={(values) => { const shippedValues = { tenantID: tenantDomain, diff --git a/src/pages/teams-share/teams/list-team/index.js b/src/pages/teams-share/teams/list-team/index.js index fb3580cc2622..1c1bb645a813 100644 --- a/src/pages/teams-share/teams/list-team/index.js +++ b/src/pages/teams-share/teams/list-team/index.js @@ -1,7 +1,7 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; import { Button } from "@mui/material"; -import { GroupAdd } from "@mui/icons-material"; +import { Delete, GroupAdd } from "@mui/icons-material"; import Link from "next/link"; import { Edit } from "@mui/icons-material"; @@ -16,6 +16,19 @@ const Page = () => { color: "warning", icon: , }, + { + label: "Delete Team", + type: "POST", + url: "/api/ExecGroupsDelete", + icon: , + data: { + ID: "id", + GroupType: "!Microsoft 365", + DisplayName: "displayName", + }, + confirmText: "Are you sure you want to delete this team?", + multiPost: false, + }, ]; return ( diff --git a/src/pages/tenant/administration/alert-configuration/alert.jsx b/src/pages/tenant/administration/alert-configuration/alert.jsx index 050a30ef4612..be33d8615a31 100644 --- a/src/pages/tenant/administration/alert-configuration/alert.jsx +++ b/src/pages/tenant/administration/alert-configuration/alert.jsx @@ -561,7 +561,7 @@ const AlertWizard = () => { diff --git a/src/pages/tenant/conditional/list-policies/index.js b/src/pages/tenant/conditional/list-policies/index.js index 8c021df61319..2c4a30d8b06f 100644 --- a/src/pages/tenant/conditional/list-policies/index.js +++ b/src/pages/tenant/conditional/list-policies/index.js @@ -84,7 +84,9 @@ const Page = () => { // Off-canvas configuration const offCanvas = { - children: (row) => , + children: (row) => ( + + ), size: "xl", }; diff --git a/src/pages/unauthenticated.js b/src/pages/unauthenticated.js index c9105b01fd6f..0c1808459687 100644 --- a/src/pages/unauthenticated.js +++ b/src/pages/unauthenticated.js @@ -2,7 +2,6 @@ import { Box, Container, Stack } from "@mui/material"; import { Grid } from "@mui/system"; import Head from "next/head"; import { CippImageCard } from "../components/CippCards/CippImageCard"; -import { Layout as DashboardLayout } from "../layouts/index.js"; import { ApiGetCall } from "../api/ApiCall"; import { useState, useEffect } from "react"; @@ -32,53 +31,51 @@ const Page = () => { }, [orgData, blockedRoles]); return ( <> - - - 401 - Access Denied - - - - - - - {(orgData.isSuccess || swaStatus.isSuccess) && Array.isArray(userRoles) && ( - 0 - ? "Return to Home" - : "Login" - } - link={ - swaStatus?.data?.clientPrincipal !== null && userRoles.length > 0 - ? "/" - : `/.auth/login/aad?post_login_redirect_uri=${encodeURIComponent( - window.location.href - )}` - } - /> - )} - + + 401 - Access Denied + + + + + + + {(orgData.isSuccess || swaStatus.isSuccess) && Array.isArray(userRoles) && ( + 0 + ? "Return to Home" + : "Login" + } + link={ + swaStatus?.data?.clientPrincipal !== null && userRoles.length > 0 + ? "/" + : `/.auth/login/aad?post_login_redirect_uri=${encodeURIComponent( + window.location.href + )}` + } + /> + )} - - - - + + + + ); };