From 0914f5406036f222374f5aad7acd6d692a4872b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 8 Oct 2025 19:37:52 +0200 Subject: [PATCH 01/13] Feat: Transport and Connector drawers --- .../CippComponents/CippAddConnectorDrawer.jsx | 166 ++++++++++++++++++ .../CippAddTransportRuleDrawer.jsx | 166 ++++++++++++++++++ .../email/transport/list-connectors/add.jsx | 89 ---------- .../email/transport/list-connectors/index.js | 32 ++-- src/pages/email/transport/list-rules/add.jsx | 89 ---------- src/pages/email/transport/list-rules/index.js | 51 ++---- 6 files changed, 368 insertions(+), 225 deletions(-) create mode 100644 src/components/CippComponents/CippAddConnectorDrawer.jsx create mode 100644 src/components/CippComponents/CippAddTransportRuleDrawer.jsx delete mode 100644 src/pages/email/transport/list-connectors/add.jsx delete mode 100644 src/pages/email/transport/list-rules/add.jsx diff --git a/src/components/CippComponents/CippAddConnectorDrawer.jsx b/src/components/CippComponents/CippAddConnectorDrawer.jsx new file mode 100644 index 000000000000..e08654239b14 --- /dev/null +++ b/src/components/CippComponents/CippAddConnectorDrawer.jsx @@ -0,0 +1,166 @@ +import { useState, useEffect } from "react"; +import { Button, Divider } from "@mui/material"; +import { Grid } from "@mui/system"; +import { useForm, useFormState, useWatch } from "react-hook-form"; +import { RocketLaunch } from "@mui/icons-material"; +import { CippOffCanvas } from "./CippOffCanvas"; +import CippFormComponent from "./CippFormComponent"; +import { CippFormTenantSelector } from "./CippFormTenantSelector"; +import { CippApiResults } from "./CippApiResults"; +import { ApiPostCall } from "../../api/ApiCall"; + +export const CippAddConnectorDrawer = ({ + buttonText = "Deploy Connector", + requiredPermissions = [], + PermissionButton = Button, +}) => { + const [drawerVisible, setDrawerVisible] = useState(false); + + const formControl = useForm({ + mode: "onChange", + defaultValues: { + selectedTenants: [], + TemplateList: null, + PowerShellCommand: "", + }, + }); + + const { isValid } = useFormState({ control: formControl.control }); + const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" }); + + const addConnector = ApiPostCall({ + urlFromData: true, + }); + + // Update PowerShellCommand when template is selected + useEffect(() => { + if (templateListVal?.value) { + formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal?.value)); + } + }, [templateListVal, formControl]); + + // Reset form fields on successful creation + useEffect(() => { + if (addConnector.isSuccess) { + const currentTenants = formControl.getValues("selectedTenants"); + formControl.reset({ + selectedTenants: currentTenants, + TemplateList: null, + PowerShellCommand: "", + }); + } + }, [addConnector.isSuccess, formControl]); + + const handleSubmit = () => { + formControl.trigger(); + // Check if the form is valid before proceeding + if (!isValid) { + return; + } + + const formData = formControl.getValues(); + + addConnector.mutate({ + url: "/api/AddExConnector", + data: formData, + }); + }; + + const handleCloseDrawer = () => { + setDrawerVisible(false); + formControl.reset({ + selectedTenants: [], + TemplateList: null, + PowerShellCommand: "", + }); + }; + + return ( + <> + setDrawerVisible(true)} + startIcon={} + > + {buttonText} + + + + + + } + > + + {/* Tenant Selector */} + + + + + + + {/* Template List */} + + option, + url: "/api/ListExconnectorTemplates", + }} + placeholder="Select a template or enter PowerShell JSON manually" + /> + + + + + {/* PowerShell Command */} + + + + + + + + + ); +}; diff --git a/src/components/CippComponents/CippAddTransportRuleDrawer.jsx b/src/components/CippComponents/CippAddTransportRuleDrawer.jsx new file mode 100644 index 000000000000..3e1ae78ce77f --- /dev/null +++ b/src/components/CippComponents/CippAddTransportRuleDrawer.jsx @@ -0,0 +1,166 @@ +import { useState, useEffect } from "react"; +import { Button, Divider } from "@mui/material"; +import { Grid } from "@mui/system"; +import { useForm, useFormState, useWatch } from "react-hook-form"; +import { RocketLaunch } from "@mui/icons-material"; +import { CippOffCanvas } from "./CippOffCanvas"; +import CippFormComponent from "./CippFormComponent"; +import { CippFormTenantSelector } from "./CippFormTenantSelector"; +import { CippApiResults } from "./CippApiResults"; +import { ApiPostCall } from "../../api/ApiCall"; + +export const CippAddTransportRuleDrawer = ({ + buttonText = "Deploy Transport Rule", + requiredPermissions = [], + PermissionButton = Button, +}) => { + const [drawerVisible, setDrawerVisible] = useState(false); + + const formControl = useForm({ + mode: "onChange", + defaultValues: { + selectedTenants: [], + TemplateList: null, + PowerShellCommand: "", + }, + }); + + const { isValid } = useFormState({ control: formControl.control }); + const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" }); + + const addTransportRule = ApiPostCall({ + urlFromData: true, + }); + + // Update PowerShellCommand when template is selected + useEffect(() => { + if (templateListVal?.value) { + formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal?.value)); + } + }, [templateListVal, formControl]); + + // Reset form fields on successful creation + useEffect(() => { + if (addTransportRule.isSuccess) { + const currentTenants = formControl.getValues("selectedTenants"); + formControl.reset({ + selectedTenants: currentTenants, + TemplateList: null, + PowerShellCommand: "", + }); + } + }, [addTransportRule.isSuccess, formControl]); + + const handleSubmit = () => { + formControl.trigger(); + // Check if the form is valid before proceeding + if (!isValid) { + return; + } + + const formData = formControl.getValues(); + + addTransportRule.mutate({ + url: "/api/AddTransportRule", + data: formData, + }); + }; + + const handleCloseDrawer = () => { + setDrawerVisible(false); + formControl.reset({ + selectedTenants: [], + TemplateList: null, + PowerShellCommand: "", + }); + }; + + return ( + <> + setDrawerVisible(true)} + startIcon={} + > + {buttonText} + + + + + + } + > + + {/* Tenant Selector */} + + + + + + + {/* Template List */} + + option, + url: "/api/ListTransportRulesTemplates", + }} + placeholder="Select a template or enter PowerShell JSON manually" + /> + + + + + {/* PowerShell Command */} + + + + + + + + + ); +}; diff --git a/src/pages/email/transport/list-connectors/add.jsx b/src/pages/email/transport/list-connectors/add.jsx deleted file mode 100644 index acd4f0c0a50f..000000000000 --- a/src/pages/email/transport/list-connectors/add.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import React, { useEffect } from "react"; -import { Divider } from "@mui/material"; -import { Grid } from "@mui/system"; -import { useForm, useWatch } from "react-hook-form"; -import { Layout as DashboardLayout } from "/src/layouts/index.js"; -import CippFormPage from "/src/components/CippFormPages/CippFormPage"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { CippFormTenantSelector } from "/src/components/CippComponents/CippFormTenantSelector"; - -const AddPolicy = () => { - const formControl = useForm({ - mode: "onChange", - defaultValues: { - selectedTenants: [], - TemplateList: null, - PowerShellCommand: "", - }, - }); - - const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" }); - - useEffect(() => { - if (templateListVal?.value) { - formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal?.value)); - } - }, [templateListVal, formControl]); - - return ( - - - - - - - - - {/* TemplateList */} - - option, - url: "/api/ListExconnectorTemplates", - }} - placeholder="Select a template or enter PowerShell JSON manually" - /> - - - - - - - - - - ); -}; - -AddPolicy.getLayout = (page) => {page}; - -export default AddPolicy; diff --git a/src/pages/email/transport/list-connectors/index.js b/src/pages/email/transport/list-connectors/index.js index fdb3ca7d92f4..4a3eeebcc84c 100644 --- a/src/pages/email/transport/list-connectors/index.js +++ b/src/pages/email/transport/list-connectors/index.js @@ -1,11 +1,11 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; -import { Button } from "@mui/material"; -import { RocketLaunch, Book, Check, Block, Delete } from "@mui/icons-material"; -import Link from "next/link"; +import { Book, Check, Block, Delete } from "@mui/icons-material"; +import { CippAddConnectorDrawer } from "../../../../components/CippComponents/CippAddConnectorDrawer"; const Page = () => { const pageTitle = "Connector List"; + const cardButtonPermissions = ["Exchange.Connector.ReadWrite"]; const actions = [ { @@ -72,6 +72,19 @@ const Page = () => { "TlsDomain", ]; + const filters = [ + { + filterName: "Inbound Connectors", + value: [{ id: "cippconnectortype", value: "Inbound" }], + type: "column", + }, + { + filterName: "Outbound Connectors", + value: [{ id: "cippconnectortype", value: "Outbound" }], + type: "column", + }, + ]; + const offCanvas = { extendedInfoFields: simpleColumns, actions: actions, @@ -83,18 +96,9 @@ const Page = () => { apiUrl="/api/ListExchangeConnectors" actions={actions} offCanvas={offCanvas} + filters={filters} simpleColumns={simpleColumns} - cardButton={ - <> - - - } + cardButton={} /> ); }; diff --git a/src/pages/email/transport/list-rules/add.jsx b/src/pages/email/transport/list-rules/add.jsx deleted file mode 100644 index e98931c56eda..000000000000 --- a/src/pages/email/transport/list-rules/add.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import React, { useEffect } from "react"; -import { Divider } from "@mui/material"; -import { Grid } from "@mui/system"; -import { useForm, useWatch } from "react-hook-form"; -import { Layout as DashboardLayout } from "/src/layouts/index.js"; -import CippFormPage from "/src/components/CippFormPages/CippFormPage"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { CippFormTenantSelector } from "/src/components/CippComponents/CippFormTenantSelector"; - -const AddPolicy = () => { - const formControl = useForm({ - mode: "onChange", - defaultValues: { - selectedTenants: [], - TemplateList: null, - PowerShellCommand: "", - }, - }); - - const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" }); - - useEffect(() => { - if (templateListVal?.value) { - formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal?.value)); - } - }, [templateListVal, formControl]); - - return ( - - - - - - - - - {/* TemplateList */} - - option, - url: "/api/ListTransportRulesTemplates", - }} - placeholder="Select a template or enter PowerShell JSON manually" - /> - - - - - - - - - - ); -}; - -AddPolicy.getLayout = (page) => {page}; - -export default AddPolicy; diff --git a/src/pages/email/transport/list-rules/index.js b/src/pages/email/transport/list-rules/index.js index db1fcf5a507e..6d1a1caddd5a 100644 --- a/src/pages/email/transport/list-rules/index.js +++ b/src/pages/email/transport/list-rules/index.js @@ -1,12 +1,12 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; -import { Button } from "@mui/material"; -import { Book, DoDisturb, Done, RocketLaunch } from "@mui/icons-material"; +import { Book, DoDisturb, Done } from "@mui/icons-material"; import { TrashIcon } from "@heroicons/react/24/outline"; -import Link from "next/link"; +import { CippAddTransportRuleDrawer } from "../../../../components/CippComponents/CippAddTransportRuleDrawer"; const Page = () => { const pageTitle = "Transport Rules"; + const cardButtonPermissions = ["Exchange.TransportRule.ReadWrite"]; const actions = [ { @@ -75,6 +75,19 @@ const Page = () => { "Tenant", ]; + const filters = [ + { + filterName: "Enabled Rules", + value: [{ id: "State", value: "Enabled" }], + type: "column", + }, + { + filterName: "Disabled Rules", + value: [{ id: "State", value: "Disabled" }], + type: "column", + }, + ]; + return ( { actions={actions} offCanvas={offCanvas} simpleColumns={simpleColumns} - filters={[ - { - filterName: "Enabled Rules", - value: [{ id: "State", value: "Enabled" }], - type: "column", - }, - { - filterName: "Disabled Rules", - value: [{ id: "State", value: "Disabled" }], - type: "column", - }, - ]} - cardButton={ - <> - - - - } + filters={filters} + cardButton={} /> ); }; From 670801302618bd0d39d95db0b1a25decedc1d6ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 9 Oct 2025 17:53:11 +0200 Subject: [PATCH 02/13] Feat: EDR only assignment and remove deprecated option --- .../security/defender/deployment/index.js | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/pages/security/defender/deployment/index.js b/src/pages/security/defender/deployment/index.js index 3ddb85e5d4cb..a7eb6dbfa7db 100644 --- a/src/pages/security/defender/deployment/index.js +++ b/src/pages/security/defender/deployment/index.js @@ -90,8 +90,8 @@ const DeployDefenderForm = () => { /> @@ -120,12 +120,6 @@ const DeployDefenderForm = () => { name="Compliance.ConnectIos" formControl={formControl} /> - { /> + + {/* EDR Assignment Section */} + + + EDR Assignment + + + + From a5060d84a4670d814cb6267b1d984340948f369a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 9 Oct 2025 19:30:20 +0200 Subject: [PATCH 03/13] ehm so this worked but i dont like it using the cal perms one of the contacts --- src/pages/identity/administration/users/user/exchange.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/identity/administration/users/user/exchange.jsx b/src/pages/identity/administration/users/user/exchange.jsx index 51b166385ef2..b81765ed651d 100644 --- a/src/pages/identity/administration/users/user/exchange.jsx +++ b/src/pages/identity/administration/users/user/exchange.jsx @@ -890,7 +890,7 @@ const Page = () => { label: "Remove Permission", type: "POST", icon: , - url: "/api/ExecModifyCalPerms", + url: "/api/ExecModifyContactPerms", data: { userID: graphUserRequest.data?.[0]?.userPrincipalName, tenantFilter: userSettingsDefaults.currentTenant, From 09ada40d82400bf37581821bbb9546330b8f35af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 9 Oct 2025 20:15:25 +0200 Subject: [PATCH 04/13] Enable multiple selections for user permissions in calendar and contact dialogs --- .../CippComponents/CippCalendarPermissionsDialog.jsx | 12 +++--------- .../CippComponents/CippContactPermissionsDialog.jsx | 8 ++------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/components/CippComponents/CippCalendarPermissionsDialog.jsx b/src/components/CippComponents/CippCalendarPermissionsDialog.jsx index 8cc9ad829ae3..33f31e21196f 100644 --- a/src/components/CippComponents/CippCalendarPermissionsDialog.jsx +++ b/src/components/CippComponents/CippCalendarPermissionsDialog.jsx @@ -33,15 +33,12 @@ const CippCalendarPermissionsDialog = ({ formHook, combinedOptions, isUserGroupL type="autoComplete" label="Add Access" name="UserToGetPermissions" - multiple={false} + multiple={true} formControl={formHook} isFetching={isUserGroupLoading} options={combinedOptions} creatable={false} - required={true} - validators={{ - validate: (value) => (value ? true : "Select a user or group to assign permissions to"), - }} + validators={{ required: "Select a user or group to assign permissions to" }} placeholder="Select a user or group to assign permissions to" /> @@ -50,11 +47,8 @@ const CippCalendarPermissionsDialog = ({ formHook, combinedOptions, isUserGroupL type="autoComplete" label="Permission Level" name="Permissions" - required={true} creatable={false} - validators={{ - validate: (value) => (value ? true : "Select the permission level for the calendar"), - }} + validators={{ required: "Select the permission level for the calendar" }} options={[ { value: "Author", label: "Author" }, { value: "Contributor", label: "Contributor" }, diff --git a/src/components/CippComponents/CippContactPermissionsDialog.jsx b/src/components/CippComponents/CippContactPermissionsDialog.jsx index ee554d6f2909..44e1ce303871 100644 --- a/src/components/CippComponents/CippContactPermissionsDialog.jsx +++ b/src/components/CippComponents/CippContactPermissionsDialog.jsx @@ -25,15 +25,12 @@ const CippContactPermissionsDialog = ({ formHook, combinedOptions, isUserGroupLo type="autoComplete" label="Add Access" name="UserToGetPermissions" - multiple={false} + multiple={true} formControl={formHook} isFetching={isUserGroupLoading} options={combinedOptions} creatable={false} - required={true} - validators={{ - validate: (value) => (value ? true : "Select a user or group to assign permissions to"), - }} + validators={{ required: "Select a user or group to assign permissions to" }} placeholder="Select a user or group to assign permissions to" /> @@ -42,7 +39,6 @@ const CippContactPermissionsDialog = ({ formHook, combinedOptions, isUserGroupLo type="autoComplete" label="Permission Level" name="Permissions" - required={true} creatable={false} validators={{ validate: (value) => (value ? true : "Select the permission level for the contact"), From bf9091c712177200c48348688536805d1ff0eb47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 9 Oct 2025 21:09:59 +0200 Subject: [PATCH 05/13] Feat: refactor proxy address adder to use domain selector --- .../CippComponents/CippAliasDialog.jsx | 74 +++++++++++++++---- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/src/components/CippComponents/CippAliasDialog.jsx b/src/components/CippComponents/CippAliasDialog.jsx index 1046a5bb1cac..7f6696054843 100644 --- a/src/components/CippComponents/CippAliasDialog.jsx +++ b/src/components/CippComponents/CippAliasDialog.jsx @@ -1,10 +1,11 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useMemo } from "react"; import { Typography, Box, Button, TextField, Chip, Stack } from "@mui/material"; import { Add } from "@mui/icons-material"; import { useWatch } from "react-hook-form"; +import { CippFormDomainSelector } from "./CippFormDomainSelector"; const CippAliasDialog = ({ formHook }) => { - const [newAlias, setNewAlias] = useState(""); + const [aliasPrefix, setAliasPrefix] = useState(""); // Initialize the form field if it doesn't exist useEffect(() => { @@ -21,15 +22,43 @@ const CippAliasDialog = ({ formHook }) => { defaultValue: [], }); + const selectedDomain = useWatch({ + control: formHook.control, + name: "AliasDomain", + }); + const isPending = formHook.formState.isSubmitting; + const selectedDomainValue = useMemo(() => { + if (!selectedDomain) return ""; + if (Array.isArray(selectedDomain)) { + return selectedDomain[0]?.value || selectedDomain[0] || ""; + } + if (typeof selectedDomain === "object") { + return selectedDomain?.value || ""; + } + return selectedDomain; + }, [selectedDomain]); + const handleAddAlias = () => { - if (newAlias.trim()) { - const currentAliases = formHook.getValues("AddedAliases") || []; - const newList = [...currentAliases, newAlias.trim()]; - formHook.setValue("AddedAliases", newList, { shouldValidate: true }); - setNewAlias(""); + const prefix = aliasPrefix.trim(); + const domain = selectedDomainValue; + + if (!prefix || !domain) { + return; + } + + const formattedAlias = `${prefix}@${domain}`; + const currentAliases = formHook.getValues("AddedAliases") || []; + + if (currentAliases.some((alias) => alias.toLowerCase() === formattedAlias.toLowerCase())) { + setAliasPrefix(""); + return; } + + const newList = [...currentAliases, formattedAlias]; + formHook.setValue("AddedAliases", newList, { shouldValidate: true }); + setAliasPrefix(""); }; const handleDeleteAlias = (aliasToDelete) => { @@ -49,16 +78,23 @@ const CippAliasDialog = ({ formHook }) => { <> - Add proxy addresses (aliases) for this user. Enter each alias and click Add or press - Enter. + Add proxy addresses (aliases) for this user. Enter a prefix, choose a verified tenant + domain, and click Add or press Enter. - + setNewAlias(e.target.value)} + value={aliasPrefix} + onChange={(e) => setAliasPrefix(e.target.value)} onKeyPress={handleKeyPress} - placeholder="Enter an alias" + placeholder="Enter alias prefix" variant="outlined" disabled={isPending} size="small" @@ -71,10 +107,20 @@ const CippAliasDialog = ({ formHook }) => { }, }} /> + + + + + } /> ); }; From 1c28afeb5e05eb3c4b7fd5dc0f638359ac76e99d Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 9 Oct 2025 23:35:44 -0400 Subject: [PATCH 07/13] extension sync rescheduling support implements FR https://github.com/KelvinTegelaar/CIPP/issues/4799 ticket # 30994418531 --- src/components/CippComponents/CippFormComponent.jsx | 5 +++++ src/data/Extensions.json | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/components/CippComponents/CippFormComponent.jsx b/src/components/CippComponents/CippFormComponent.jsx index af77e98ed1e1..2ca9d52d500a 100644 --- a/src/components/CippComponents/CippFormComponent.jsx +++ b/src/components/CippComponents/CippFormComponent.jsx @@ -611,6 +611,11 @@ export const CippFormComponent = (props) => { )} /> + {helperText && ( + + {helperText} + + )} {get(errors, convertedName, {})?.message} diff --git a/src/data/Extensions.json b/src/data/Extensions.json index f778868c163b..3009704f99cd 100644 --- a/src/data/Extensions.json +++ b/src/data/Extensions.json @@ -624,6 +624,18 @@ "compareType": "is", "compareValue": true } + }, + { + "type": "datePicker", + "name": "Hudu.NextSync", + "label": "Reschedule next sync date", + "helperText": "Set a future date to delay the next scheduled sync. Leave blank to sync during the next scheduled sync.", + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": true, From 2be9df4d5600861e20449566056656b233043535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 10 Oct 2025 08:01:59 +0200 Subject: [PATCH 08/13] Fix: replace deploy button with add connector drawer in exchange and transport rule templates --- .../list-connector-templates/index.js | 14 +++----------- .../email/transport/list-templates/index.js | 18 ++++-------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/pages/email/transport/list-connector-templates/index.js b/src/pages/email/transport/list-connector-templates/index.js index 75723a53422d..2e2b3e406959 100644 --- a/src/pages/email/transport/list-connector-templates/index.js +++ b/src/pages/email/transport/list-connector-templates/index.js @@ -6,10 +6,12 @@ import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx" import { TrashIcon } from "@heroicons/react/24/outline"; import { GitHub } from "@mui/icons-material"; import ConnectorTemplateDetails from "../../../../components/CippComponents/ConnectorTemplateDetails"; +import { CippAddConnectorDrawer } from "../../../../components/CippComponents/CippAddConnectorDrawer"; import { ApiGetCall } from "/src/api/ApiCall"; const Page = () => { const pageTitle = "Exchange Connector Templates"; + const cardButtonPermissions = ["Exchange.Connector.ReadWrite"]; const integrations = ApiGetCall({ url: "/api/ListExtensionsConfig", queryKey: "Integrations", @@ -93,17 +95,7 @@ const Page = () => { label: "Add Template", href: "/email/connectors/add-connector-templates", }} - cardButton={ - <> - - - } + cardButton={} /> ); }; diff --git a/src/pages/email/transport/list-templates/index.js b/src/pages/email/transport/list-templates/index.js index ea143610103f..0f4d417efeae 100644 --- a/src/pages/email/transport/list-templates/index.js +++ b/src/pages/email/transport/list-templates/index.js @@ -1,13 +1,13 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; import { TrashIcon } from "@heroicons/react/24/outline"; -import { Button } from "@mui/material"; -import { RocketLaunch, GitHub } from "@mui/icons-material"; -import Link from "next/link"; +import { GitHub } from "@mui/icons-material"; import { ApiGetCall } from "/src/api/ApiCall"; +import { CippAddTransportRuleDrawer } from "../../../../components/CippComponents/CippAddTransportRuleDrawer"; const Page = () => { const pageTitle = "Transport Rule Templates"; + const cardButtonPermissions = ["Exchange.TransportRule.ReadWrite"]; const integrations = ApiGetCall({ url: "/api/ListExtensionsConfig", queryKey: "Integrations", @@ -84,17 +84,7 @@ const Page = () => { actions={actions} offCanvas={offCanvas} simpleColumns={simpleColumns} - cardButton={ - <> - - - } + cardButton={ } /> ); }; From aa40986668675960bb26880bf3bd50cbb0b00f3f Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 10 Oct 2025 14:37:37 -0400 Subject: [PATCH 09/13] fix CA pollicy in executive summary fixes #4790 --- src/components/ExecutiveReportButton.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/ExecutiveReportButton.js b/src/components/ExecutiveReportButton.js index cbd26cc24968..e7d0cdde65de 100644 --- a/src/components/ExecutiveReportButton.js +++ b/src/components/ExecutiveReportButton.js @@ -2579,7 +2579,6 @@ export const ExecutiveReportButton = (props) => { data: { tenantFilter: settings.currentTenant, }, - dataKey: "Results", queryKey: `ca-policies-report-${settings.currentTenant}`, waiting: previewOpen, }); @@ -2663,7 +2662,7 @@ export const ExecutiveReportButton = (props) => { licensingData={licenseData.isSuccess ? licenseData?.data : null} deviceData={deviceData.isSuccess ? deviceData?.data : null} conditionalAccessData={ - conditionalAccessData.isSuccess ? conditionalAccessData?.data : null + conditionalAccessData.isSuccess ? conditionalAccessData?.data?.Results : null } standardsCompareData={standardsCompareData.isSuccess ? standardsCompareData?.data : null} driftComplianceData={driftComplianceData.isSuccess ? driftComplianceData?.data : null} @@ -3015,7 +3014,7 @@ export const ExecutiveReportButton = (props) => { licensingData={licenseData.isSuccess ? licenseData?.data : null} deviceData={deviceData.isSuccess ? deviceData?.data : null} conditionalAccessData={ - conditionalAccessData.isSuccess ? conditionalAccessData?.data : null + conditionalAccessData.isSuccess ? conditionalAccessData?.data?.Results : null } standardsCompareData={ standardsCompareData.isSuccess ? standardsCompareData?.data : null From a51323a93c36db77c80366b586c1c51cd4e30141 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 10 Oct 2025 15:13:45 -0400 Subject: [PATCH 10/13] fix backUrl fixes #4786 --- src/pages/tenant/manage/configuration-backup.js | 1 - src/pages/tenant/manage/drift.js | 1 - src/pages/tenant/manage/edit.js | 1 - src/pages/tenant/manage/history.js | 1 - src/pages/tenant/manage/recover-policies.js | 1 - 5 files changed, 5 deletions(-) diff --git a/src/pages/tenant/manage/configuration-backup.js b/src/pages/tenant/manage/configuration-backup.js index 0cf7dd569c72..8969f31ca4e4 100644 --- a/src/pages/tenant/manage/configuration-backup.js +++ b/src/pages/tenant/manage/configuration-backup.js @@ -182,7 +182,6 @@ const Page = () => { { tabOptions={tabOptions} title={title} subtitle={subtitle} - backUrl="/tenant/standards/list-standards" actions={actions} actionsData={{}} isFetching={driftApi.isFetching || standardsApi.isFetching || comparisonApi.isFetching} diff --git a/src/pages/tenant/manage/edit.js b/src/pages/tenant/manage/edit.js index a49d0afe00b8..8ab89052ca89 100644 --- a/src/pages/tenant/manage/edit.js +++ b/src/pages/tenant/manage/edit.js @@ -145,7 +145,6 @@ const Page = () => { { { tabOptions={tabOptions} title={title} subtitle={subtitle} - backUrl="/tenant/standards/list-standards" actions={actions} actionsData={{}} isFetching={recoverApi.isPending} From 6c6064b264bb4c552b52792e5f3444a79e8f1bf9 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 10 Oct 2025 16:53:35 -0400 Subject: [PATCH 11/13] allow page to load on alltenants fixes #4788 --- .../email/administration/tenant-allow-block-lists/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/email/administration/tenant-allow-block-lists/index.js b/src/pages/email/administration/tenant-allow-block-lists/index.js index bf0f3e3275bf..4770163895fa 100644 --- a/src/pages/email/administration/tenant-allow-block-lists/index.js +++ b/src/pages/email/administration/tenant-allow-block-lists/index.js @@ -58,5 +58,5 @@ const Page = () => { ); }; -Page.getLayout = (page) => {page}; +Page.getLayout = (page) => {page}; export default Page; From f415350079990a0c92942ef3bdc2f38b2a4eab4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 10 Oct 2025 23:08:22 +0200 Subject: [PATCH 12/13] Fix: reset form values on successful shared mailbox creation --- .../CippComponents/CippSharedMailboxDrawer.jsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/CippComponents/CippSharedMailboxDrawer.jsx b/src/components/CippComponents/CippSharedMailboxDrawer.jsx index 887c46ec1bd2..2efaed2a67f7 100644 --- a/src/components/CippComponents/CippSharedMailboxDrawer.jsx +++ b/src/components/CippComponents/CippSharedMailboxDrawer.jsx @@ -1,7 +1,6 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Button } from "@mui/material"; import { useForm } from "react-hook-form"; -import { Divider } from "@mui/material"; import { Add } from "@mui/icons-material"; import { CippOffCanvas } from "./CippOffCanvas"; import CippFormComponent from "./CippFormComponent"; @@ -57,6 +56,18 @@ export const CippSharedMailboxDrawer = ({ }); }; + // Reset form on successful creation, preserving the selected domain + useEffect(() => { + if (createSharedMailbox.isSuccess) { + const domain = formControl.getValues("domain"); + formControl.reset({ + displayName: "", + username: "", + domain: domain, + }); + } + }, [createSharedMailbox.isSuccess, formControl]); + return ( <> Date: Fri, 10 Oct 2025 18:27:46 -0400 Subject: [PATCH 13/13] up version --- package.json | 2 +- public/version.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f58b604c130a..c408d29c4b78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cipp", - "version": "8.5.1", + "version": "8.5.2", "author": "CIPP Contributors", "homepage": "https://cipp.app/", "bugs": { diff --git a/public/version.json b/public/version.json index f39cee3866d5..d0e25ec56792 100644 --- a/public/version.json +++ b/public/version.json @@ -1,3 +1,3 @@ { - "version": "8.5.1" -} + "version": "8.5.2" +} \ No newline at end of file