diff --git a/package.json b/package.json index 06670325843f..05a3468c52e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cipp", - "version": "10.2.0", + "version": "10.2.1", "author": "CIPP Contributors", "homepage": "https://cipp.app/", "bugs": { diff --git a/public/version.json b/public/version.json index 7e488263a60c..6fafb4fbb418 100644 --- a/public/version.json +++ b/public/version.json @@ -1,3 +1,3 @@ { - "version": "10.2.0" + "version": "10.2.1" } \ No newline at end of file diff --git a/src/components/CippComponents/CippAddTenantGroupDrawer.jsx b/src/components/CippComponents/CippAddTenantGroupDrawer.jsx index 75804c15f89c..a82e0fd3f791 100644 --- a/src/components/CippComponents/CippAddTenantGroupDrawer.jsx +++ b/src/components/CippComponents/CippAddTenantGroupDrawer.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { Button, Box } from "@mui/material"; import { useForm, useFormState } from "react-hook-form"; import { GroupAdd } from "@mui/icons-material"; @@ -6,7 +6,6 @@ import { CippOffCanvas } from "./CippOffCanvas"; import { CippApiResults } from "./CippApiResults"; import { ApiPostCall } from "../../api/ApiCall"; import CippAddEditTenantGroups from "./CippAddEditTenantGroups"; -import { getCippValidator } from "../../utils/get-cipp-validator"; export const CippAddTenantGroupDrawer = ({ buttonText = "Add Tenant Group", diff --git a/src/components/CippFormPages/CippAddEditUser.jsx b/src/components/CippFormPages/CippAddEditUser.jsx index edcc5e7cb73c..b479cacd197a 100644 --- a/src/components/CippFormPages/CippAddEditUser.jsx +++ b/src/components/CippFormPages/CippAddEditUser.jsx @@ -112,6 +112,21 @@ const CippAddEditUser = (props) => { return username.toLowerCase(); }; + const validateOtherMails = (value) => { + if (!value || (Array.isArray(value) && value.length === 0)) { + return true; + } + + const emailList = (Array.isArray(value) ? value.join(",") : value) + .split(",") + .map((email) => email.trim()) + .filter(Boolean); + + const invalidEmail = emailList.find((email) => getCippValidator(email, "email") !== true); + + return !invalidEmail || `This is not a valid email: ${invalidEmail}`; + }; + useEffect(() => { //if watch.firstname changes, and watch.lastname changes, set displayname to firstname + lastname if (watcher.givenName && watcher.surname && formType === "add") { @@ -331,7 +346,6 @@ const CippAddEditUser = (props) => { setDisplayNameManuallySet(true); }} required={true} - validators={{ required: "Display Name is required" }} /> @@ -356,7 +370,6 @@ const CippAddEditUser = (props) => { setUsernameManuallySet(true); }} required={true} - validators={{ required: "Username is required" }} /> @@ -603,10 +616,10 @@ const CippAddEditUser = (props) => { !value || getCippValidator(value, "email") }} + validators={{ validate: validateOtherMails }} /> {userSettingsDefaults?.userAttributes diff --git a/src/layouts/config.js b/src/layouts/config.js index 78a9cd4ed9d5..41c2ce0ed418 100644 --- a/src/layouts/config.js +++ b/src/layouts/config.js @@ -741,6 +741,11 @@ export const nativeMenuItems = [ path: "/email/reports/calendar-permissions", permissions: ["Exchange.Mailbox.*"], }, + { + title: "Mailbox Forwarding", + path: "/email/reports/mailbox-forwarding", + permissions: ["Exchange.Mailbox.*"], + }, { title: "Anti-Phishing Filters", path: "/email/reports/antiphishing-filters", diff --git a/src/pages/email/reports/mailbox-forwarding/index.js b/src/pages/email/reports/mailbox-forwarding/index.js new file mode 100644 index 000000000000..008637df1a97 --- /dev/null +++ b/src/pages/email/reports/mailbox-forwarding/index.js @@ -0,0 +1,116 @@ +import { Layout as DashboardLayout } from "../../../../layouts/index.js"; +import { CippTablePage } from "../../../../components/CippComponents/CippTablePage.jsx"; +import { useState } from "react"; +import { Button, Alert, SvgIcon, IconButton, Tooltip } from "@mui/material"; +import { useSettings } from "../../../../hooks/use-settings"; +import { Stack } from "@mui/system"; +import { Sync, Info } from "@mui/icons-material"; +import { useDialog } from "../../../../hooks/use-dialog"; +import { CippApiDialog } from "../../../../components/CippComponents/CippApiDialog"; +import { CippQueueTracker } from "../../../../components/CippTable/CippQueueTracker"; + +const Page = () => { + const currentTenant = useSettings().currentTenant; + const syncDialog = useDialog(); + const [syncQueueId, setSyncQueueId] = useState(null); + + const isAllTenants = currentTenant === "AllTenants"; + + const columns = [ + ...(isAllTenants ? ["Tenant"] : []), + "UPN", + "DisplayName", + "RecipientTypeDetails", + "ForwardingType", + "ForwardTo", + "DeliverToMailboxAndForward", + "CacheTimestamp", + ]; + + const apiData = { + UseReportDB: true, + }; + + const filters = [ + { + filterName: "External Forwarding", + value: [{ id: "ForwardingType", value: "External" }], + type: "column", + }, + { + filterName: "Internal Forwarding", + value: [{ id: "ForwardingType", value: "Internal" }], + type: "column", + }, + ]; + + const pageActions = [ + + + + + + + + + , + ]; + + return ( + <> + {currentTenant && currentTenant !== "" ? ( + + ) : ( + Please select a tenant to view mailbox forwarding settings. + )} + { + if (result?.Metadata?.QueueId) { + setSyncQueueId(result.Metadata.QueueId); + } + }, + }} + /> + + ); +}; + +Page.getLayout = (page) => {page}; + +export default Page; diff --git a/src/pages/identity/administration/users/add.jsx b/src/pages/identity/administration/users/add.jsx index 28606efc90ba..46a8c07fac61 100644 --- a/src/pages/identity/administration/users/add.jsx +++ b/src/pages/identity/administration/users/add.jsx @@ -2,13 +2,13 @@ import { Box } from "@mui/material"; import CippFormPage from "../../../../components/CippFormPages/CippFormPage"; import { Layout as DashboardLayout } from "../../../../layouts/index.js"; import { useForm, useWatch } from "react-hook-form"; -import { CippFormUserSelector } from "../../../../components/CippComponents/CippFormUserSelector"; import { useSettings } from "../../../../hooks/use-settings"; import { useEffect } from "react"; import CippAddEditUser from "../../../../components/CippFormPages/CippAddEditUser"; const Page = () => { const userSettingsDefaults = useSettings(); + const tenantDomain = useSettings().currentTenant; const formControl = useForm({ mode: "onBlur", @@ -54,6 +54,7 @@ const Page = () => { title="User" backButtonTitle="User Overview" postUrl="/api/AddUser" + relatedQueryKeys={`Users - ${tenantDomain}`} >