From 12c30565340fb4a22f949008f538237878645944 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 30 Oct 2023 12:13:38 -0400 Subject: [PATCH 01/23] GDAP Relationships - Add CA role check column - Switch filters to Complex type - Add new filters for Auto Extend --- .../administration/ListGDAPRelationships.js | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/views/tenant/administration/ListGDAPRelationships.js b/src/views/tenant/administration/ListGDAPRelationships.js index dcba0648a907..6ee6a8cfa07c 100644 --- a/src/views/tenant/administration/ListGDAPRelationships.js +++ b/src/views/tenant/administration/ListGDAPRelationships.js @@ -163,6 +163,17 @@ const GDAPRelationships = () => { exportSelector: 'endDateTime', cell: (row) => (row['autoExtendDuration'] === 'PT0S' ? 'No' : 'Yes'), }, + { + name: 'Includes CA Role', + selector: (row) => row?.accessDetails, + sortable: true, + cell: (row) => + row?.accessDetails?.unifiedRoles?.filter( + (e) => e.roleDefinitionId === '62e90394-69f5-4237-9190-012177145e10', + ).length > 0 + ? 'Yes' + : 'No', + }, { name: 'Actions', cell: Actions, @@ -178,9 +189,17 @@ const GDAPRelationships = () => { tenantSelector={false} datatable={{ filterlist: [ - { filterName: 'Active Relationships', filter: '"status":"active"' }, - { filterName: 'Terminated Relationships', filter: '"status":"Terminated"' }, + { filterName: 'Active Relationships', filter: 'Complex: status eq active' }, + { filterName: 'Terminated Relationships', filter: 'Complex: status eq terminated' }, { filterName: 'Pending Relationships', filter: 'Pending' }, + { + filterName: 'Active with Auto Extend', + filter: 'Complex: status eq active; autoExtendDuration ne PT0S', + }, + { + filterName: 'Active without Auto Extend', + filter: 'Complex: status eq active; autoExtendDuration eq PT0S', + }, ], tableProps: { selectableRows: true, From 7a52b0a42db1664daa8468815da8367ee354dd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 30 Oct 2023 20:17:51 +0100 Subject: [PATCH 02/23] All the link fixes in 1 commit --- .github/ISSUE_TEMPLATE/feature.yml | 2 +- .github/workflows/Close_Stale_Issues_and_PRs.yml | 2 +- .github/workflows/Comment_on_Issues.yml | 4 ++-- src/views/cipp/CIPPSettings.js | 2 +- src/views/endpoint/intune/MEMAddPolicy.js | 4 +++- src/views/tenant/administration/GDAPWizard.js | 6 +----- src/views/tenant/standards/ApplyStandard.js | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index af41440ebfc9..de839daf7a30 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -11,7 +11,7 @@ body: - Please search the existing feature request to see if there has been a similar issue filed. - - If a feature has been filed before, but not followed up by a contributor, you can develop the feature yourself by checking the development documentation [here](https://cipp.app/docs/dev/). + - If a feature has been filed before, but not followed up by a contributor, you can develop the feature yourself by checking the development documentation [here](https://docs.cipp.app/dev-documentation/cipp-dev-guide/setting-up-for-local-development). - Repeat feature requests are allowed if the previous request has been closed for more than 30 days diff --git a/.github/workflows/Close_Stale_Issues_and_PRs.yml b/.github/workflows/Close_Stale_Issues_and_PRs.yml index 7eff0bf2f619..35bd43d9f8f0 100644 --- a/.github/workflows/Close_Stale_Issues_and_PRs.yml +++ b/.github/workflows/Close_Stale_Issues_and_PRs.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/stale@v4 with: - stale-issue-message: 'This issue is stale because it has been open 10 days with no activity. We will close this issue soon. If you want this feature implemented you can contribute it. See: https://cipp.app/GettingStarted/Contributions/ . Please notify the team if you are working on this yourself.' + stale-issue-message: 'This issue is stale because it has been open 10 days with no activity. We will close this issue soon. If you want this feature implemented you can contribute it. See: https://docs.cipp.app/dev-documentation/contributing-to-the-code . Please notify the team if you are working on this yourself.' close-issue-message: 'This issue was closed because it has been stalled for 14 days with no activity.' stale-issue-label: 'no-activity' exempt-issue-labels: 'planned' diff --git a/.github/workflows/Comment_on_Issues.yml b/.github/workflows/Comment_on_Issues.yml index 6bd12f6a005b..c43a6c184869 100644 --- a/.github/workflows/Comment_on_Issues.yml +++ b/.github/workflows/Comment_on_Issues.yml @@ -16,7 +16,7 @@ jobs: with: issue-number: ${{ github.event.issue.number }} body: | - Thank you for creating a bug. Please make sure your bug is indeed a unique case by checking current and past issues, and reading the complete documentation at https://kelvintegelaar.github.io/CIPP + Thank you for creating a bug. Please make sure your bug is indeed a unique case by checking current and past issues, and reading the complete documentation at https://docs.cipp.app/ If your bug is a known documentation issue, it will be closed without notice by a contributor. To confirm that this is not a bug found in the documentation, please copy and paste the following comment: "I confirm that I have checked the documentation thoroughly and believe this to be an actual bug.". Without confirming, your report will be closed in 24 hours. If you'd like this bug to be assigned to you, please comment "I would like to work on this please!". @@ -35,5 +35,5 @@ jobs: Your current priority is set to "No Priority". No Priority Feature requests automatically get closed in two days if a contributor does not accept the FR. If you are a sponsor you can request an upgrade of priority. To upgrade the priority type "I would like to upgrade the priority". - If you want this feature to be integrated you can always do this yourself by checking out our contributions guide at https://cipp.app/docs/dev/. Contributors to the CIPP project reserve the right to close feature requests at will. + If you want this feature to be integrated you can always do this yourself by checking out our contributions guide at https://docs.cipp.app/dev-documentation/contributing-to-the-code. Contributors to the CIPP project reserve the right to close feature requests at will. If you'd like this feature request to be assigned to you, please comment "I would like to work on this please!". diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index 8c46d827521f..66c09666d7ec 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -402,7 +402,7 @@ const GeneralSettings = () => { documentation on how to add permissions{' '} here diff --git a/src/views/endpoint/intune/MEMAddPolicy.js b/src/views/endpoint/intune/MEMAddPolicy.js index f87f6b87dd2a..a564ce3d36db 100644 --- a/src/views/endpoint/intune/MEMAddPolicy.js +++ b/src/views/endpoint/intune/MEMAddPolicy.js @@ -130,7 +130,9 @@ const AddPolicy = () => {

Step 2

Enter the raw JSON for this policy. See{' '} - this for more + + this + {' '} information.
diff --git a/src/views/tenant/administration/GDAPWizard.js b/src/views/tenant/administration/GDAPWizard.js index 8722bde0b5f7..3c6147e7547d 100644 --- a/src/views/tenant/administration/GDAPWizard.js +++ b/src/views/tenant/administration/GDAPWizard.js @@ -54,11 +54,7 @@ const GDAPWizard = () => {
The GDAP migration tool requires setup. Please check the documentation{' '} - + here.

diff --git a/src/views/tenant/standards/ApplyStandard.js b/src/views/tenant/standards/ApplyStandard.js index 64d9fbf0ffce..2f84f99607ea 100644 --- a/src/views/tenant/standards/ApplyStandard.js +++ b/src/views/tenant/standards/ApplyStandard.js @@ -83,7 +83,7 @@ const ApplyStandard = () => { > Ensure you read{' '} - + the documentation fully {' '} before proceeding with this wizard. Some of the changes cannot be reverted by CIPP. From e79ed922ddd3b30a13b5618c6bf35deedeb989a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Bentsen=20Kj=C3=A6rg=C3=A5rd=20=28KBK=29?= Date: Wed, 1 Nov 2023 09:27:59 +0100 Subject: [PATCH 03/23] Fix wrongly used variable --- src/views/identity/administration/UserActions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/identity/administration/UserActions.js b/src/views/identity/administration/UserActions.js index 2a96415e0b15..774d27e481c3 100644 --- a/src/views/identity/administration/UserActions.js +++ b/src/views/identity/administration/UserActions.js @@ -31,7 +31,7 @@ export default function UserActions({ tenantDomain, userId, userEmail, className } const editLink = `/identity/administration/users/edit?tenantDomain=${tenantDomain}&userId=${userId}` - const editMailboxLink = `/email/administration/edit-mailbox-permissions?tenantDomain=${tenantDomain}&userId=${userId}` + const editMailboxLink = `/email/administration/edit-mailbox-permissions?tenantDomain=${tenantDomain}&userId=${userEmail}` const actions = [ { From 798dd658c1dca6d7115eb5814f347b85964aa420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 2 Nov 2023 00:24:54 +0100 Subject: [PATCH 04/23] Add hover help text to standards radio buttons --- src/data/standards.json | 46 +++++++++---------- .../tenant/standards/ListAppliedStandards.js | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/data/standards.json b/src/data/standards.json index 328a668fdc85..4e57829a0265 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -2,7 +2,7 @@ { "name": "standards.MailContacts.GeneralContact.Enabled", "cat": "Global", - "helpText": "", + "helpText": "Receives emails about updates about subscriptions etc", "addedComponent": { "type": "input", "name": "standards.MailContacts.GeneralContact.Mail", @@ -13,7 +13,7 @@ { "name": "standards.MailContacts.SecurityContact.Enabled", "cat": "Global", - "helpText": "", + "helpText": "Receives emails about security alerts or advisories by Microsoft", "addedComponent": { "type": "input", "name": "standards.MailContacts.SecurityContact.Mail", @@ -24,7 +24,7 @@ { "name": "standards.MailContacts.MarketingContact.Enabled", "cat": "Global", - "helpText": "", + "helpText": "Receives the emails related to marketing; new features etc", "addedComponent": { "type": "input", "name": "standards.MailContacts.MarketingContact.Mail", @@ -35,7 +35,7 @@ { "name": "standards.MailContacts.TechContact.Enabled", "cat": "Global", - "helpText": "", + "helpText": "Receives emails related to possible technical issues, service disruptions, etc", "addedComponent": { "type": "input", "name": "standards.MailContacts.TechContact.Mail", @@ -46,7 +46,7 @@ { "name": "standards.AuditLog", "cat": "Global", - "helpText": "", + "helpText": "Also runs Enable-OrganizationCustomization if needed", "addedComponent": null, "label": "Enable the Unified Audit Log" }, @@ -67,21 +67,21 @@ { "name": "standards.ModernAuth", "cat": "Global", - "helpText": "", + "helpText": "Modern Authentication is enabled by default. This standard is no longer required and can be safely disabled", "addedComponent": null, "label": "Enable Modern Authentication" }, { "name": "standards.DisableBasicAuth", "cat": "Global", - "helpText": "", + "helpText": "Basic Authentication is disabled by default. This standard is no longer required and can be safely disabled", "addedComponent": null, "label": "Disable Basic Authentication" }, { "name": "standards.DisableBasicAuthSMTP", "cat": "Global", - "helpText": "", + "helpText": "Disables SMTP AUTH for the organization. This is the default for new tenants. Can be overridden by enabling SMTP AUTH on specific users", "addedComponent": null, "label": "Disable SMTP Basic Authentication" }, @@ -95,14 +95,14 @@ { "name": "standards.PWnumberMatchingRequiredState", "cat": "AAD", - "helpText": "", + "helpText": "Passwordless with number matching is now enabled by default. This standard is no longer required and can be safely disabled", "addedComponent": null, "label": "Enable Passwordless with Number Matching" }, { "cat": "AAD", "name": "standards.PWdisplayAppInformationRequiredState", - "helpText": "", + "helpText": "Enables the MS authenticator app to display information about the app that is requesting authentication", "addedComponent": null, "label": "Enable Passwordless with Location information and Number Matching" }, @@ -151,21 +151,21 @@ { "cat": "AAD", "name": "standards.SecurityDefaults", - "helpText": "", + "helpText": "Enables security defaults for the tenant. This has a lot of implications and should be carefully considered before enabling", "addedComponent": null, "label": "Enable Security Defaults" }, { "cat": "AAD", "name": "standards.PasswordExpireDisabled", - "helpText": "", + "helpText": "Disables the expiration of passwords for the tenant", "addedComponent": null, "label": "Do not expire passwords" }, { "cat": "AAD", "name": "standards.DisableSecurityGroupUsers", - "helpText": "", + "helpText": "Completely disables the creation of security groups by users. This also breaks the ability to manage groups themselves, or create Teams", "addedComponent": null, "label": "Disable Security Group creation by users" }, @@ -210,14 +210,14 @@ { "cat": "AAD", "name": "standards.NudgeMFA.enable", - "helpText": "", + "helpText": "Enables registration campaign for the tenant", "addedComponent": null, "label": "Request to setup Authenticator if not setup yet." }, { "cat": "AAD", "name": "standards.NudgeMFA.disable", - "helpText": "", + "helpText": "Disables registration campaign for the tenant", "addedComponent": null, "label": "Disables the request to setup Authenticator if setup." }, @@ -238,7 +238,7 @@ { "cat": "AAD", "name": "standards.UndoOauth", - "helpText": "", + "helpText": "Disables App consent and set to Allow user consent for apps", "addedComponent": null, "label": "Undo App Consent Standard" }, @@ -252,7 +252,7 @@ { "cat": "AAD", "name": "standards.EnableFIDO2", - "helpText": "", + "helpText": "Enables the FIDO2 authenticationMethod for the tenant", "addedComponent": null, "label": "Enable FIDO2 capabilities" }, @@ -298,14 +298,14 @@ { "name": "standards.AutoExpandArchive", "cat": "Exchange", - "helpText": "", + "helpText": "Enables auto-expanding archives for the tenant", "addedComponent": null, "label": "Enable Auto-expanding archives" }, { "name": "standards.SpoofWarn.enable", "cat": "Exchange", - "helpText": "", + "helpText": "Adds indicators to e-mail messages received from external senders in Outlook. Works on all Outlook clients/OWA", "addedComponent": null, "label": "Enable Spoofing warnings for Outlook (This e-mail is external identifiers)" }, @@ -340,7 +340,7 @@ { "name": "standards.ActivityBasedTimeout", "cat": "Global", - "helpText": "", + "helpText": "Enables and sets Idle session timeout for Microsoft 365 to 1 hour. This policy affects most M365 web apps", "addedComponent": null, "label": "Enable 1 hour Activity based Timeout" }, @@ -414,7 +414,7 @@ { "name": "standards.intuneDeviceRetirementDays.Enabled", "cat": "Intune", - "helpText": "", + "helpText": "A value between 0 and 270 is supported. A value of 0 disables retirement.", "addedComponent": { "type": "input", "name": "standards.intuneDeviceRetirementDays.days", @@ -485,14 +485,14 @@ { "name": "standards.DeletedUserRentention", "cat": "SharePoint", - "helpText": "", + "helpText": "Sets the retenton period for deleted users OneDrive to 1 year/365 days", "addedComponent": null, "label": "Retain a deleted user OneDrive for 1 year" }, { "name": "standards.DisableUserSiteCreate", "cat": "SharePoint", - "helpText": "", + "helpText": "Disables users from creating new SharePoint sites", "addedComponent": null, "label": "Disable site creation by standard users" }, diff --git a/src/views/tenant/standards/ListAppliedStandards.js b/src/views/tenant/standards/ListAppliedStandards.js index d22f03d05862..ed0c7856a40a 100644 --- a/src/views/tenant/standards/ListAppliedStandards.js +++ b/src/views/tenant/standards/ListAppliedStandards.js @@ -514,7 +514,7 @@ const ListAppliedStandards = () => { name: template.name, }))} placeholder="Select a template" - label="Choose your Transport Rule templates to apply" + label="Choose your Exchange Connector templates to apply" /> )} From 33582cf3fbd781c5fe774ed490646df91c37427e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 2 Nov 2023 16:14:09 +0100 Subject: [PATCH 05/23] required field marker --- src/components/forms/RFFComponents.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/forms/RFFComponents.js b/src/components/forms/RFFComponents.js index 5365819e6623..414a472b6c82 100644 --- a/src/components/forms/RFFComponents.js +++ b/src/components/forms/RFFComponents.js @@ -420,7 +420,7 @@ export const RFFSelectSearch = ({ isMulti={multi} /> )} - + {meta.error && meta.touched && {meta.error}} ) }} From f2376defc14f05558c01aafd24c6d345921a6070 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 2 Nov 2023 17:02:00 +0100 Subject: [PATCH 06/23] added frontend changes --- src/views/cipp/CIPPSettings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index 66c09666d7ec..b8ad4330c463 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -452,13 +452,13 @@ const GeneralSettings = () => { <> p['@odata.type'] == '#microsoft.graph.group', )} title="Groups" /> p['@odata.type'] == '#microsoft.graph.directoryRole', )} title="Roles" From 6cc21e1e9be354820e9b45d5d5e46e00a93aeea7 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 2 Nov 2023 17:23:59 +0100 Subject: [PATCH 07/23] improved text --- src/views/cipp/CIPPSettings.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index b8ad4330c463..b242ee5257cd 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -416,7 +416,9 @@ const GeneralSettings = () => { )} {permissionsResult.data.Results?.MissingGroups.length > 0 && ( <> - Your SAM User is missing the following group memberships. + Your SAM User is missing the following group memberships. If you have setup + GDAP outside of CIPP, execute an access check to confirm access and role + availability to your tenants {permissionsResult.data.Results?.MissingGroups?.map((r, index) => ( {r} @@ -426,7 +428,7 @@ const GeneralSettings = () => { )} {permissionsResult.data.Results?.CIPPGroupCount == 0 && ( <> - NOTE: Your M365 GDAP groups were not set up by CIPP. Please check the groups + NOTE: Your GDAP groups were not set up by CIPP. Please check the groups below to see if you have the correct GDAP permissions, or execute an access check. From 5a49ac5e9b59de142160bbff4b942012d00801d1 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 2 Nov 2023 22:58:47 +0100 Subject: [PATCH 08/23] fixed wizard bug by improving text --- src/views/cipp/Setup.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/cipp/Setup.js b/src/views/cipp/Setup.js index 82da760206e7..e8d9a33d3064 100644 --- a/src/views/cipp/Setup.js +++ b/src/views/cipp/Setup.js @@ -51,7 +51,7 @@ const Setup = () => { const valbutton = (value) => getResults.data?.step < 5 ? undefined - : `You must finish the setup process. you are currently at step ${getResults.data?.step} of 5.` + : `You do not have to click next. Finish the wizard via the setup button below. After it says "Setup Completed" you may browse away from this page.` const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery() const [genericGetRequest, getResults] = useLazyGenericGetRequestQuery() const onSubmit = (values) => { @@ -159,14 +159,14 @@ const Setup = () => { Please use a Global Administrator to perform these tasks. You can restart the process at any time, by clicking on the start button once more.

- + startCIPPSetup(true)} - validate={valbutton} + validate={() => valbutton()} > Start Setup Wizard From 51dccd8f64e41c442c590d8a25bc36a83b94fc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Bentsen=20Kj=C3=A6rg=C3=A5rd=20=28KBK=29?= Date: Fri, 3 Nov 2023 10:06:38 +0100 Subject: [PATCH 09/23] Fix caldefaults LimitedDetails and AvailabilityOnly --- src/data/standards.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/data/standards.json b/src/data/standards.json index 328a668fdc85..2db75bc38816 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -371,12 +371,12 @@ "value": "Contributor" }, { - "label": "Free Busy Time And Subject And Location - The user can view free/busy time within the calendar and the subject and location of appointments.", - "value": "FreeBusyTimeAndSubjectAndLocation" + "label": "Limited Details - The user can view free/busy time within the calendar and the subject and location of appointments.", + "value": "LimitedDetails" }, { - "label": "Indicates that the user can view only free/busy time within the calendar.", - "value": "FreeBusyTimeOnly" + "label": "Availability Only - Indicates that the user can view only free/busy time within the calendar.", + "value": "AvailabilityOnly" }, { "label": "None - The user has no permissions on the folder.", From 07e6de8b8d6c6c0ec30f75dc61e20b757172088e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 15:53:18 +0100 Subject: [PATCH 10/23] improved access checks --- src/views/cipp/CIPPSettings.js | 389 ++++++++++++++++++--------------- 1 file changed, 210 insertions(+), 179 deletions(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index b242ee5257cd..385075a06fc2 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -151,9 +151,10 @@ const CIPPSettings = () => { export default CIPPSettings const GeneralSettings = () => { - const { data: versions, isSuccess: isSuccessVersion } = useLoadVersionsQuery() const { data: tenants = [] } = useListTenantsQuery({ AllTenantSelector: false }) const [checkPermissions, permissionsResult] = useLazyExecPermissionsAccessCheckQuery() + const [checkGDAP, GDAPResult] = useLazyGenericGetRequestQuery() + const [clearCache, clearCacheResult] = useLazyExecClearCacheQuery() const [checkAccess, accessCheckResult] = useLazyExecTenantsAccessCheckQuery() const [selectedTenants, setSelectedTenants] = useState([]) @@ -207,6 +208,34 @@ const GeneralSettings = () => { }, ] + const checkGDAPColumns = [ + { + name: 'Tenant', + selector: (row) => row['Tenant'], + grow: 0, + cell: cellGenericFormatter(), + }, + { + name: 'Error Type', + selector: (row) => row['Type'], + minWidth: '380px', + maxWidth: '380px', + cell: cellGenericFormatter(), + }, + { + name: 'Issue', + selector: (row) => row?.Issue, + }, + { + name: 'Resolution Link', + selector: (row) => row?.link, + }, + { + name: 'Relationship ID', + selector: (row) => row?.Relationship, + }, + ] + const handleCheckAccess = () => { const mapped = tenants.reduce( (current, { customerId, ...rest }) => ({ @@ -287,21 +316,6 @@ const GeneralSettings = () => { return tokenOffcanvasGroups } - const handleClearCache = useConfirmModal({ - body:
Are you sure you want to clear the cache?
, - onConfirm: () => { - clearCache({ tenantsOnly: false }) - localStorage.clear() - }, - }) - - const handleClearCacheTenant = useConfirmModal({ - body:
Are you sure you want to clear the cache?
, - onConfirm: () => { - clearCache({ tenantsOnly: true }) - }, - }) - const tableProps = { pagination: false, actions: [ @@ -336,39 +350,12 @@ const GeneralSettings = () => {
- - - Frontend Version - - - -
Latest: {isSuccessVersion ? versions.RemoteCIPPVersion : }
-
Current: {isSuccessVersion ? versions.LocalCIPPVersion : }
-
-
-
- - - - API Version - - - -
Latest: {isSuccessVersion ? versions.RemoteCIPPAPIVersion : }
-
Current: {isSuccessVersion ? versions.LocalCIPPAPIVersion : }
-
-
+
- + Permissions Check @@ -414,25 +401,6 @@ const GeneralSettings = () => { )} - {permissionsResult.data.Results?.MissingGroups.length > 0 && ( - <> - Your SAM User is missing the following group memberships. If you have setup - GDAP outside of CIPP, execute an access check to confirm access and role - availability to your tenants - - {permissionsResult.data.Results?.MissingGroups?.map((r, index) => ( - {r} - ))} - - - )} - {permissionsResult.data.Results?.CIPPGroupCount == 0 && ( - <> - NOTE: Your GDAP groups were not set up by CIPP. Please check the groups - below to see if you have the correct GDAP permissions, or execute an access - check. - - )} {permissionsResult.data.Results?.AccessTokenDetails?.Name !== '' && ( <> @@ -450,68 +418,70 @@ const GeneralSettings = () => { /> )} - {permissionsResult.data.Results?.Memberships !== '' && ( + + )} + + + + + + + GDAP Check + + + Click the button below to start a check for general GDAP settings. + checkGDAP({ path: '/api/ExecAccessChecks?GDAP=true' })} + disabled={GDAPResult.isFetching} + className="mt-3" + > + {GDAPResult.isFetching && ( + + )} + Run GDAP Check + + + + {GDAPResult.isSuccess && GDAPResult.data.Results.GDAPIssues?.length > 0 && ( + + )} + {GDAPResult.isSuccess && GDAPResult.data.Results.GDAPIssues?.length === 0 && ( + + No relationships with issues found. Please perform a Permissions Check or + Tenant Access Check if you are experiencing issues. + + )} + {GDAPResult.isSuccess && ( <> p['@odata.type'] == '#microsoft.graph.group', )} title="Groups" /> p['@odata.type'] == '#microsoft.graph.directoryRole', )} title="Roles" /> )} - - )} - - - - - - - Clear Cache - - - - Click the button below to clear the application cache. You can clear only the tenant - cache, or all caches. + - handleClearCache()} - disabled={clearCacheResult.isFetching} - className="me-3 mt-3" - > - {clearCacheResult.isFetching && ( - - )} - Clear All Caches - - handleClearCacheTenant()} - disabled={clearCacheResult.isFetching} - className="me-3 mt-3" - > - {clearCacheResult.isFetching && ( - - )} - Clear Tenant Cache - - {clearCacheResult.isSuccess && ( -
{clearCacheResult.data?.Results}
- )} - - + + Tenant Access Check @@ -541,6 +511,7 @@ const GeneralSettings = () => { )} + { - - -
) @@ -1359,6 +1327,8 @@ const DNSSettings = () => { const [getDnsConfig, getDnsConfigResult] = useLazyGetDnsConfigQuery() const [editDnsConfig, editDnsConfigResult] = useLazyEditDnsConfigQuery() const inputRef = useRef(null) + const [clearCache, clearCacheResult] = useLazyExecClearCacheQuery() + const { data: versions, isSuccess: isSuccessVersion } = useLoadVersionsQuery() const [alertVisible, setAlertVisible] = useState(false) @@ -1370,7 +1340,20 @@ const DNSSettings = () => { setAlertVisible(false) }, 2000) } + const handleClearCache = useConfirmModal({ + body:
Are you sure you want to clear the cache?
, + onConfirm: () => { + clearCache({ tenantsOnly: false }) + localStorage.clear() + }, + }) + const handleClearCacheTenant = useConfirmModal({ + body:
Are you sure you want to clear the cache?
, + onConfirm: () => { + clearCache({ tenantsOnly: true }) + }, + }) const resolvers = ['Google', 'Cloudflare', 'Quad9'] return ( @@ -1382,81 +1365,129 @@ const DNSSettings = () => { Application Settings -

DNS Resolver

- - {resolvers.map((r, index) => ( + + + + + +

DNS Resolver

+ + {resolvers.map((r, index) => ( + switchResolver(r)} + color={r === getDnsConfigResult.data.Resolver ? 'primary' : 'secondary'} + key={index} + > + {r} + + ))} + + {(editDnsConfigResult.isSuccess || editDnsConfigResult.isError) && ( + + {editDnsConfigResult.isSuccess + ? editDnsConfigResult.data.Results + : 'Error setting resolver'} + + )} +
+ +

Frontend Version

+ +
Latest: {isSuccessVersion ? versions.RemoteCIPPVersion : }
+
Current: {isSuccessVersion ? versions.LocalCIPPVersion : }
+
+
+ + +

Clear Caches

switchResolver(r)} - color={r === getDnsConfigResult.data.Resolver ? 'primary' : 'secondary'} - key={index} + className="me-2 mb-2" + onClick={() => handleClearCache()} + disabled={clearCacheResult.isFetching} > - {r} + {clearCacheResult.isFetching && ( + + )} + Clear All Cache - ))} -
- {(editDnsConfigResult.isSuccess || editDnsConfigResult.isError) && ( - - {editDnsConfigResult.isSuccess - ? editDnsConfigResult.data.Results - : 'Error setting resolver'} - - )} - - - - -

Settings Backup

- runBackup({ path: '/api/ExecRunBackup' })} - disabled={RunBackupResult.isFetching} - className="me-3 mt-3" - > - {RunBackupResult.isFetching && ( - + handleClearCacheTenant()} + disabled={clearCacheResult.isFetching} + > + {clearCacheResult.isFetching && ( + + )} + Clear Tenant Cache + + {clearCacheResult.isSuccess && ( +
{clearCacheResult.data?.Results}
)} - Run backup -
- handleChange(e)} - /> - inputRef.current.click()} - disabled={restoreBackupResult.isFetching} - className="me-3 mt-3" - > - {restoreBackupResult.isFetching && ( - +
+ + +

Settings Backup

+ runBackup({ path: '/api/ExecRunBackup' })} + disabled={RunBackupResult.isFetching} + > + {RunBackupResult.isFetching && ( + + )} + Run backup + + handleChange(e)} + /> + inputRef.current.click()} + disabled={restoreBackupResult.isFetching} + > + {restoreBackupResult.isFetching && ( + + )} + Restore backup + + {restoreBackupResult.isSuccess && ( + <> + {restoreBackupResult.data.Results} + )} - Restore backup - - {restoreBackupResult.isSuccess && ( - <> - {restoreBackupResult.data.Results} - - )} - {RunBackupResult.isSuccess && ( - <> - - downloadTxtFile(RunBackupResult.data.backup)} - className="m-1" - > - Download Backup - - - - )} -
+ {RunBackupResult.isSuccess && ( + <> + + downloadTxtFile(RunBackupResult.data.backup)}> + Download Backup + + + + )} +
+ +

Backend API Version

+ +
Latest: {isSuccessVersion ? versions.RemoteCIPPAPIVersion : }
+
Current: {isSuccessVersion ? versions.LocalCIPPAPIVersion : }
+
+ )} From 9fee67b87bf4977b08494a80079c7a25365081ad Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 17:50:29 +0100 Subject: [PATCH 11/23] improved the layout a little --- src/views/cipp/CIPPSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index 385075a06fc2..fd049b7629cd 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -354,7 +354,7 @@ const GeneralSettings = () => {
- + Permissions Check From 81249e1c80e409d5f83f67e8a7cd8abec3fc5e44 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 17:50:59 +0100 Subject: [PATCH 12/23] improve layout of table --- src/views/cipp/CIPPSettings.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index fd049b7629cd..4c6b60f71992 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -218,8 +218,6 @@ const GeneralSettings = () => { { name: 'Error Type', selector: (row) => row['Type'], - minWidth: '380px', - maxWidth: '380px', cell: cellGenericFormatter(), }, { From fd8164e794044ffef6a1d93dd59f9176e11db8d3 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 17:53:10 +0100 Subject: [PATCH 13/23] adding links --- src/views/cipp/CIPPSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index 4c6b60f71992..cdb468d9df3a 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -226,7 +226,7 @@ const GeneralSettings = () => { }, { name: 'Resolution Link', - selector: (row) => row?.link, + selector: (row) => row?.Link, }, { name: 'Relationship ID', From 01047abd9ad3d4123db7784f849b8ea0145b57f0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 18:02:36 +0100 Subject: [PATCH 14/23] improved cellformatter for urls --- src/components/tables/CellGenericFormat.js | 4 ++++ src/views/cipp/CIPPSettings.js | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/components/tables/CellGenericFormat.js b/src/components/tables/CellGenericFormat.js index e442378a5633..1015106a1935 100644 --- a/src/components/tables/CellGenericFormat.js +++ b/src/components/tables/CellGenericFormat.js @@ -7,6 +7,7 @@ import { } from '@fortawesome/free-solid-svg-icons' import { CellBadge } from 'src/components/tables' import { CBadge, CTooltip } from '@coreui/react' +import { startsWith } from 'core-js/core/string' const IconWarning = () => const IconError = () => @@ -79,6 +80,9 @@ export const cellGenericFormatter = if (cell.toLowerCase() === 'failed') { return {CellTip('Failed to retrieve from API')} } + if (cell.toLowerCase().startsWith('http')) { + return `URL` + } return CellTip(cell) } if (typeof cell === 'number') { diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index cdb468d9df3a..9e223b32cc1c 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -223,14 +223,17 @@ const GeneralSettings = () => { { name: 'Issue', selector: (row) => row?.Issue, + cell: cellGenericFormatter(), }, { name: 'Resolution Link', selector: (row) => row?.Link, + cell: cellGenericFormatter(), }, { name: 'Relationship ID', selector: (row) => row?.Relationship, + cell: cellGenericFormatter(), }, ] From 5344fda97a4683a9fbb977b4eadf3fbfb6f4e3bb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 18:06:44 +0100 Subject: [PATCH 15/23] improvements --- src/views/cipp/CIPPSettings.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index 9e223b32cc1c..576ad9ee520d 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -212,13 +212,16 @@ const GeneralSettings = () => { { name: 'Tenant', selector: (row) => row['Tenant'], - grow: 0, cell: cellGenericFormatter(), + minWidth: '200px', + maxWidth: '200px', }, { name: 'Error Type', selector: (row) => row['Type'], cell: cellGenericFormatter(), + minWidth: '150px', + maxWidth: '150px', }, { name: 'Issue', From 39fdbc7422787e09e593d4869ca16dce96b64692 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 18:16:50 +0100 Subject: [PATCH 16/23] fix --- src/components/tables/CellGenericFormat.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/tables/CellGenericFormat.js b/src/components/tables/CellGenericFormat.js index 1015106a1935..1fd1a70e6138 100644 --- a/src/components/tables/CellGenericFormat.js +++ b/src/components/tables/CellGenericFormat.js @@ -7,7 +7,6 @@ import { } from '@fortawesome/free-solid-svg-icons' import { CellBadge } from 'src/components/tables' import { CBadge, CTooltip } from '@coreui/react' -import { startsWith } from 'core-js/core/string' const IconWarning = () => const IconError = () => From e8c9603d014e4116e8ecf3afd7fa096b10ad06a2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 18:39:53 +0100 Subject: [PATCH 17/23] design changes --- src/components/tables/CellGenericFormat.js | 2 +- src/views/cipp/CIPPSettings.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/tables/CellGenericFormat.js b/src/components/tables/CellGenericFormat.js index 1fd1a70e6138..d78f7759dcd4 100644 --- a/src/components/tables/CellGenericFormat.js +++ b/src/components/tables/CellGenericFormat.js @@ -80,7 +80,7 @@ export const cellGenericFormatter = return {CellTip('Failed to retrieve from API')} } if (cell.toLowerCase().startsWith('http')) { - return `URL` + return URL } return CellTip(cell) } diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index 576ad9ee520d..ace316706511 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -220,8 +220,8 @@ const GeneralSettings = () => { name: 'Error Type', selector: (row) => row['Type'], cell: cellGenericFormatter(), - minWidth: '150px', - maxWidth: '150px', + minWidth: '100px', + maxWidth: '100px', }, { name: 'Issue', @@ -427,7 +427,7 @@ const GeneralSettings = () => { - + GDAP Check From 34e6d99c8692ac52397c7ad532e110055874b3da Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 3 Nov 2023 13:50:23 -0400 Subject: [PATCH 18/23] Mailbox Restores --- src/_nav.js | 19 ++ .../utilities/CippActionsOffcanvas.js | 7 + src/components/utilities/SharedModal.js | 3 + src/routes.js | 14 ++ .../tools/MailboxRestoreWizard.js | 214 ++++++++++++++++++ .../email-exchange/tools/MailboxRestores.js | 170 ++++++++++++++ 6 files changed, 427 insertions(+) create mode 100644 src/views/email-exchange/tools/MailboxRestoreWizard.js create mode 100644 src/views/email-exchange/tools/MailboxRestores.js diff --git a/src/_nav.js b/src/_nav.js index 852e4334d8cb..272eb82cd2f8 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -677,6 +677,25 @@ const _nav = [ }, ], }, + { + component: CNavGroup, + name: 'Tools', + section: 'Tools', + to: '/email/tools', + icon: , + items: [ + { + component: CNavItem, + name: 'Mailbox Restore Wizard', + to: '/email/tools/mailbox-restore-wizard', + }, + { + component: CNavItem, + name: 'Mailbox Restores', + to: '/email/tools/mailbox-restores', + }, + ], + }, { component: CNavTitle, name: 'Settings', diff --git a/src/components/utilities/CippActionsOffcanvas.js b/src/components/utilities/CippActionsOffcanvas.js index 371276f49375..ce148defa5a4 100644 --- a/src/components/utilities/CippActionsOffcanvas.js +++ b/src/components/utilities/CippActionsOffcanvas.js @@ -85,6 +85,13 @@ export default function CippActionsOffcanvas(props) { title: 'Confirm', onConfirm: () => genericGetRequest({ path: modalUrl }), }) + } else if (modalType === 'codeblock') { + ModalService.open({ + data: modalBody, + componentType: 'codeblock', + title: 'Info', + size: 'lg', + }) } else { ModalService.confirm({ key: modalContent, diff --git a/src/components/utilities/SharedModal.js b/src/components/utilities/SharedModal.js index 4975c0cc17f6..26b473729a91 100644 --- a/src/components/utilities/SharedModal.js +++ b/src/components/utilities/SharedModal.js @@ -2,6 +2,7 @@ import React from 'react' import { CButton, CModal, CModalBody, CModalFooter, CModalHeader, CModalTitle } from '@coreui/react' import PropTypes from 'prop-types' import { CippTable } from 'src/components/tables' +import CippCodeBlock from 'src/components/utilities/CippCodeBlock' /** * @@ -18,6 +19,8 @@ function mapBodyComponent({ componentType, data, componentProps }) { return
{Array.isArray(data) && data.map((el, idx) =>
{el}
)}
case 'text': return String(data) + case 'codeblock': + return default: return String(data) } diff --git a/src/routes.js b/src/routes.js index d305063a4109..5be9247bfae0 100644 --- a/src/routes.js +++ b/src/routes.js @@ -225,6 +225,10 @@ const ServiceHealth = React.lazy(() => import('src/views/tenant/administration/S const EnterpriseApplications = React.lazy(() => import('src/views/tenant/administration/ListEnterpriseApps'), ) +const MailboxRestoreWizard = React.lazy(() => + import('src/views/email-exchange/tools/MailboxRestoreWizard'), +) +const MailboxRestores = React.lazy(() => import('src/views/email-exchange/tools/MailboxRestores')) const routes = [ // { path: '/', exact: true, name: 'Home' }, @@ -544,6 +548,16 @@ const routes = [ name: 'List Spamfilter Templates', component: SpamFilterTemplate, }, + { + path: '/email/tools/mailbox-restore-wizard', + name: 'Mailbox Restore Wizard', + component: MailboxRestoreWizard, + }, + { + path: '/email/tools/mailbox-restores', + name: 'Mailbox Restores', + component: MailboxRestores, + }, { path: '/email/spamfilter/add-template', name: 'Add Spamfilter Template', diff --git a/src/views/email-exchange/tools/MailboxRestoreWizard.js b/src/views/email-exchange/tools/MailboxRestoreWizard.js new file mode 100644 index 000000000000..2e8acddc59f7 --- /dev/null +++ b/src/views/email-exchange/tools/MailboxRestoreWizard.js @@ -0,0 +1,214 @@ +import React from 'react' +import { CCallout, CCol, CListGroup, CListGroupItem, CRow, CSpinner } from '@coreui/react' +import { Field, FormSpy } from 'react-final-form' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faExclamationTriangle, faTimes, faCheck } from '@fortawesome/free-solid-svg-icons' +import { useSelector } from 'react-redux' +import { CippWizard } from 'src/components/layout' +import PropTypes from 'prop-types' +import { + RFFCFormCheck, + RFFCFormInput, + RFFCFormSelect, + RFFCFormSwitch, + RFFSelectSearch, +} from 'src/components/forms' +import { TenantSelector } from 'src/components/utilities' +import { useListUsersQuery } from 'src/store/api/users' +import { useGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app' + +const Error = ({ name }) => ( + + touched && error ? ( + + + {error} + + ) : null + } + /> +) + +Error.propTypes = { + name: PropTypes.string.isRequired, +} + +const MailboxRestoreWizard = () => { + const tenantDomain = useSelector((state) => state.app.currentTenant.defaultDomainName) + const { + data: sourceMailboxes = [], + isFetching: sMailboxesIsFetching, + error: sMailboxError, + } = useGenericGetRequestQuery({ + path: '/api/ListMailboxes', + params: { TenantFilter: tenantDomain, SoftDeletedMailbox: true }, + }) + const { + data: targetMailboxes = [], + isFetching: tMailboxesIsFetching, + error: tMailboxError, + } = useGenericGetRequestQuery({ + path: '/api/ListMailboxes', + params: { TenantFilter: tenantDomain }, + }) + const currentSettings = useSelector((state) => state.app) + const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery() + + const handleSubmit = async (values) => { + const shippedValues = { + TenantFilter: tenantDomain, + RequestName: values.RequestName, + SourceMailbox: values.SourceMailbox.value, + TargetMailbox: values.TargetMailbox.value, + BadItemLimit: values.BadItemLimit, + LargeItemLimit: values.LargeItemLimit, + AcceptLargeDataLoss: values.AcceptLargeDataLoss, + } + + //alert(JSON.stringify(values, null, 2)) + genericPostRequest({ path: '/api/ExecMailboxRestore', values: shippedValues }) + } + + return ( + + +
+

Step 1

+
Choose a tenant
+
+
+ {(props) => } +
+
+ +
+

Step 2

+
Select a soft deleted mailbox to restore.
+
+
+
+ ({ + value: mbx.ExchangeGuid, + name: `${mbx.displayName} <${mbx.UPN}>`, + }))} + placeholder={!sMailboxesIsFetching ? 'Select mailbox' : 'Loading...'} + name="SourceMailbox" + /> + {sMailboxError && Failed to load source mailboxes} +
+
+
+ +
+

Step 2

+
Select a mailbox to restore to.
+
+
+
+ ({ + value: mbx.ExchangeGuid, + name: `${mbx.displayName} <${mbx.UPN}>`, + }))} + placeholder={!tMailboxesIsFetching ? 'Select mailbox' : 'Loading...'} + name="TargetMailbox" + /> + {sMailboxError && Failed to load source mailboxes} +
+
+
+ +
+

Step 3

+
Enter Restore Request Options
+
+
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+

Step 4

+
Confirm and apply
+
+
+
+ {postResults.isFetching && ( + + Loading + + )} + {postResults.isSuccess && ( + + {postResults.data.Results.map((message, idx) => { + return
  • {message}
  • + })} +
    + )} + {!postResults.isSuccess && ( + + {(props) => ( + <> + + + + +
    Selected Tenant:
    + {tenantDomain} +
    + +
    Source Mailbox:
    + {props.values.SourceMailbox.label} +
    + +
    Target Mailbox:
    + {props.values.TargetMailbox.label} +
    +
    +
    +
    + + )} +
    + )} +
    +
    +
    +
    + ) +} + +export default MailboxRestoreWizard diff --git a/src/views/email-exchange/tools/MailboxRestores.js b/src/views/email-exchange/tools/MailboxRestores.js new file mode 100644 index 000000000000..05459fa1e08d --- /dev/null +++ b/src/views/email-exchange/tools/MailboxRestores.js @@ -0,0 +1,170 @@ +import { CSpinner, CButton } from '@coreui/react' +import { + faEllipsisV, + faTrashAlt, + faExclamationTriangle, + faCheck, +} from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import React, { useState } from 'react' +import { useSelector } from 'react-redux' +import { CippPageList } from 'src/components/layout' +import { + CellDelegatedPrivilege, + cellDateFormatter, + cellNullTextFormatter, +} from 'src/components/tables' +import { CippActionsOffcanvas } from 'src/components/utilities' +import GDAPRoles from 'src/data/GDAPRoles' +import { useLazyGenericGetRequestQuery } from 'src/store/api/app' +import { ModalService } from 'src/components/utilities' +import { constants } from 'buffer' +import Skeleton from 'react-loading-skeleton' +import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat' + +const Actions = (row, rowIndex, formatExtraData) => { + const [ocVisible, setOCVisible] = useState(false) + const [getMailboxRestoreStats, mailboxRestoreStats] = useLazyGenericGetRequestQuery() + const tenant = useSelector((state) => state.app.currentTenant) + + function statProperty(mailboxRestoreStats, propertyName) { + return ( + <> + {mailboxRestoreStats.isFetching && } + {!mailboxRestoreStats.isFetching && + mailboxRestoreStats.isSuccess && + (mailboxRestoreStats?.data[0][propertyName]?.toString() ?? ' ')} + + ) + } + + function loadOffCanvasDetails(id) { + setOCVisible(true) + getMailboxRestoreStats({ + path: 'api/ListMailboxRestores', + params: { + TenantFilter: tenant.defaultDomainName, + Identity: id, + Statistics: true, + IncludeReport: true, + }, + }) + } + var extendedInfo = [ + { label: 'Status', value: statProperty(mailboxRestoreStats, 'Status') }, + { label: 'Status Detail', value: statProperty(mailboxRestoreStats, 'StatusDetail') }, + { label: 'Sync Stage', value: statProperty(mailboxRestoreStats, 'SyncStage') }, + { label: 'Data Consistency', value: statProperty(mailboxRestoreStats, 'DataConsistencyScore') }, + { + label: 'Estimated Transfer', + value: statProperty(mailboxRestoreStats, 'EstimatedTransferSize'), + }, + { + label: 'Bytes Transferred', + value: statProperty(mailboxRestoreStats, 'BytesTransferred'), + }, + { + label: 'Percent Complete', + value: statProperty(mailboxRestoreStats, 'PercentComplete'), + }, + { + label: 'Estimated Item Count', + value: statProperty(mailboxRestoreStats, 'EstimatedTransferItemCount'), + }, + { + label: 'Transferred Items', + value: statProperty(mailboxRestoreStats, 'ItemsTransferred'), + }, + ] + + return ( + <> + loadOffCanvasDetails(row.Identity)}> + + + setOCVisible(false)} + /> + + ) +} + +const MailboxRestores = () => { + const tenant = useSelector((state) => state.app.currentTenant) + const columns = [ + { + name: 'Name', + selector: (row) => row['Name'], + sortable: true, + exportSelector: 'Name', + cell: cellGenericFormatter(), + }, + { + name: 'Status', + selector: (row) => row['Status'], + sortable: true, + exportSelector: 'Status', + cell: cellGenericFormatter(), + }, + { + name: 'Target Mailbox', + selector: (row) => row['TargetMailbox'], + sortable: true, + exportSelector: 'TargetMailbox', + cell: cellGenericFormatter(), + }, + { + name: 'Created', + selector: (row) => row['WhenCreated'], + sortable: true, + exportSelector: 'WhenCreated', + cell: cellDateFormatter({ format: 'short' }), + }, + { + name: 'Changed', + selector: (row) => row['WhenChanged'], + sortable: true, + exportSelector: 'WhenChanged', + cell: cellDateFormatter({ format: 'short' }), + }, + { + name: 'Actions', + cell: Actions, + maxWidth: '80px', + }, + ] + return ( +
    + +
    + ) +} + +export default MailboxRestores From 10cdce00435ebac982c7c6816154a549ce136f96 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 18:57:35 +0100 Subject: [PATCH 19/23] sortable --- src/views/cipp/CIPPSettings.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index ace316706511..d4405538b881 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -212,6 +212,7 @@ const GeneralSettings = () => { { name: 'Tenant', selector: (row) => row['Tenant'], + sortable: true, cell: cellGenericFormatter(), minWidth: '200px', maxWidth: '200px', @@ -219,6 +220,7 @@ const GeneralSettings = () => { { name: 'Error Type', selector: (row) => row['Type'], + sortable: true, cell: cellGenericFormatter(), minWidth: '100px', maxWidth: '100px', @@ -226,15 +228,18 @@ const GeneralSettings = () => { { name: 'Issue', selector: (row) => row?.Issue, + sortable: true, cell: cellGenericFormatter(), }, { name: 'Resolution Link', + sortable: true, selector: (row) => row?.Link, cell: cellGenericFormatter(), }, { name: 'Relationship ID', + sortable: true, selector: (row) => row?.Relationship, cell: cellGenericFormatter(), }, From 66fd3dbedf7c6b86b62ebe42ccae55f7d80b3145 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 18:58:30 +0100 Subject: [PATCH 20/23] fixes interface bugs --- src/views/cipp/CIPPSettings.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index d4405538b881..ff405447c7ed 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -86,7 +86,6 @@ import { CellDelegatedPrivilege } from 'src/components/tables/CellDelegatedPrivi import { TableModalButton } from 'src/components/buttons' import { cellTableFormatter } from 'src/components/tables/CellTable' import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat' -import { check } from 'prettier' const CIPPSettings = () => { const [active, setActive] = useState(1) From fd8d3930d9d2c3f734c9d433efc0a59792e9301e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 3 Nov 2023 13:59:46 -0400 Subject: [PATCH 21/23] Update SharedModal.js --- src/components/utilities/SharedModal.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/utilities/SharedModal.js b/src/components/utilities/SharedModal.js index 26b473729a91..fb8501fc93ca 100644 --- a/src/components/utilities/SharedModal.js +++ b/src/components/utilities/SharedModal.js @@ -20,7 +20,9 @@ function mapBodyComponent({ componentType, data, componentProps }) { case 'text': return String(data) case 'codeblock': - return + return ( + + ) default: return String(data) } From b776180ebc58918c38f76577ee6dec90d678ba2c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 19:00:40 +0100 Subject: [PATCH 22/23] fixed backup wizard --- src/views/cipp/CIPPSettings.js | 35 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index ff405447c7ed..965ae5beef54 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -337,23 +337,7 @@ const GeneralSettings = () => { />, ], } - const downloadTxtFile = (data) => { - const txtdata = [JSON.stringify(RunBackupResult.data.backup)] - const file = new Blob(txtdata, { type: 'text/plain' }) - const element = document.createElement('a') - element.href = URL.createObjectURL(file) - element.download = 'CIPP-Backup' + Date.now() + '.json' - document.body.appendChild(element) - element.click() - } - const inputRef = useRef(null) - const handleChange = (e) => { - const fileReader = new FileReader() - fileReader.readAsText(e.target.files[0], 'UTF-8') - fileReader.onload = (e) => { - restoreBackup({ path: '/api/ExecRestoreBackup', values: e.target.result }) - } - } + return (
    @@ -1339,7 +1323,22 @@ const DNSSettings = () => { const { data: versions, isSuccess: isSuccessVersion } = useLoadVersionsQuery() const [alertVisible, setAlertVisible] = useState(false) - + const downloadTxtFile = (data) => { + const txtdata = [JSON.stringify(RunBackupResult.data.backup)] + const file = new Blob(txtdata, { type: 'text/plain' }) + const element = document.createElement('a') + element.href = URL.createObjectURL(file) + element.download = 'CIPP-Backup' + Date.now() + '.json' + document.body.appendChild(element) + element.click() + } + const handleChange = (e) => { + const fileReader = new FileReader() + fileReader.readAsText(e.target.files[0], 'UTF-8') + fileReader.onload = (e) => { + restoreBackup({ path: '/api/ExecRestoreBackup', values: e.target.result }) + } + } const switchResolver = (resolver) => { editDnsConfig({ resolver }) getDnsConfig() From b015da799d2d127a2ac974eabc4091e4b3485437 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 3 Nov 2023 19:01:34 +0100 Subject: [PATCH 23/23] upped to 4.5.5 --- public/version_latest.txt | 2 +- version_latest.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/version_latest.txt b/public/version_latest.txt index ae153944ee8b..50021202769b 100644 --- a/public/version_latest.txt +++ b/public/version_latest.txt @@ -1 +1 @@ -4.5.0 \ No newline at end of file +4.5.5 \ No newline at end of file diff --git a/version_latest.txt b/version_latest.txt index 64b5ae3938a0..50021202769b 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -4.4.0 \ No newline at end of file +4.5.5 \ No newline at end of file