From 0a0c77eff9990ac2b0f33b4e2fcd521dd261fec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 14 Feb 2025 18:53:03 +0100 Subject: [PATCH 01/90] recommendations and casing Set a few back to autoComplete Casing --- src/data/standards.json | 143 ++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/src/data/standards.json b/src/data/standards.json index b027c365d60b..5f59f9404465 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -47,7 +47,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Enable-OrganizationCustomization", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.ProfilePhotos", @@ -57,7 +57,7 @@ "docsDescription": "Controls whether users can set their own profile photos in Microsoft 365. When disabled, only User and Global administrators can update profile photos for users.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -121,7 +121,7 @@ "label": "Hide self-service password reset" }, { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Visual Template", "name": "standards.Branding.layoutTemplateType", @@ -189,7 +189,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Update-MgBetaAdminReportSetting -BodyParameter @{displayConcealedNames = $true}", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DisableGuestDirectory", @@ -202,7 +202,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Set-AzureADMSAuthorizationPolicy -GuestUserRoleId '2af84b1e-32c8-42b7-82bc-daa82404023b'", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DisableBasicAuthSMTP", @@ -215,7 +215,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-TransportConfig -SmtpClientAuthenticationDisabled $true", - "recommendedBy": [] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.ActivityBasedTimeout", @@ -224,7 +224,7 @@ "helpText": "Enables and sets Idle session timeout for Microsoft 365 to 1 hour. This policy affects most M365 web apps", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -347,7 +347,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Portal or Graph API", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.PWdisplayAppInformationRequiredState", @@ -383,7 +383,7 @@ "docsDescription": "Sets the Authenticator Lite state to enabled. This allows users to use the Authenticator Lite built into the Outlook app instead of the full Authenticator app.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -417,7 +417,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.EnableHardwareOAuth", @@ -453,7 +453,7 @@ "docsDescription": "Enables Temporary Password generation for the tenant.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select TAP Lifetime", @@ -474,7 +474,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.PasswordExpireDisabled", @@ -487,7 +487,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Update-MgDomain", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.ExternalMFATrusted", @@ -496,7 +496,7 @@ "helpText": "Sets the state of the Cross-tenant access setting to trust external MFA. This allows guest users to use their home tenant MFA to access your tenant.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -530,7 +530,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EnableAppConsentRequests", @@ -559,7 +559,7 @@ "docsDescription": "Sets the state of the registration campaign for the tenant. If enabled nudges users to set up the Microsoft Authenticator during sign-in.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -612,7 +612,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableSecurityGroupUsers", @@ -667,7 +667,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Graph API", - "recommendedBy": [] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.OauthConsent", @@ -687,7 +687,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.OauthConsentLowSec", @@ -905,7 +905,7 @@ "docsDescription": "Sets the global quarantine notification interval for the tenant. This is the time between the quarantine notification emails are sent out to users. Default is 24 hours.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.GlobalQuarantineNotifications.NotificationInterval", @@ -942,7 +942,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Set-RemoteDomain -Identity 'Default' -TNEFEnabled $false", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.FocusedInbox", @@ -952,7 +952,7 @@ "docsDescription": "Sets the default Focused Inbox state for the tenant. This can be overridden by the user in their Outlook settings. For more information, see [Microsoft's documentation.](https://support.microsoft.com/en-us/office/focused-inbox-for-outlook-f445ad7f-02f4-4294-a82e-71d8964e3978)", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.FocusedInbox.state", @@ -982,7 +982,7 @@ "docsDescription": "Sets the default state for Cloud Message Recall for the tenant. By default this is enabled. You can read more about the feature [here.](https://techcommunity.microsoft.com/t5/exchange-team-blog/cloud-based-message-recall-in-exchange-online/ba-p/3744714)", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.CloudMessageRecall.state", @@ -1049,7 +1049,7 @@ "docsDescription": "Adds or removes indicators to e-mail messages received from external senders in Outlook. You can read more about this feature on [Microsoft's Exchange Team Blog.](https://techcommunity.microsoft.com/t5/exchange-team-blog/native-external-sender-callouts-on-email-in-outlook/ba-p/2250098)", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.SpoofWarn.state", @@ -1068,8 +1068,8 @@ "label": "Enable or disable 'external' warning in Outlook", "impact": "Low Impact", "impactColour": "info", - "powershellEquivalent": "et-ExternalInOutlook \u2013Enabled $true or $false", - "recommendedBy": ["CIS"] + "powershellEquivalent": "Set-ExternalInOutlook \u2013Enabled $true or $false", + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EnableMailTips", @@ -1089,7 +1089,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Set-OrganizationConfig", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.TeamsMeetingsByDefault", @@ -1098,7 +1098,7 @@ "helpText": "Sets the default state for automatically turning meetings into Teams meetings for the tenant. This can be overridden by the user in Outlook.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.TeamsMeetingsByDefault.state", @@ -1143,7 +1143,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Rotate-DkimSigningConfig", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.AddDKIM", @@ -1155,7 +1155,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "New-DkimSigningConfig and Set-DkimSigningConfig", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EnableMailboxAuditing", @@ -1168,7 +1168,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Set-OrganizationConfig -AuditDisabled $false", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.SendReceiveLimitTenant", @@ -1208,10 +1208,10 @@ }, "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select Sharing Level", - "name": "standards.calDefault.permissionlevel", + "name": "standards.calDefault.permissionLevel", "options": [ { "label": "Owner - The user can create, read, edit, and delete all items in the folder, and create subfolders. The user is both folder owner and folder contact.", @@ -1284,12 +1284,13 @@ "cat": "Exchange Standards", "tag": ["CIS"], "helpText": "Automatically adds all available domains as a proxy address.", - "docsDescription": "Automatically finds all available domain names in the tenant, and tries to add proxyaddresses based on the users UPN to each of these.", + "docsDescription": "Automatically finds all available domain names in the tenant, and tries to add proxy addresses based on the user's UPN to each of these.", "addedComponent": [], "label": "Automatically deploy proxy addresses", "impact": "Medium Impact", "impactColour": "warning", - "powershellEquivalent": "set-mailbox -emailaddresses @{add=$emailaddress}" + "powershellEquivalent": "Set-Mailbox -EmailAddresses @{add=$EmailAddress}", + "recommendedBy": [] }, { "name": "standards.DisableAdditionalStorageProviders", @@ -1311,7 +1312,7 @@ "helpText": "Sets the shorten meetings settings on a tenant level. This will shorten meetings by the selected amount of minutes. Valid values are 0 to 29. Short meetings are under 60 minutes, long meetings are over 60 minutes.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.ShortenMeetings.ShortenEventScopeDefault", @@ -1357,7 +1358,7 @@ "docsDescription": "", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.Bookings.state", @@ -1407,7 +1408,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-MailboxJunkEmailConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DelegateSentItems", @@ -1439,7 +1440,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-Mailbox", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.UserSubmissions", @@ -1449,7 +1450,7 @@ "docsDescription": "Set the state of the built-in Report button in Outlook. This gives the users the ability to report emails as spam or phish.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.UserSubmissions.state", @@ -1488,7 +1489,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Get-Mailbox & Update-MgUser", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EXODisableAutoForwarding", @@ -1501,7 +1502,7 @@ "impact": "High Impact", "impactColour": "danger", "powershellEquivalent": "Set-HostedOutboundSpamFilterPolicy -AutoForwardingMode 'Off'", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.RetentionPolicyTag", @@ -1781,12 +1782,7 @@ { "name": "standards.SafeAttachmentPolicy", "cat": "Defender Standards", - "tag": [ - "CIS", - "mdo_safedocuments", - "mdo_commonattachmentsfilter", - "mdo_safeattachmentpolicy" - ], + "tag": ["CIS", "mdo_safedocuments", "mdo_commonattachmentsfilter", "mdo_safeattachmentpolicy"], "helpText": "This creates a Safe Attachment policy", "addedComponent": [ { @@ -2163,7 +2159,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Graph API", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.intuneBrandingProfile", @@ -2277,12 +2273,13 @@ "name": "standards.intuneDeviceReg", "cat": "Intune Standards", "tag": ["mediumimpact"], - "helpText": "sets the maximum number of devices that can be registered by a user. A value of 0 disables device registration by users", + "helpText": "Sets the maximum number of devices that can be registered by a user. A value of 0 disables device registration by users", "addedComponent": [ { "type": "number", "name": "standards.intuneDeviceReg.max", - "label": "Maximum devices (Enter 2147483647 for unlimited.)" + "label": "Maximum devices (Enter 2147483647 for unlimited.)", + "required": true } ], "label": "Set Maximum Number of Devices per user", @@ -2310,7 +2307,7 @@ "docsDescription": "When a OneDrive user gets deleted, the personal SharePoint site is saved for selected amount of time that data can be retrieved from it.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "name": "standards.DeletedUserRentention.Days", "label": "Retention time (Default 30 days)", @@ -2369,7 +2366,7 @@ "label": "Set deleted user retention time in OneDrive", "impact": "Low Impact", "impactColour": "info", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", "recommendedBy": [] }, { @@ -2387,7 +2384,7 @@ "label": "Set Default Timezone for Tenant", "impact": "Low Impact", "impactColour": "info", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", "recommendedBy": [] }, { @@ -2412,7 +2409,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Set-SPOTenant -DisallowInfectedFileDownload $true", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS 3.0", "CIPP"] }, { "name": "standards.SPDisableLegacyWorkflows", @@ -2436,7 +2433,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-SPOTenant -DefaultSharingLinkType Direct", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS 3.0", "CIPP"] }, { "name": "standards.SPExternalUserExpiration", @@ -2459,20 +2456,20 @@ { "name": "standards.SPEmailAttestation", "cat": "SharePoint Standards", - "tag": ["CIS"], - "helpText": "Ensure reauthentication with verification code is restricted", + "tag": ["mediumimpact", "CIS"], + "helpText": "Ensure re-authentication with verification code is restricted", "addedComponent": [ { "type": "number", "name": "standards.SPEmailAttestation.Days", - "label": "Require reauth every X Days (Default 15)" + "label": "Require re-authentication every X Days (Default 15)" } ], - "label": "Require reauthentication with verification code", + "label": "Require re-authentication with verification code", "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-SPOTenant -EmailAttestationRequired $true -EmailAttestationReAuthDays 15", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS 3.0", "CIPP"] }, { "name": "standards.DisableAddShortcutsToOneDrive", @@ -2545,7 +2542,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-SPOTenant -LegacyAuthProtocolsEnabled $false", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.sharingCapability", @@ -2554,7 +2551,7 @@ "helpText": "Sets the default sharing level for OneDrive and SharePoint. This is a tenant wide setting and overrules any settings set on the site level", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select Sharing Level", "name": "standards.sharingCapability.Level", @@ -2581,8 +2578,8 @@ "label": "Set Sharing Level for OneDrive and SharePoint", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", - "recommendedBy": ["CIS"] + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableReshare", @@ -2594,8 +2591,8 @@ "label": "Disable Resharing by External Users", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", - "recommendedBy": ["CIS"] + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableUserSiteCreate", @@ -2607,7 +2604,7 @@ "label": "Disable site creation by standard users", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { @@ -2625,7 +2622,7 @@ "label": "Exclude File Extensions from Syncing", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { @@ -2637,7 +2634,7 @@ "label": "Do not allow Mac devices to sync using OneDrive", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { @@ -2649,7 +2646,7 @@ "label": "Only allow users to sync OneDrive from AAD joined devices", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { @@ -2659,7 +2656,7 @@ "helpText": "Restricts sharing to only users with the specified domain. This is useful for organizations that only want to share with their own domain.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "name": "standards.sharingDomainRestriction.Mode", "label": "Limit external sharing by domains", @@ -2688,7 +2685,7 @@ "label": "Restrict sharing to a specific domain", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { From c1894f6b920905ab6c68c06ea051342d1e9a1295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sat, 15 Feb 2025 13:00:17 +0100 Subject: [PATCH 02/90] Fix AutoAddProxy standard typo and disable features that dont work in the standard --- src/data/standards.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/data/standards.json b/src/data/standards.json index 5f59f9404465..d8884a90d596 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -1280,7 +1280,7 @@ "recommendedBy": ["CIS"] }, { - "name": "standardsAutoAddProxy", + "name": "standards.AutoAddProxy", "cat": "Exchange Standards", "tag": ["CIS"], "helpText": "Automatically adds all available domains as a proxy address.", @@ -1290,7 +1290,12 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-Mailbox -EmailAddresses @{add=$EmailAddress}", - "recommendedBy": [] + "recommendedBy": [], + "disabledFeatures": { + "report": true, + "warn": true, + "remediate": false + } }, { "name": "standards.DisableAdditionalStorageProviders", From 29266f69c4fcaa767758bfd918e26e635d2f1e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sat, 15 Feb 2025 13:23:12 +0100 Subject: [PATCH 03/90] Remove last redundant tags for ashe --- src/data/standards.json | 68 ++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/data/standards.json b/src/data/standards.json index d8884a90d596..de04bd037a17 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -207,7 +207,7 @@ { "name": "standards.DisableBasicAuthSMTP", "cat": "Global Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Disables SMTP AUTH for the organization and all users. This is the default for new tenants. ", "docsDescription": "Disables SMTP basic authentication for the tenant and all users with it explicitly enabled.", "addedComponent": [], @@ -617,7 +617,7 @@ { "name": "standards.DisableSecurityGroupUsers", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Completely disables the creation of security groups by users. This also breaks the ability to manage groups themselves, or create Teams", "addedComponent": [], "label": "Disable Security Group creation by users", @@ -629,7 +629,7 @@ { "name": "standards.LegacyMFACleanup", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This standard currently does not function and can be safely disabled", "addedComponent": [], "label": "Remove Legacy MFA if SD or CA is active", @@ -641,7 +641,7 @@ { "name": "standards.DisableSelfServiceLicenses", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This standard disables all self service licenses and enables all exclusions", "addedComponent": [ { @@ -660,7 +660,7 @@ { "name": "standards.DisableGuests", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Blocks login for guest users that have not logged in for 90 days", "addedComponent": [], "label": "Disable Guest accounts that have not logged on for 90 days", @@ -704,7 +704,7 @@ { "name": "standards.GuestInvite", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This setting controls who can invite guests to your directory to collaborate on resources secured by your company, such as SharePoint sites or Azure resources.", "addedComponent": [ { @@ -767,7 +767,7 @@ { "name": "standards.UndoOauth", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Disables App consent and set to Allow user consent for apps", "addedComponent": [], "label": "Undo App Consent Standard", @@ -779,7 +779,7 @@ { "name": "standards.SecurityDefaults", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Enables security defaults for the tenant, for newer tenants this is enabled by default. Do not enable this feature if you use Conditional Access.", "docsDescription": "Enables SD for the tenant, which disables all forms of basic authentication and enforces users to configure MFA. Users are only prompted for MFA when a logon is considered 'suspect' by Microsoft.", "addedComponent": [], @@ -792,7 +792,7 @@ { "name": "standards.DisableSMS", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using SMS as an MFA method. If a user only has SMS as a MFA method, they will be unable to log in.", "docsDescription": "Disables SMS as an MFA method for the tenant. If a user only has SMS as a MFA method, they will be unable to sign in.", "addedComponent": [], @@ -805,7 +805,7 @@ { "name": "standards.DisableVoice", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using Voice call as an MFA method. If a user only has Voice as a MFA method, they will be unable to log in.", "docsDescription": "Disables Voice call as an MFA method for the tenant. If a user only has Voice call as a MFA method, they will be unable to sign in.", "addedComponent": [], @@ -818,7 +818,7 @@ { "name": "standards.DisableEmail", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using email as an MFA method. This disables the email OTP option for guest users, and instead prompts them to create a Microsoft account.", "addedComponent": [], "label": "Disables Email as an MFA method", @@ -830,7 +830,7 @@ { "name": "standards.Disablex509Certificate", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using Certificates as an MFA method.", "docsDescription": "", "addedComponent": [], @@ -843,7 +843,7 @@ { "name": "standards.DisableQRCodePin", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using QR Code Pin as an MFA method. If a user only has QR Code Pin as a MFA method, they will be unable to log in.", "docsDescription": "Disables QR Code Pin as an MFA method for the tenant. If a user only has QR Code Pin as a MFA method, they will be unable to sign in.", "addedComponent": [], @@ -856,7 +856,7 @@ { "name": "standards.PerUserMFA", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Enables per user MFA for all users.", "addedComponent": [], "label": "Enables per user MFA for all users.", @@ -1313,7 +1313,7 @@ { "name": "standards.ShortenMeetings", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the shorten meetings settings on a tenant level. This will shorten meetings by the selected amount of minutes. Valid values are 0 to 29. Short meetings are under 60 minutes, long meetings are over 60 minutes.", "addedComponent": [ { @@ -1358,7 +1358,7 @@ { "name": "standards.Bookings", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the state of Bookings on the tenant. Bookings is a scheduling tool that allows users to book appointments with others both internal and external.", "docsDescription": "", "addedComponent": [ @@ -1401,7 +1401,7 @@ { "name": "standards.SafeSendersDisable", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Loops through all users and removes the Safe Senders list. This is to prevent SPF bypass attacks, as the Safe Senders list is not checked by SPF.", "addedComponent": [], "disabledFeatures": { @@ -1418,7 +1418,7 @@ { "name": "standards.DelegateSentItems", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets emails sent as and on behalf of shared mailboxes to also be stored in the shared mailbox sent items folder", "docsDescription": "This makes sure that e-mails sent from shared mailboxes or delegate mailboxes, end up in the mailbox of the shared/delegate mailbox instead of the sender, allowing you to keep replies in the same mailbox as the original e-mail.", "addedComponent": [ @@ -1437,7 +1437,7 @@ { "name": "standards.SendFromAlias", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Enables the ability for users to send from their alias addresses.", "docsDescription": "Allows users to change the 'from' address to any set in their Azure AD Profile.", "addedComponent": [], @@ -1450,7 +1450,7 @@ { "name": "standards.UserSubmissions", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Set the state of the spam submission button in Outlook", "docsDescription": "Set the state of the built-in Report button in Outlook. This gives the users the ability to report emails as spam or phish.", "addedComponent": [ @@ -1512,7 +1512,7 @@ { "name": "standards.RetentionPolicyTag", "cat": "Exchange Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Creates a CIPP - Deleted Items retention policy tag that permanently deletes items in the Deleted Items folder after X days.", "docsDescription": "Creates a CIPP - Deleted Items retention policy tag that permanently deletes items in the Deleted Items folder after X days.", "addedComponent": [ @@ -1950,7 +1950,7 @@ { "name": "standards.SpamFilterPolicy", "cat": "Defender Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This standard creates a Spam filter policy similar to the default strict policy.", "addedComponent": [ { @@ -2277,7 +2277,7 @@ { "name": "standards.intuneDeviceReg", "cat": "Intune Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the maximum number of devices that can be registered by a user. A value of 0 disables device registration by users", "addedComponent": [ { @@ -2296,7 +2296,7 @@ { "name": "standards.intuneRequireMFA", "cat": "Intune Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Requires MFA for all users to register devices with Intune. This is useful when not using Conditional Access.", "label": "Require Multifactor Authentication to register or join devices with Microsoft Entra", "impact": "Medium Impact", @@ -2461,7 +2461,7 @@ { "name": "standards.SPEmailAttestation", "cat": "SharePoint Standards", - "tag": ["mediumimpact", "CIS"], + "tag": ["CIS"], "helpText": "Ensure re-authentication with verification code is restricted", "addedComponent": [ { @@ -2479,7 +2479,7 @@ { "name": "standards.DisableAddShortcutsToOneDrive", "cat": "SharePoint Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "If disabled, the button Add shortcut to OneDrive will be removed and users in the tenant will no longer be able to add new shortcuts to their OneDrive. Existing shortcuts will remain functional", "addedComponent": [ { @@ -2509,7 +2509,7 @@ { "name": "standards.SPSyncButtonState", "cat": "SharePoint Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "If disabled, users in the tenant will no longer be able to use the Sync button to sync SharePoint content on all sites. However, existing synced content will remain functional on the user's computer.", "addedComponent": [ { @@ -2602,7 +2602,7 @@ { "name": "standards.DisableUserSiteCreate", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Disables users from creating new SharePoint sites", "docsDescription": "Disables standard users from creating SharePoint sites, also disables the ability to fully create teams", "addedComponent": [], @@ -2615,7 +2615,7 @@ { "name": "standards.ExcludedfileExt", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Sets the file extensions that are excluded from syncing with OneDrive. These files will be blocked from upload. '*.' is automatically added to the extension and can be omitted.", "addedComponent": [ { @@ -2633,7 +2633,7 @@ { "name": "standards.disableMacSync", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Disables the ability for Mac devices to sync with OneDrive.", "addedComponent": [], "label": "Do not allow Mac devices to sync using OneDrive", @@ -2645,7 +2645,7 @@ { "name": "standards.unmanagedSync", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "The unmanaged Sync standard has been temporarily disabled and does nothing.", "addedComponent": [], "label": "Only allow users to sync OneDrive from AAD joined devices", @@ -2851,7 +2851,7 @@ { "name": "standards.TeamsExternalAccessPolicy", "cat": "Teams Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the properties of the Global external access policy.", "docsDescription": "Sets the properties of the Global external access policy. External access policies determine whether or not your users can: 1) communicate with users who have Session Initiation Protocol (SIP) accounts with a federated organization; 2) communicate with users who are using custom applications built with Azure Communication Services; 3) access Skype for Business Server over the Internet, without having to log on to your internal network; 4) communicate with users who have SIP accounts with a public instant messaging (IM) provider such as Skype; and, 5) communicate with people who are using Teams with an account that's not managed by an organization.", "addedComponent": [ @@ -2880,7 +2880,7 @@ { "name": "standards.TeamsFederationConfiguration", "cat": "Teams Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the properties of the Global federation configuration.", "docsDescription": "Sets the properties of the Global federation configuration. Federation configuration settings determine whether or not your users can communicate with users who have SIP accounts with a federated organization.", "addedComponent": [ @@ -2936,7 +2936,7 @@ { "name": "standards.TeamsMessagingPolicy", "cat": "Teams Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the properties of the Global messaging policy.", "docsDescription": "Sets the properties of the Global messaging policy. Messaging policies control which chat and channel messaging features are available to users in Teams.", "addedComponent": [ From 1a9abb5a3d17ffc6695a9cf01b173c79867effdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sat, 15 Feb 2025 14:16:46 +0100 Subject: [PATCH 04/90] New standard: AntiSpamSafeList --- src/data/standards.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/data/standards.json b/src/data/standards.json index de04bd037a17..8cc6be4216b3 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -1310,6 +1310,25 @@ "powershellEquivalent": "Get-OwaMailboxPolicy | Set-OwaMailboxPolicy -AdditionalStorageProvidersEnabled $False", "recommendedBy": ["CIS"] }, + { + "name": "standards.AntiSpamSafeList", + "cat": "Defender Standards", + "tag": [], + "helpText": "Sets the anti-spam connection filter policy option 'safe list' in Defender.", + "docsDescription": "Sets [Microsoft's built-in 'safe list'](https://learn.microsoft.com/en-us/powershell/module/exchange/set-hostedconnectionfilterpolicy?view=exchange-ps#-enablesafelist) in the anti-spam connection filter policy, rather than setting a custom safe/block list of IPs.", + "addedComponent": [ + { + "type": "switch", + "name": "standards.AntiSpamSafeList.EnableSafeList", + "label": "Enable Safe List" + } + ], + "label": "Set Anti-Spam Connection Filter Safe List", + "impact": "Medium Impact", + "impactColour": "info", + "powershellEquivalent": "Set-HostedConnectionFilterPolicy \"Default\" -EnableSafeList $true", + "recommendedBy": [] + }, { "name": "standards.ShortenMeetings", "cat": "Exchange Standards", From 81f3057857a66a9d551aa022a1a7f6b7a758f53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 18:18:07 +0100 Subject: [PATCH 05/90] Change to POST --- src/pages/email/administration/mailboxes/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/email/administration/mailboxes/index.js b/src/pages/email/administration/mailboxes/index.js index 90bfc401266e..13caa3d14794 100644 --- a/src/pages/email/administration/mailboxes/index.js +++ b/src/pages/email/administration/mailboxes/index.js @@ -68,7 +68,7 @@ const Page = () => { }, { label: "Convert to Room Mailbox", - type: "GET", + type: "POST", url: "/api/ExecConvertToRoomMailbox", icon: , data: { From d683c91d6a7aefa26b6230bc8d3c9d3f1d8200ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 18:29:45 +0100 Subject: [PATCH 06/90] Change to POST --- src/pages/email/administration/contacts/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/email/administration/contacts/index.js b/src/pages/email/administration/contacts/index.js index 9d75996d8652..22e922d006ce 100644 --- a/src/pages/email/administration/contacts/index.js +++ b/src/pages/email/administration/contacts/index.js @@ -20,7 +20,7 @@ const Page = () => { }, { label: "Remove Contact", - type: "GET", + type: "POST", url: "/api/RemoveContact", data: { GUID: "id", From f9ea548fe0d77826d01839872aaf76e494d0b088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 18:50:26 +0100 Subject: [PATCH 07/90] Change mailbox conversion actions from GET to POST and update API endpoint --- .../CippComponents/CippUserActions.jsx | 12 +++---- .../email/administration/mailboxes/index.js | 32 ++++++++++--------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/components/CippComponents/CippUserActions.jsx b/src/components/CippComponents/CippUserActions.jsx index 93e6d991adb6..a385c9d72c2f 100644 --- a/src/components/CippComponents/CippUserActions.jsx +++ b/src/components/CippComponents/CippUserActions.jsx @@ -107,19 +107,19 @@ export const CippUserActions = () => { { //tested label: "Convert to Shared Mailbox", - type: "GET", + type: "POST", icon: , - url: "/api/ExecConvertToSharedMailbox", - data: { ID: "userPrincipalName" }, + url: "/api/ExecConvertMailbox", + data: { ID: "userPrincipalName", MailboxType: "!Shared" }, confirmText: "Are you sure you want to convert this user to a shared mailbox?", multiPost: false, }, { label: "Convert to User Mailbox", - type: "GET", + type: "POST", icon: , - url: "/api/ExecConvertToSharedMailbox", - data: { ID: "userPrincipalName", ConvertToUser: true }, + url: "/api/ExecConvertMailbox", + data: { ID: "userPrincipalName", MailboxType: "!Regular" }, confirmText: "Are you sure you want to convert this user to a user mailbox?", multiPost: false, }, diff --git a/src/pages/email/administration/mailboxes/index.js b/src/pages/email/administration/mailboxes/index.js index 13caa3d14794..6c0771eaf01d 100644 --- a/src/pages/email/administration/mailboxes/index.js +++ b/src/pages/email/administration/mailboxes/index.js @@ -2,7 +2,7 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; import Link from "next/link"; import { Button } from "@mui/material"; -import { Add } from "@mui/icons-material"; +import { Add, Mail } from "@mui/icons-material"; import { Archive, @@ -44,35 +44,37 @@ const Page = () => { icon: , }, { - label: "Convert to Shared Mailbox", - type: "GET", - icon: , - url: "/api/ExecConvertToSharedMailbox", + label: "Convert to User Mailbox", + type: "POST", + url: "/api/ExecConvertMailbox", + icon: , data: { ID: "UPN", + MailboxType: "!Regular", }, - confirmText: "Are you sure you want to convert this mailbox to a shared mailbox?", - condition: (row) => row.recipientTypeDetails !== "SharedMailbox", + confirmText: "Are you sure you want to convert this mailbox to a user mailbox?", + condition: (row) => row.recipientTypeDetails !== "UserMailbox", }, { - label: "Convert to User Mailbox", - type: "GET", - url: "/api/ExecConvertToSharedMailbox", - icon: , + label: "Convert to Shared Mailbox", + type: "POST", + icon: , + url: "/api/ExecConvertMailbox", data: { ID: "UPN", - ConvertToUser: true, + MailboxType: "!Shared", }, - confirmText: "Are you sure you want to convert this mailbox to a user mailbox?", - condition: (row) => row.recipientTypeDetails !== "UserMailbox", + confirmText: "Are you sure you want to convert this mailbox to a shared mailbox?", + condition: (row) => row.recipientTypeDetails !== "SharedMailbox", }, { label: "Convert to Room Mailbox", type: "POST", - url: "/api/ExecConvertToRoomMailbox", + url: "/api/ExecConvertMailbox", icon: , data: { ID: "UPN", + MailboxType: "!Room", }, confirmText: "Are you sure you want to convert this mailbox to a room mailbox?", condition: (row) => row.recipientTypeDetails !== "RoomMailbox", From 4843840c5dc854f960ac4dd3eeafbb3fc2128432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 18:56:17 +0100 Subject: [PATCH 08/90] Change to POST --- src/pages/endpoint/MEM/list-compliance-policies/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/endpoint/MEM/list-compliance-policies/index.js b/src/pages/endpoint/MEM/list-compliance-policies/index.js index 47e955ce1452..71d2d4f8a8ba 100644 --- a/src/pages/endpoint/MEM/list-compliance-policies/index.js +++ b/src/pages/endpoint/MEM/list-compliance-policies/index.js @@ -60,7 +60,7 @@ const Page = () => { }, { label: "Delete Policy", - type: "GET", + type: "POST", url: "/api/RemovePolicy", data: { ID: "id", From a74d9b1da0f679a8913a6f3cf67fffb7727eaafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 20:28:28 +0100 Subject: [PATCH 09/90] Change restore action type from GET to POST --- src/pages/identity/administration/deleted-items/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/identity/administration/deleted-items/index.js b/src/pages/identity/administration/deleted-items/index.js index 43d9ddb9d817..b82213e9e8c9 100644 --- a/src/pages/identity/administration/deleted-items/index.js +++ b/src/pages/identity/administration/deleted-items/index.js @@ -1,6 +1,6 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; -import RestoreFromTrashIcon from '@mui/icons-material/RestoreFromTrash'; +import RestoreFromTrashIcon from "@mui/icons-material/RestoreFromTrash"; const Page = () => { const pageTitle = "Deleted Items"; @@ -8,7 +8,7 @@ const Page = () => { const actions = [ { label: "Restore Object", - type: "GET", + type: "POST", icon: , url: "/api/ExecRestoreDeleted", data: { ID: "id" }, From 174b37f18600bab0e2973ecfb973d77687935e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 21:36:16 +0100 Subject: [PATCH 10/90] Change spam filter actions from GET to POST --- src/pages/email/spamfilter/list-spamfilter/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/email/spamfilter/list-spamfilter/index.js b/src/pages/email/spamfilter/list-spamfilter/index.js index 55985f5d7316..f6961ffc7d04 100644 --- a/src/pages/email/spamfilter/list-spamfilter/index.js +++ b/src/pages/email/spamfilter/list-spamfilter/index.js @@ -8,7 +8,7 @@ import { RocketLaunch } from "@mui/icons-material"; const Page = () => { const pageTitle = "Spam Filters"; - const apiUrl = "/api/ListSpamfilter" + const apiUrl = "/api/ListSpamfilter"; const actions = [ { @@ -23,11 +23,11 @@ const Page = () => { }, { label: "Enable Rule", - type: "GET", + type: "POST", icon: , url: "/api/EditSpamfilter", data: { - State: "enable", + State: "!enable", name: "Name", }, confirmText: "Are you sure you want to enable this rule?", @@ -35,11 +35,11 @@ const Page = () => { }, { label: "Disable Rule", - type: "GET", + type: "POST", icon: , url: "/api/EditSpamfilter", data: { - State: "disable", + State: "!disable", name: "Name", }, confirmText: "Are you sure you want to disable this rule?", @@ -47,7 +47,7 @@ const Page = () => { }, { label: "Delete Rule", - type: "GET", + type: "POST", icon: , url: "/api/RemoveSpamFilter", data: { From bdbe851b0782ccd465d94030ab362baf62fcb92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 21:47:27 +0100 Subject: [PATCH 11/90] Change remove mailbox rule action type from GET to POST --- src/pages/email/administration/mailbox-rules/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/email/administration/mailbox-rules/index.js b/src/pages/email/administration/mailbox-rules/index.js index c80b749aad07..e25ba44d8ae6 100644 --- a/src/pages/email/administration/mailbox-rules/index.js +++ b/src/pages/email/administration/mailbox-rules/index.js @@ -10,7 +10,7 @@ const Page = () => { const actions = [ { label: "Remove Mailbox Rule", - type: "GET", + type: "POST", icon: , url: "/api/ExecRemoveMailboxRule", data: { ruleId: "Identity", userPrincipalName: "UserPrincipalName", ruleName: "Name" }, From 892004cc214e47d0487e680ad7d9f0eaf9f8abfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 21:53:36 +0100 Subject: [PATCH 12/90] Change Send MFA Push action type from GET to POST --- src/pages/email/administration/mailboxes/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/email/administration/mailboxes/index.js b/src/pages/email/administration/mailboxes/index.js index 6c0771eaf01d..19f7b04cd22b 100644 --- a/src/pages/email/administration/mailboxes/index.js +++ b/src/pages/email/administration/mailboxes/index.js @@ -35,7 +35,7 @@ const Page = () => { }, { label: "Send MFA Push", - type: "GET", + type: "POST", url: "/api/ExecSendPush", data: { UserEmail: "UPN", From 2789f7bbe5074602bb125bfa11c5fa566cda2751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 22:04:40 +0100 Subject: [PATCH 13/90] Change Enable Online Archive action type from GET to POST --- src/components/CippComponents/CippUserActions.jsx | 2 +- src/pages/email/administration/mailboxes/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/CippComponents/CippUserActions.jsx b/src/components/CippComponents/CippUserActions.jsx index a385c9d72c2f..0e1191f3ed86 100644 --- a/src/components/CippComponents/CippUserActions.jsx +++ b/src/components/CippComponents/CippUserActions.jsx @@ -126,7 +126,7 @@ export const CippUserActions = () => { { //tested label: "Enable Online Archive", - type: "GET", + type: "POST", icon: , url: "/api/ExecEnableArchive", data: { ID: "userPrincipalName" }, diff --git a/src/pages/email/administration/mailboxes/index.js b/src/pages/email/administration/mailboxes/index.js index 19f7b04cd22b..bf085c191ca7 100644 --- a/src/pages/email/administration/mailboxes/index.js +++ b/src/pages/email/administration/mailboxes/index.js @@ -82,7 +82,7 @@ const Page = () => { { //tested label: "Enable Online Archive", - type: "GET", + type: "POST", icon: , url: "/api/ExecEnableArchive", data: { ID: "UPN" }, From 656809ec46fc20ffd60308d8fd2f3b71f5f1ba50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 17 Feb 2025 22:18:43 +0100 Subject: [PATCH 14/90] Change Block Sign In action type from GET to POST --- src/components/CippComponents/CippUserActions.jsx | 4 ++-- .../email/reports/SharedMailboxEnabledAccount/index.js | 2 +- src/pages/email/resources/management/list-rooms/index.js | 6 +++--- src/pages/identity/reports/inactive-users-report/index.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/CippComponents/CippUserActions.jsx b/src/components/CippComponents/CippUserActions.jsx index 0e1191f3ed86..dbeae334071d 100644 --- a/src/components/CippComponents/CippUserActions.jsx +++ b/src/components/CippComponents/CippUserActions.jsx @@ -237,7 +237,7 @@ export const CippUserActions = () => { }, { label: "Block Sign In", - type: "GET", + type: "POST", icon: , url: "/api/ExecDisableUser", data: { ID: "id" }, @@ -247,7 +247,7 @@ export const CippUserActions = () => { }, { label: "Unblock Sign In", - type: "GET", + type: "POST", icon: , url: "/api/ExecDisableUser", data: { ID: "id", Enable: true }, diff --git a/src/pages/email/reports/SharedMailboxEnabledAccount/index.js b/src/pages/email/reports/SharedMailboxEnabledAccount/index.js index 186556bbe91e..4b05494fa344 100644 --- a/src/pages/email/reports/SharedMailboxEnabledAccount/index.js +++ b/src/pages/email/reports/SharedMailboxEnabledAccount/index.js @@ -19,7 +19,7 @@ const Page = () => { actions={[ { label: "Block Sign In", - type: "GET", + type: "POST", icon: , url: "/api/ExecDisableUser", data: { ID: "id" }, diff --git a/src/pages/email/resources/management/list-rooms/index.js b/src/pages/email/resources/management/list-rooms/index.js index 9fc307d60e63..56133e7d0976 100644 --- a/src/pages/email/resources/management/list-rooms/index.js +++ b/src/pages/email/resources/management/list-rooms/index.js @@ -18,7 +18,7 @@ const Page = () => { }, { label: "Block Sign In", - type: "GET", + type: "POST", icon: , url: "/api/ExecDisableUser", data: { ID: "id" }, @@ -28,7 +28,7 @@ const Page = () => { }, { label: "Unblock Sign In", - type: "GET", + type: "POST", icon: , url: "/api/ExecDisableUser", data: { ID: "id", Enable: true }, @@ -62,7 +62,7 @@ const Page = () => { "city", "state", "countryOrRegion", - "hiddenFromAddressListsEnabled" + "hiddenFromAddressListsEnabled", ]} cardButton={ + color="muted" + style={{ paddingLeft: 0 }} + size="small" + href={`https://entra.microsoft.com/${userSettingsDefaults.currentTenant}/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/${userId}`} + target="_blank" + rel="noopener noreferrer" + > + View in Entra + ), }, ] @@ -189,7 +189,7 @@ const Page = () => { const mailboxRuleActions = [ { label: "Remove Mailbox Rule", - type: "GET", + type: "POST", icon: , url: "/api/ExecRemoveMailboxRule", data: { diff --git a/src/pages/tenant/administration/alert-configuration/index.js b/src/pages/tenant/administration/alert-configuration/index.js index 1544d84c8e39..41f76c7dac2e 100644 --- a/src/pages/tenant/administration/alert-configuration/index.js +++ b/src/pages/tenant/administration/alert-configuration/index.js @@ -24,7 +24,7 @@ const Page = () => { }, { label: "Delete Alert", - type: "GET", + type: "POST", url: "/api/RemoveQueuedAlert", data: { ID: "RowKey", diff --git a/src/pages/tenant/conditional/list-named-locations/index.js b/src/pages/tenant/conditional/list-named-locations/index.js index 834efd07eb32..a53610c35926 100644 --- a/src/pages/tenant/conditional/list-named-locations/index.js +++ b/src/pages/tenant/conditional/list-named-locations/index.js @@ -11,7 +11,7 @@ const Page = () => { const actions = [ { label: "Add location to named location", - type: "GET", + type: "POST", url: "/api/ExecNamedLocation", icon: , data: { diff --git a/src/pages/tenant/conditional/list-policies/index.js b/src/pages/tenant/conditional/list-policies/index.js index 8d4b4af2d867..8c021df61319 100644 --- a/src/pages/tenant/conditional/list-policies/index.js +++ b/src/pages/tenant/conditional/list-policies/index.js @@ -32,34 +32,40 @@ const Page = () => { }, { label: "Enable policy", - type: "GET", - url: "/api/EditCAPolicy?State=Enabled", + type: "POST", + url: "/api/EditCAPolicy", data: { GUID: "id", + State: "!Enabled", }, confirmText: "Are you sure you want to enable this policy?", + condition: (row) => row.state !== "enabled", icon: , color: "info", }, { label: "Disable policy", - type: "GET", - url: "/api/EditCAPolicy?State=Disabled", + type: "POST", + url: "/api/EditCAPolicy", data: { GUID: "id", + State: "!Disabled", }, confirmText: "Are you sure you want to disable this policy?", + condition: (row) => row.state !== "disabled", icon: , color: "info", }, { label: "Set policy to report only", - type: "GET", - url: "/api/EditCAPolicy?State=enabledForReportingButNotEnforced", + type: "POST", + url: "/api/EditCAPolicy", data: { GUID: "id", + State: "!enabledForReportingButNotEnforced", }, confirmText: "Are you sure you want to set this policy to report only?", + condition: (row) => row.state !== "enabledForReportingButNotEnforced", icon: , color: "info", }, From b05272c6a306df7153a887af9921814bf97d385c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= <31723128+kris6673@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:26:32 +0100 Subject: [PATCH 34/90] Update src/data/standards.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Esco Signed-off-by: Kristian Kjærgård <31723128+kris6673@users.noreply.github.com> --- src/data/standards.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/standards.json b/src/data/standards.json index 8cc6be4216b3..c41d979fdc0b 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -2493,7 +2493,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-SPOTenant -EmailAttestationRequired $true -EmailAttestationReAuthDays 15", - "recommendedBy": ["CIS 3.0", "CIPP"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableAddShortcutsToOneDrive", From 65203d75b36df506dfdd8cc1d0ceaf3acf1f73c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= <31723128+kris6673@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:26:45 +0100 Subject: [PATCH 35/90] Update src/data/standards.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Esco Signed-off-by: Kristian Kjærgård <31723128+kris6673@users.noreply.github.com> --- src/data/standards.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/data/standards.json b/src/data/standards.json index c41d979fdc0b..d05130e9a626 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -1326,6 +1326,7 @@ "label": "Set Anti-Spam Connection Filter Safe List", "impact": "Medium Impact", "impactColour": "info", + "addedDate": "2025-02-15", "powershellEquivalent": "Set-HostedConnectionFilterPolicy \"Default\" -EnableSafeList $true", "recommendedBy": [] }, From ff65d4814c11dd3c3a29c776ba2af4c5a0ef0f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= <31723128+kris6673@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:26:54 +0100 Subject: [PATCH 36/90] Update src/data/standards.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Esco Signed-off-by: Kristian Kjærgård <31723128+kris6673@users.noreply.github.com> --- src/data/standards.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/standards.json b/src/data/standards.json index d05130e9a626..20c728c6a5df 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -2434,7 +2434,7 @@ "impact": "Low Impact", "impactColour": "info", "powershellEquivalent": "Set-SPOTenant -DisallowInfectedFileDownload $true", - "recommendedBy": ["CIS 3.0", "CIPP"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.SPDisableLegacyWorkflows", From 8602d02320c1a53c683015e97ce71eb901149795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= <31723128+kris6673@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:29:31 +0100 Subject: [PATCH 37/90] Update src/data/standards.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Esco Signed-off-by: Kristian Kjærgård <31723128+kris6673@users.noreply.github.com> --- src/data/standards.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/standards.json b/src/data/standards.json index 20c728c6a5df..80368e71d88d 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -2458,7 +2458,7 @@ "impact": "Medium Impact", "impactColour": "warning", "powershellEquivalent": "Set-SPOTenant -DefaultSharingLinkType Direct", - "recommendedBy": ["CIS 3.0", "CIPP"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.SPExternalUserExpiration", From bff556ea0a5b23fa8935c5a85e48e4df4bb049f1 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 24 Feb 2025 12:23:39 -0500 Subject: [PATCH 38/90] fix version number in build steps --- .github/workflows/cipp_dev_build.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cipp_dev_build.yml b/.github/workflows/cipp_dev_build.yml index 834f1995b668..dad0dbebe307 100644 --- a/.github/workflows/cipp_dev_build.yml +++ b/.github/workflows/cipp_dev_build.yml @@ -18,10 +18,17 @@ jobs: uses: actions/checkout@v4.2.2 # Set up Node.js + - name: Get Node version + id: get_node_version + run: | + node_raw_version=$(node -p "require('./package.json').engines.node") + node_sanitized_version=$(echo $node_raw_version | sed -E 's/[^0-9.]+//g') + echo "node_version=$node_sanitized_version" >> $GITHUB_OUTPUT + - name: Set up Node.js uses: actions/setup-node@v4.2.0 with: - node-version: '20.18.1' + node-version: ${{ steps.get_node_version.outputs.node_version }} # Install dependencies - name: Install Dependencies From 33ac08f539de7abd3f0a875ac76de7284725f29d Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 24 Feb 2025 12:39:28 -0500 Subject: [PATCH 39/90] make build process get node version --- .github/workflows/cipp_frontend_build.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cipp_frontend_build.yml b/.github/workflows/cipp_frontend_build.yml index 3d6d1c79550e..76a7dbb2fbbf 100644 --- a/.github/workflows/cipp_frontend_build.yml +++ b/.github/workflows/cipp_frontend_build.yml @@ -18,10 +18,17 @@ jobs: uses: actions/checkout@v4.2.2 # Set up Node.js + - name: Get Node version + id: get_node_version + run: | + node_raw_version=$(node -p "require('./package.json').engines.node") + node_sanitized_version=$(echo $node_raw_version | sed -E 's/[^0-9.]+//g') + echo "node_version=$node_sanitized_version" >> $GITHUB_OUTPUT + - name: Set up Node.js uses: actions/setup-node@v4.2.0 with: - node-version: '20.18.1' + node-version: ${{ steps.get_node_version.outputs.node_version }} # Install dependencies - name: Install Dependencies From 980738b8ec136ebda978e0200ffc413f188e23ea Mon Sep 17 00:00:00 2001 From: Esco Date: Tue, 25 Feb 2025 09:35:29 +0100 Subject: [PATCH 40/90] feat: readd defaultValue to Standards --- .../CippComponents/CippFormComponent.jsx | 4 + src/data/standards.json | 76 +++++++++---------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/components/CippComponents/CippFormComponent.jsx b/src/components/CippComponents/CippFormComponent.jsx index c353ac89f71b..5ba298a7be3e 100644 --- a/src/components/CippComponents/CippFormComponent.jsx +++ b/src/components/CippComponents/CippFormComponent.jsx @@ -43,6 +43,7 @@ export const CippFormComponent = (props) => { name, // The name that may have bracket notation label, labelLocation = "behind", // Default location for switches + defaultValue, ...other } = props; const { errors } = useFormState({ control: formControl.control }); @@ -121,6 +122,7 @@ export const CippFormComponent = (props) => { {...other} {...formControl.register(convertedName, { ...validators })} label={label} + defaultValue={defaultValue} /> @@ -156,6 +158,7 @@ export const CippFormComponent = (props) => { {...other} {...formControl.register(convertedName, { ...validators })} label={label} + defaultValue={defaultValue} /> @@ -171,6 +174,7 @@ export const CippFormComponent = (props) => { renderSwitchWithLabel( Date: Tue, 25 Feb 2025 14:45:30 -0500 Subject: [PATCH 41/90] fix offboarding job nest actions in postExecution object --- src/components/CippWizard/CippWizardOffboarding.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/CippWizard/CippWizardOffboarding.jsx b/src/components/CippWizard/CippWizardOffboarding.jsx index 6c79070dcd81..bfc00908777d 100644 --- a/src/components/CippWizard/CippWizardOffboarding.jsx +++ b/src/components/CippWizard/CippWizardOffboarding.jsx @@ -292,18 +292,18 @@ export const CippWizardOffboarding = (props) => { Send results to: - + From 16400f3522695cb40433d21fa36b4655f62dc84e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 18:05:07 -0500 Subject: [PATCH 42/90] feat: disable form elements in cippformcondition default action=hide Added to integration definitions to ensure that integrations are enabled before navigating to tenant/field mapping or filling out API details --- .../CippComponents/CippFormCondition.jsx | 60 ++- src/data/Extensions.json | 348 +++++++++++++++--- src/pages/cipp/integrations/configure.js | 25 +- 3 files changed, 369 insertions(+), 64 deletions(-) diff --git a/src/components/CippComponents/CippFormCondition.jsx b/src/components/CippComponents/CippFormCondition.jsx index f6e3bdd4fdf2..45ea1c016cac 100644 --- a/src/components/CippComponents/CippFormCondition.jsx +++ b/src/components/CippComponents/CippFormCondition.jsx @@ -1,8 +1,9 @@ import { useWatch } from "react-hook-form"; import isEqual from "lodash/isEqual"; // lodash for deep comparison +import React from "react"; export const CippFormCondition = (props) => { - let { field, compareType = "is", compareValue, children, formControl } = props; + let { field, compareType = "is", compareValue, action = 'hide', children, formControl } = props; if ( field === undefined || @@ -22,17 +23,38 @@ export const CippFormCondition = (props) => { compareValue = compareValue.value; } + const disableChildren = (children) => { + return React.Children.map(children, (child) => { + if (React.isValidElement(child)) { + if (child.props?.children && child.type.name !== "CippFormCondition") { + return React.cloneElement(child, { + children: disableChildren(child.props.children), + disabled: true, + }); + } + return React.cloneElement(child, { disabled: true }); + } + return child; + }); + }; + switch (compareType) { case "regex": if (watcher?.match(new RegExp(compareValue))) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "is": // Deep comparison for objects and arrays if (isEqual(watcher, compareValue)) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "isNot": @@ -40,6 +62,9 @@ export const CippFormCondition = (props) => { if (!isEqual(watcher, compareValue)) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "contains": @@ -55,6 +80,9 @@ export const CippFormCondition = (props) => { // Check if object contains the key return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "doesNotContain": @@ -73,6 +101,9 @@ export const CippFormCondition = (props) => { // Check if object does not contain the key return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "greaterThan": @@ -83,6 +114,9 @@ export const CippFormCondition = (props) => { ) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "lessThan": @@ -93,6 +127,9 @@ export const CippFormCondition = (props) => { ) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "arrayLength": @@ -103,12 +140,18 @@ export const CippFormCondition = (props) => { ) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "hasValue": if (watcher !== undefined && watcher !== null && watcher !== "") { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; /* @@ -119,6 +162,9 @@ export const CippFormCondition = (props) => { if (Array.isArray(watcher) && watcher.some((item) => item?.label === compareValue)) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "labelContains": @@ -129,6 +175,9 @@ export const CippFormCondition = (props) => { ) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "valueEq": @@ -136,6 +185,9 @@ export const CippFormCondition = (props) => { if (Array.isArray(watcher) && watcher.some((item) => item?.value === compareValue)) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; case "valueContains": @@ -146,9 +198,15 @@ export const CippFormCondition = (props) => { ) { return children; } + if (action === "disable") { + return disableChildren(children); + } return null; default: + if (action === "disable") { + return disableChildren(children); + } return null; } }; diff --git a/src/data/Extensions.json b/src/data/Extensions.json index 7f9d8ddcb38e..708cbc6f17db 100644 --- a/src/data/Extensions.json +++ b/src/data/Extensions.json @@ -44,21 +44,39 @@ "name": "Sherweb.clientId", "label": "Client ID", "placeholder": "Enter your Sherweb Client ID", - "required": true + "required": true, + "condition": { + "field": "Sherweb.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "textField", "name": "Sherweb.SubscriptionKey", "label": "Subscription Key", "placeholder": "Enter your Sherweb Subscription Key", - "required": true + "required": true, + "condition": { + "field": "Sherweb.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "Sherweb.APIKey", "label": "Client Secret", "placeholder": "Enter your Sherweb Client Secret", - "required": true + "required": true, + "condition": { + "field": "Sherweb.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "autoComplete", @@ -70,7 +88,13 @@ "labelField": "RowKey", "valueField": "RowKey" }, - "multiple": true + "multiple": true, + "condition": { + "field": "Sherweb.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ] }, @@ -91,29 +115,47 @@ } ], "SettingOptions": [ + { + "type": "switch", + "name": "Gradient.Enabled", + "label": "Enable Integration" + }, { "type": "textField", "name": "Gradient.VendorKey", "label": "Gradient Vendor API Key", "placeholder": "Enter your Gradient Vendor Key.", - "required": true + "required": true, + "condition": { + "field": "Gradient.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "Gradient.APIKey", "label": "Gradient Partner API Key", "placeholder": "Enter your Gradient Partner Key. Leave blank to keep your current key.", - "required": true + "required": true, + "condition": { + "field": "Gradient.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "Gradient.BillingEnabled", - "label": "Enable sending all license information to Gradient" - }, - { - "type": "switch", - "name": "Gradient.Enabled", - "label": "Enable Integration" + "label": "Enable sending all license information to Gradient", + "condition": { + "field": "Gradient.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": false @@ -134,26 +176,61 @@ } ], "SettingOptions": [ + { + "type": "switch", + "name": "HaloPSA.Enabled", + "label": "Enable Integration" + }, + { + "type": "switch", + "name": "HaloPSA.ConsolidateTickets", + "label": "Consolidate Tickets", + "placeholder": "Consolidate tickets for the same alert into one ticket.", + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } + }, { "type": "textField", "name": "HaloPSA.ResourceURL", "label": "HaloPSA Resource Server URL", "placeholder": "Enter your HaloPSA Resource Server URL.", - "required": true + "required": true, + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "textField", "name": "HaloPSA.AuthURL", "label": "HaloPSA Authorisation Endpoint URL", "placeholder": "Enter your HaloPSA Authorisation Endpoint URL.", - "required": true + "required": true, + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "textField", "name": "HaloPSA.Tenant", "label": "HaloPSA Tenant", "placeholder": "Enter your HaloPSA Tenant (Leave blank if self-hosted)", - "required": true + "required": true, + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "autoComplete", @@ -170,6 +247,12 @@ "labelField": "name", "valueField": "id", "showRefresh": true + }, + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" } }, { @@ -177,19 +260,26 @@ "name": "HaloPSA.ClientID", "label": "HaloPSA Client ID", "placeholder": "Enter your HaloPSA Client ID", - "required": true + "required": true, + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "HaloPSA.APIKey", "label": "HaloPSA Client Secret", "placeholder": "Enter your client Secret. Leave blank to keep your current key.", - "required": true - }, - { - "type": "switch", - "name": "HaloPSA.Enabled", - "label": "Enable Integration" + "required": true, + "condition": { + "field": "HaloPSA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": true @@ -211,46 +301,82 @@ } ], "SettingOptions": [ + { + "type": "switch", + "name": "NinjaOne.Enabled", + "label": "Enable Integration" + }, { "type": "textField", "name": "NinjaOne.Instance", "label": "Please enter your NinjaOne Instance hostname", "placeholder": "app.ninjarmm.com, eu.ninjarmm.com, oc.ninjarmm.com, ca.ninjarmm.com, us2.ninjarmm.com", - "required": true + "required": true, + "condition": { + "field": "NinjaOne.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "textField", "name": "NinjaOne.ClientID", "label": "NinjaOne API Client ID", "placeholder": "Enter your NinjaOne API Client ID", - "required": true + "required": true, + "condition": { + "field": "NinjaOne.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "NinjaOne.APIKey", "label": "NinjaOne API Client Secret", "placeholder": "Enter your NinjaOne API Client Secret", - "required": true + "required": true, + "condition": { + "field": "NinjaOne.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "NinjaOne.LicenseDocumentsEnabled", - "label": "Sync Licenses (Requires NinjaOne Documentation)" + "label": "Sync Licenses (Requires NinjaOne Documentation)", + "condition": { + "field": "NinjaOne.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "NinjaOne.UserDocumentsEnabled", - "label": "Sync Users (Requires NinjaOne Documentation)" + "label": "Sync Users (Requires NinjaOne Documentation)", + "condition": { + "field": "NinjaOne.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "NinjaOne.LicensedOnly", - "label": "Only Sync Licensed Users (Requires NinjaOne Documentation)" - }, - { - "type": "switch", - "name": "NinjaOne.Enabled", - "label": "Enable Integration" + "label": "Only Sync Licensed Users (Requires NinjaOne Documentation)", + "condition": { + "field": "NinjaOne.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": true, @@ -275,49 +401,91 @@ } ], "SettingOptions": [ + { + "type": "switch", + "name": "Hudu.Enabled", + "label": "Enable Integration" + }, { "type": "textField", "name": "Hudu.BaseUrl", "label": "Please enter your Hudu URL", "placeholder": "https://yourcompany.huducloud.com", - "required": true + "required": true, + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "Hudu.APIKey", "label": "Hudu API Key", "placeholder": "Enter your Hudu API Key", - "required": true - }, - { - "type": "switch", - "name": "Hudu.Enabled", - "label": "Enable Integration" + "required": true, + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "Hudu.CreateMissingUsers", - "label": "Create missing users in Hudu" + "label": "Create missing users in Hudu", + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "Hudu.CreateMissingDevices", - "label": "Create missing devices in Hudu" + "label": "Create missing devices in Hudu", + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "textField", "name": "Hudu.ExcludeSerials", - "label": "Exclude device serials (comma separated)" + "label": "Exclude device serials (comma separated)", + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "Hudu.ImportDomains", - "label": "Import domains from M365" + "label": "Import domains from M365", + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "Hudu.MonitorDomains", - "label": "Monitor domains in Hudu" + "label": "Monitor domains in Hudu", + "condition": { + "field": "Hudu.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "_comment": "I have added this switch as a logic check for the Hudu integration script to check against when CIPP first connects to the Hudu Instance via Connect-HuduAPI.ps1", @@ -370,13 +538,25 @@ "type": "textField", "name": "PWPush.BaseUrl", "label": "PWPush URL", - "placeholder": "Enter your PWPush URL. (default: https://pwpush.com)" + "placeholder": "Enter your PWPush URL. (default: https://pwpush.com)", + "condition": { + "field": "PWPush.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "PWPush.APIKey", "label": "PWPush API Key", - "placeholder": "Enter your PWPush API Key. (optional)" + "placeholder": "Enter your PWPush API Key. (optional)", + "condition": { + "field": "PWPush.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "textField", @@ -413,23 +593,47 @@ "type": "number", "name": "PWPush.ExpireAfterDays", "label": "Expiration in Days", - "placeholder": "Expiration time in days. (optional)" + "placeholder": "Expiration time in days. (optional)", + "condition": { + "field": "PWPush.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "number", "name": "PWPush.ExpireAfterViews", "label": "Expiration after views", - "placeholder": "Expiration after views. (optional)" + "placeholder": "Expiration after views. (optional)", + "condition": { + "field": "PWPush.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "PWPush.RetrievalStep", - "label": "Click to retrieve password (recommended)" + "label": "Click to retrieve password (recommended)", + "condition": { + "field": "PWPush.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", "name": "PWPush.DeletableByViewer", - "label": "Allow deletion of passwords" + "label": "Allow deletion of passwords", + "condition": { + "field": "PWPush.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": false @@ -454,7 +658,13 @@ { "type": "password", "name": "HIBP.APIKey", - "label": "Enter your own HIBP API Key. When you are a CyberDrain hosted partner, leave this key blank." + "label": "Enter your own HIBP API Key. When you are a CyberDrain hosted partner, leave this key blank.", + "condition": { + "field": "HIBP.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "switch", @@ -493,12 +703,24 @@ { "type": "textField", "name": "CFZTNA.ClientID", - "label": "CloudFlare Tunnel Service Account Client ID" + "label": "CloudFlare Tunnel Service Account Client ID", + "condition": { + "field": "CFZTNA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } }, { "type": "password", "name": "CFZTNA.APIKey", - "label": "CloudFlare Tunnel Service Account Client Secret" + "label": "CloudFlare Tunnel Service Account Client Secret", + "condition": { + "field": "CFZTNA.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": false @@ -519,17 +741,23 @@ } ], "SettingOptions": [ + { + "type": "switch", + "name": "GitHub.Enabled", + "label": "Enable Integration" + }, { "type": "password", "name": "GitHub.APIKey", "label": "GitHub Personal Access Token", "placeholder": "Enter your GitHub PAT", - "required": true - }, - { - "type": "switch", - "name": "GitHub.Enabled", - "label": "Enable Integration" + "required": true, + "condition": { + "field": "GitHub.Enabled", + "compareType": "is", + "compareValue": true, + "action": "disable" + } } ], "mappingRequired": false diff --git a/src/pages/cipp/integrations/configure.js b/src/pages/cipp/integrations/configure.js index 9eed557868ab..e65e27607f5a 100644 --- a/src/pages/cipp/integrations/configure.js +++ b/src/pages/cipp/integrations/configure.js @@ -200,13 +200,32 @@ const Page = () => { - - {extension?.mappingRequired && } - {extension?.fieldMapping && } + {extension?.mappingRequired && ( + setting?.name === `${extension.id}.Enabled` + ) && integrations?.data?.[extension.id]?.Enabled !== true + } + /> + )} + {extension?.fieldMapping && ( + setting.name === `${extension.id}.Enabled` + ) && integrations?.data?.[extension.id]?.Enabled !== true + } + /> + )} From c14f506a5be57536c5e316177126fae08299bbb4 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 18:57:20 -0500 Subject: [PATCH 43/90] Update CippSchedulerForm.jsx --- src/components/CippFormPages/CippSchedulerForm.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/CippFormPages/CippSchedulerForm.jsx b/src/components/CippFormPages/CippSchedulerForm.jsx index 03579b6cd2e4..325fd788757e 100644 --- a/src/components/CippFormPages/CippSchedulerForm.jsx +++ b/src/components/CippFormPages/CippSchedulerForm.jsx @@ -203,7 +203,6 @@ const CippSchedulerForm = (props) => { options={recurrenceOptions} multiple={false} disableClearable={true} - creatable={false} /> {selectedCommand?.addedFields?.Synopsis && ( From 37f39176fe11a02deb9e60c1ad7c43e6c396509e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 22:11:04 -0500 Subject: [PATCH 44/90] Create dev_deploy.yml Signed-off-by: John Duprey --- .github/workflows/dev_deploy.yml | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/dev_deploy.yml diff --git a/.github/workflows/dev_deploy.yml b/.github/workflows/dev_deploy.yml new file mode 100644 index 000000000000..01fd002acea0 --- /dev/null +++ b/.github/workflows/dev_deploy.yml @@ -0,0 +1,41 @@ +name: CIPP Development Frontend CI/CD + +on: + push: + branches: + - dev + +jobs: + build_and_deploy_job: + if: github.event.repository.fork == false && github.event_name == 'push' + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_MOSS_0A047A40F }} # change this to your repository secret name + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + action: 'upload' + ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### + # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig + app_location: '/' # App source code path + api_location: '' # Api source code path - optional + output_location: 'out' # Built app content directory - optional + ###### End of Repository/Build Configurations ###### + + close_pull_request_job: + if: github.event.repository.fork == false && github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_MOSS_0A047A40F }} # change this to your repository secret name + action: 'close' From c6b6408689ec43b5cb4a2e282905b581a6b43292 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 22:27:34 -0500 Subject: [PATCH 45/90] Update settings-context.js --- src/contexts/settings-context.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/contexts/settings-context.js b/src/contexts/settings-context.js index 76a29de26948..49b3eafedc6c 100644 --- a/src/contexts/settings-context.js +++ b/src/contexts/settings-context.js @@ -72,6 +72,7 @@ const initialSettings = { paletteMode: "light", pinNav: true, currentTenant: null, + showDevtools: false, }; const initialState = { From ed0c7d6adf4d07be07f2dcb178a4b73d90d4f2ca Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 22:37:58 -0500 Subject: [PATCH 46/90] fix tanstack tools --- src/pages/_app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/_app.js b/src/pages/_app.js index e520d50c5822..e5934e9bdf6b 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -111,11 +111,11 @@ const App = (props) => { /> - {settings?.showDevtools && ( + {settings?.showDevtools ? ( - )} + ) : null} ); }} From e8a15e93f4fcbae1cce3d43f001e1120cd1e149a Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 22:38:14 -0500 Subject: [PATCH 47/90] add default domain name --- .../CippIntegrations/CippIntegrationTenantMapping.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx b/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx index 179f057db2d2..5ad81d9ade01 100644 --- a/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx +++ b/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx @@ -89,6 +89,7 @@ const CippIntegrationSettings = ({ children }) => { Tenant: selectedTenant.label, IntegrationName: selectedCompany.label, IntegrationId: selectedCompany.value, + TenantDomain: selectedTenant.addedFields.defaultDomainName, }; setTableData([...tableData, newRowData]); @@ -109,6 +110,7 @@ const CippIntegrationSettings = ({ children }) => { newTableData.push({ TenantId: tenant.customerId, Tenant: tenant.displayName, + TenantDomain: tenant.defaultDomainName, IntegrationName: matchingCompany.name, IntegrationId: matchingCompany.value, }); From 1cbacd74e3fefa5e3b514257b6dac4901dd213f8 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 23:10:27 -0500 Subject: [PATCH 48/90] Update CippIntegrationTenantMapping.jsx --- .../CippIntegrations/CippIntegrationTenantMapping.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx b/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx index 5ad81d9ade01..53ed74c6e822 100644 --- a/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx +++ b/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx @@ -239,7 +239,7 @@ const CippIntegrationSettings = ({ children }) => { reportTitle={`${extension.id}-tenant-map`} data={tableData} simple={false} - simpleColumns={["Tenant", "IntegrationName"]} + simpleColumns={["IntegrationName", "Tenant", "TenantDomain"]} isFetching={mappings.isFetching} refreshFunction={() => mappings.refetch()} /> From 88fd0f6dca1984c00c65e40271facf2f71384e2f Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 23:20:41 -0500 Subject: [PATCH 49/90] Update _app.js --- src/pages/_app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/_app.js b/src/pages/_app.js index e5934e9bdf6b..69f35059554e 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -111,7 +111,7 @@ const App = (props) => { /> - {settings?.showDevtools ? ( + {settings.isInitialized && settings?.showDevtools === true ? ( From 94ea962755febfdfbef9a1d48999aa98e27cf780 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 25 Feb 2025 23:46:48 -0500 Subject: [PATCH 50/90] feat: check auth more frequently trigger logon page after 2 minutes if session times out and window focus changes --- src/api/ApiCall.jsx | 6 ++++-- src/components/CippComponents/CippSettingsSideBar.jsx | 3 +++ src/components/PrivateRoute.js | 6 ++++-- src/layouts/account-popover.js | 7 +++---- src/layouts/index.js | 2 ++ src/pages/unauthenticated.js | 4 +++- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/api/ApiCall.jsx b/src/api/ApiCall.jsx index fa953247204c..b8a38648769a 100644 --- a/src/api/ApiCall.jsx +++ b/src/api/ApiCall.jsx @@ -16,6 +16,8 @@ export function ApiGetCall(props) { bulkRequest = false, toast = false, onResult, + staleTime = 600000, // 10 minutes + refetchOnWindowFocus = false, } = props; const queryClient = useQueryClient(); const dispatch = useDispatch(); @@ -93,8 +95,8 @@ export function ApiGetCall(props) { return response.data; } }, - staleTime: 600000, // 10 minutes - refetchOnWindowFocus: false, + staleTime: staleTime, + refetchOnWindowFocus: refetchOnWindowFocus, retry: retryFn, }); return queryInfo; diff --git a/src/components/CippComponents/CippSettingsSideBar.jsx b/src/components/CippComponents/CippSettingsSideBar.jsx index 14c3ede87846..cb08993a8ea1 100644 --- a/src/components/CippComponents/CippSettingsSideBar.jsx +++ b/src/components/CippComponents/CippSettingsSideBar.jsx @@ -21,6 +21,9 @@ export const CippSettingsSideBar = (props) => { const currentUser = ApiGetCall({ url: "/.auth/me", + queryKey: "authmecipp", + staleTime: 120000, + refetchOnWindowFocus: true, }); const saveSettingsPost = ApiPostCall({ diff --git a/src/components/PrivateRoute.js b/src/components/PrivateRoute.js index 4c77fa33627c..011886bc4499 100644 --- a/src/components/PrivateRoute.js +++ b/src/components/PrivateRoute.js @@ -5,13 +5,15 @@ export const PrivateRoute = ({ children, routeType }) => { const { data: profile, error, - isFetching, + isLoading, } = ApiGetCall({ url: "/.auth/me", queryKey: "authmecipp", + refetchOnWindowFocus: true, + staleTime: 120000, // 2 minutes }); - if (isFetching) { + if (isLoading) { return "Loading..."; } diff --git a/src/layouts/account-popover.js b/src/layouts/account-popover.js index a8682abefa70..ab6b9a11155b 100644 --- a/src/layouts/account-popover.js +++ b/src/layouts/account-popover.js @@ -9,7 +9,6 @@ import SunIcon from "@heroicons/react/24/outline/SunIcon"; import { Avatar, Box, - FormControlLabel, List, ListItem, ListItemButton, @@ -18,10 +17,8 @@ import { Popover, Stack, SvgIcon, - Switch, Typography, useMediaQuery, - IconButton, } from "@mui/material"; import { usePopover } from "../hooks/use-popover"; import { paths } from "../paths"; @@ -42,7 +39,9 @@ export const AccountPopover = (props) => { const orgData = ApiGetCall({ url: "/.auth/me", - queryKey: "me", + queryKey: "authmecipp", + staleTime: 120000, + refetchOnWindowFocus: true, }); const handleLogout = useCallback(async () => { diff --git a/src/layouts/index.js b/src/layouts/index.js index 33ffc87aa2eb..892e54e4c485 100644 --- a/src/layouts/index.js +++ b/src/layouts/index.js @@ -83,6 +83,8 @@ export const Layout = (props) => { const currentRole = ApiGetCall({ url: "/.auth/me", queryKey: "authmecipp", + staleTime: 120000, + refetchOnWindowFocus: true, }); const [hideSidebar, setHideSidebar] = useState(false); diff --git a/src/pages/unauthenticated.js b/src/pages/unauthenticated.js index 6c06e2ca3a80..5543103d52d5 100644 --- a/src/pages/unauthenticated.js +++ b/src/pages/unauthenticated.js @@ -8,7 +8,9 @@ import { useState, useEffect } from "react"; const Page = () => { const orgData = ApiGetCall({ url: "/.auth/me", - queryKey: "me", + queryKey: "authmecipp", + staleTime: 120000, + refetchOnWindowFocus: true, }); const blockedRoles = ["anonymous", "authenticated"]; const [userRoles, setUserRoles] = useState([]); From 9f4c8f061c11e9cebfbbb2099e303ebb5fb2fe87 Mon Sep 17 00:00:00 2001 From: Esco Date: Wed, 26 Feb 2025 11:51:49 +0100 Subject: [PATCH 51/90] feat: new UserPreferredLanguage standard --- src/data/standards.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/data/standards.json b/src/data/standards.json index d9d135ca79c7..f86d36e285e9 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -909,6 +909,33 @@ "powershellEquivalent": "Graph API", "recommendedBy": [] }, + { + "name": "standards.UserPreferredLanguage", + "cat": "Entra (AAD) Standards", + "tag": [], + "helpText": "Sets the preferred language property for all users in the tenant. This will override the user's language settings.", + "docsDescription": "Sets the preferred language property for all users in the tenant. This will override the user's language settings.", + "addedComponent": [ + { + "type": "autoComplete", + "multiple": false, + "creatable": false, + "name": "standards.UserPreferredLanguage.preferredLanguage", + "label": "Preferred Language", + "api": { + "url": "/languageList.json", + "labelField": "language", + "valueField": "tag" + } + } + ], + "label": "Preferred language for all users", + "impact": "High Impact", + "impactColour": "info", + "addedDate": "2025-02-26", + "powershellEquivalent": "Update-MgUser -UserId user@domain.com -BodyParameter @{preferredLanguage='en-US'}", + "recommendedBy": [] + }, { "name": "standards.OutBoundSpamAlert", "cat": "Exchange Standards", From c7ca93cc691f2ee9848486df7cdbbb3ab69d1ea8 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 26 Feb 2025 16:52:33 -0500 Subject: [PATCH 52/90] Update standards.json --- src/data/standards.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/standards.json b/src/data/standards.json index d9d135ca79c7..b40aefec3cd2 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -3206,7 +3206,8 @@ { "type": "textField", "name": "standards.AutopilotStatusPage.ErrorMessage", - "label": "Custom Error Message" + "label": "Custom Error Message", + "required": false }, { "type": "switch", From 7d0e29559badf44e3777c8559a946f1d9e936f30 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 26 Feb 2025 17:24:20 -0500 Subject: [PATCH 53/90] fix tenant setting actions --- src/pages/cipp/settings/tenants.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/cipp/settings/tenants.js b/src/pages/cipp/settings/tenants.js index 529e7c413a18..320e22fa5add 100644 --- a/src/pages/cipp/settings/tenants.js +++ b/src/pages/cipp/settings/tenants.js @@ -21,6 +21,7 @@ const Page = () => { data: { value: "customerId" }, confirmText: "Are you sure you want to exclude these tenants?", multiPost: false, + condition: (row) => row.displayName !== '*Partner Tenant', }, { label: "Include Tenants", @@ -30,13 +31,14 @@ const Page = () => { data: { value: "customerId" }, confirmText: "Are you sure you want to include these tenants?", multiPost: false, + condition: (row) => row.displayName !== '*Partner Tenant', }, { label: "Refresh CPV Permissions", type: "POST", url: `/api/ExecCPVPermissions`, icon: , - data: { TenantFilter: "customerId" }, + data: { tenantFilter: "customerId" }, confirmText: "Are you sure you want to refresh the CPV permissions for these tenants?", multiPost: false, }, @@ -45,10 +47,11 @@ const Page = () => { type: "POST", url: `/api/ExecCPVPermissions?&ResetSP=true`, icon: , - data: { TenantFilter: "customerId" }, + data: { tenantFilter: "customerId" }, confirmText: "Are you sure you want to reset the CPV permissions for these tenants? (This will delete the Service Principal and re-add it.)", multiPost: false, + condition: (row) => row.displayName !== '*Partner Tenant', }, { label: "Remove Tenant", @@ -58,6 +61,7 @@ const Page = () => { data: { TenantID: "customerId" }, confirmText: "Are you sure you want to remove this tenant?", multiPost: false, + condition: (row) => row.displayName !== '*Partner Tenant', }, ]; From c8a21c4f26c04a1b9a001fcffdedd641a4db524c Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 26 Feb 2025 18:54:39 -0500 Subject: [PATCH 54/90] fix: external link turbo mode --- .../CippComponents/CippApiDialog.jsx | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/components/CippComponents/CippApiDialog.jsx b/src/components/CippComponents/CippApiDialog.jsx index d5e15d9bccff..a85e0e5a4830 100644 --- a/src/components/CippComponents/CippApiDialog.jsx +++ b/src/components/CippComponents/CippApiDialog.jsx @@ -274,19 +274,21 @@ export const CippApiDialog = (props) => { }; // Handling link navigation - if (api.link) { - const linkWithRowData = api.link.replace(/\[([^\]]+)\]/g, (_, key) => { - return getNestedValue(row, key) || `[${key}]`; - }); + useEffect(() => { + if (api.link && createDialog.open) { + const linkWithRowData = api.link.replace(/\[([^\]]+)\]/g, (_, key) => { + return getNestedValue(row, key) || `[${key}]`; + }); - if (linkWithRowData.startsWith("/")) { - router.push(linkWithRowData, undefined, { shallow: true }); - } else { - window.open(linkWithRowData, api.target || "_blank"); + if (linkWithRowData.startsWith("/")) { + router.push(linkWithRowData, undefined, { shallow: true }); + } else { + window.open(linkWithRowData, api.target || "_blank"); + } + createDialog.handleClose(); } + }, [api.link, createDialog.open]); - return null; - } useEffect(() => { if (api.noConfirm) { formHook.handleSubmit(onSubmit)(); // Submits the form on mount From 6f95ab364e065dab7de2699adb5baa349d997043 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 26 Feb 2025 19:06:02 -0500 Subject: [PATCH 55/90] feat: add role list back to user preferences page --- src/pages/cipp/preferences.js | 20 ++++++++++++++++++++ src/utils/get-cipp-formatting.js | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/pages/cipp/preferences.js b/src/pages/cipp/preferences.js index a6c34d96bbab..2653b577399d 100644 --- a/src/pages/cipp/preferences.js +++ b/src/pages/cipp/preferences.js @@ -9,11 +9,20 @@ import { useSettings } from "../../hooks/use-settings"; import countryList from "../../data/countryList.json"; import { CippSettingsSideBar } from "../../components/CippComponents/CippSettingsSideBar"; import CippDevOptions from "/src/components/CippComponents/CippDevOptions"; +import { ApiGetCall } from "../../api/ApiCall"; +import { getCippFormatting } from "../../utils/get-cipp-formatting"; const Page = () => { const settings = useSettings(); const formcontrol = useForm({ mode: "onChange", defaultValues: settings }); + const auth = ApiGetCall({ + url: "/.auth/me", + queryKey: "authmecipp", + staleTime: 120000, + refetchOnWindowFocus: true, + }); + const addedAttributes = [ { value: "consentProvidedForMinor", label: "consentProvidedForMinor" }, { value: "employeeId", label: "employeeId" }, @@ -281,6 +290,17 @@ const Page = () => { + !['anonymous', 'authenticated'].includes(role)) + .map((role) => ({ + label: "", + value: getCippFormatting(role,"role"), + }))} + showDivider={false} + /> + diff --git a/src/utils/get-cipp-formatting.js b/src/utils/get-cipp-formatting.js index 3d6841d267b4..25b1cd58c7ec 100644 --- a/src/utils/get-cipp-formatting.js +++ b/src/utils/get-cipp-formatting.js @@ -219,7 +219,7 @@ export const getCippFormatting = (data, cellName, type, canReceive) => { } } - if (cellName === "ClientId") { + if (cellName === "ClientId" || cellName === "role") { return isText ? data : ; } From 252b40e96f217623ef379857ac0ffa9d1c88add6 Mon Sep 17 00:00:00 2001 From: Esco Date: Thu, 27 Feb 2025 13:13:41 +0100 Subject: [PATCH 56/90] feat: more SpamFilter options --- src/data/standards.json | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/data/standards.json b/src/data/standards.json index b4eb7e73eab0..de8a4c8a2724 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -2268,6 +2268,82 @@ "value": "DefaultFullAccessWithNotificationPolicy" } ] + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.IncreaseScoreWithImageLinks", + "label": "Increase score if message contains image links to remote websites", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.IncreaseScoreWithBizOrInfoUrls", + "label": "Increase score if message contains links to .biz or .info domains", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamFramesInHtml", + "label": "Mark as spam if message contains HTML or iframe tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamObjectTagsInHtml", + "label": "Mark as spam if message contains HTML object tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamEmbedTagsInHtml", + "label": "Mark as spam if message contains HTML embed tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamFormTagsInHtml", + "label": "Mark as spam if message contains HTML form tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamWebBugsInHtml", + "label": "Mark as spam if message contains web bugs (also known as web beacons)", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamSensitiveWordList", + "label": "Mark as spam if message contains words from the sensitive words list", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.EnableLanguageBlockList", + "label": "Enable language block list", + "defaultValue": false + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "name": "standards.SpamFilterPolicy.LanguageBlockList", + "label": "Languages to block (uppercase ISO 639-1 two-letter)" + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.EnableRegionBlockList", + "label": "Enable region block list", + "defaultValue": false + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "name": "standards.SpamFilterPolicy.RegionBlockList", + "label": "Regions to block (uppercase ISO 3166-1 two-letter)" } ], "label": "Default Spam Filter Policy", From dd1c132defb3f6368e9d48a21d49164221effa6a Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 27 Feb 2025 12:10:32 -0500 Subject: [PATCH 57/90] feat: add docs link to speed dial --- src/pages/_app.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pages/_app.js b/src/pages/_app.js index 69f35059554e..00cfbe97275a 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -12,7 +12,6 @@ import { createEmotionCache } from "../utils/create-emotion-cache"; import "../libs/nprogress"; import { PrivateRoute } from "../components/PrivateRoute"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { useMediaPredicate } from "react-media-hook"; import Error500 from "./500"; import { ErrorBoundary } from "react-error-boundary"; @@ -25,10 +24,12 @@ import { Help as HelpIcon, BugReport as BugReportIcon, Feedback as FeedbackIcon, + AutoStories, } from "@mui/icons-material"; import { SvgIcon } from "@mui/material"; import discordIcon from "../../public/discord-mark-blue.svg"; import React from "react"; +import { usePathname } from "next/navigation"; TimeAgo.addDefaultLocale(en); const ReactQueryDevtoolsProduction = React.lazy(() => @@ -43,6 +44,7 @@ const App = (props) => { const { Component, emotionCache = clientSideEmotionCache, pageProps } = props; const getLayout = Component.getLayout ?? ((page) => page); const preferredTheme = useMediaPredicate("(prefers-color-scheme: dark)") ? "dark" : "light"; + const pathname = usePathname(); const speedDialActions = [ { @@ -69,6 +71,13 @@ const App = (props) => { href: "https://discord.gg/cyberdrain", onClick: () => window.open("https://discord.gg/cyberdrain", "_blank") }, + { + id: "documentation", + icon: , + name: "Check the Documentation", + href: `https://docs.cipp.app/user-documentation/${pathname}`, + onClick: () => window.open(`https://docs.cipp.app/user-documentation/${pathname}`, "_blank") + } ]; return ( From 4e0242c51b762c53b0528c00fada00fe248c74fe Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 27 Feb 2025 23:12:48 -0500 Subject: [PATCH 58/90] form tweaks --- src/components/CippStandards/CippStandardAccordion.jsx | 1 + src/pages/cipp/settings/partner-webhooks.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/CippStandards/CippStandardAccordion.jsx b/src/components/CippStandards/CippStandardAccordion.jsx index 4fc8eb1011d3..2d1ff418b693 100644 --- a/src/components/CippStandards/CippStandardAccordion.jsx +++ b/src/components/CippStandards/CippStandardAccordion.jsx @@ -49,6 +49,7 @@ const CippAddedComponent = React.memo(({ standardName, component, formControl }) label: tz.timezone, value: tz.timezone, })); + updatedComponent.multiple = false; } else { updatedComponent.type = component.type; } diff --git a/src/pages/cipp/settings/partner-webhooks.js b/src/pages/cipp/settings/partner-webhooks.js index d44f24c690a8..2a5c38ddae47 100644 --- a/src/pages/cipp/settings/partner-webhooks.js +++ b/src/pages/cipp/settings/partner-webhooks.js @@ -120,6 +120,7 @@ const Page = () => { title={pageTitle} hideBackButton={true} hidePageType={true} + allowResubmit={true} formControl={formControl} resetForm={false} postUrl="/api/ExecPartnerWebhook?Action=CreateSubscription" From 93ac677c1eec9a40c7fa8b0a012408d25a216bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 28 Feb 2025 16:22:35 +0100 Subject: [PATCH 59/90] feat: update mailbox API data structure to use ExchangeGuid so it dosnt fail when the user has a personal MS account --- src/pages/email/administration/mailboxes/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/email/administration/mailboxes/index.js b/src/pages/email/administration/mailboxes/index.js index 128fd39dd175..716f1abb4c53 100644 --- a/src/pages/email/administration/mailboxes/index.js +++ b/src/pages/email/administration/mailboxes/index.js @@ -121,14 +121,15 @@ const Page = () => { url: "/api/ExecStartManagedFolderAssistant", icon: , data: { - ID: "UPN", + ID: "ExchangeGuid", + UserPrincipalName: "UPN", }, confirmText: "Are you sure you want to start the managed folder assistant for this user?", }, { label: "Delete Mailbox", type: "POST", - icon: , // Added + icon: , url: "/api/RemoveUser", data: { ID: "UPN" }, confirmText: "Are you sure you want to delete this mailbox?", From 155954c5018f51a95e56da732d536c15b06904f0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:42:51 +0100 Subject: [PATCH 60/90] CIPP now gives head --- src/components/CippCards/CippPageCard.jsx | 5 ++--- src/components/CippComponents/CippHead.jsx | 11 +++++++++++ src/components/CippComponents/CippTablePage.jsx | 5 ++--- src/components/CippComponents/CippTenantSelector.jsx | 1 + src/components/CippFormPages/CippFormPage.jsx | 7 +++---- src/components/CippWizard/CippWizardPage.jsx | 5 ++--- src/pages/tenant/standards/bpa-report/builder.js | 5 ++--- 7 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 src/components/CippComponents/CippHead.jsx diff --git a/src/components/CippCards/CippPageCard.jsx b/src/components/CippCards/CippPageCard.jsx index 9c1e1bce81b7..72f44a95b09b 100644 --- a/src/components/CippCards/CippPageCard.jsx +++ b/src/components/CippCards/CippPageCard.jsx @@ -2,6 +2,7 @@ import { useRouter } from "next/router"; import { Box, Container, Stack, Button, SvgIcon, Typography, Card } from "@mui/material"; import ArrowLeftIcon from "@mui/icons-material/ArrowLeft"; import Head from "next/head"; +import { CippHead } from "../CippComponents/CippHead"; const CippPageCard = (props) => { const { title, @@ -20,9 +21,7 @@ const CippPageCard = (props) => { return ( <> - - {title} - + { + const tenant = useSettings().currentTenant; + return ( + + {tenant ? `${tenant} - ${title}` : title} + + ); +}; diff --git a/src/components/CippComponents/CippTablePage.jsx b/src/components/CippComponents/CippTablePage.jsx index 61f5e89cac86..37a3a9d44ccc 100644 --- a/src/components/CippComponents/CippTablePage.jsx +++ b/src/components/CippComponents/CippTablePage.jsx @@ -3,6 +3,7 @@ import { Box, Container, Stack } from "@mui/system"; import Head from "next/head"; import { CippDataTable } from "../CippTable/CippDataTable"; import { useSettings } from "../../hooks/use-settings"; +import { CippHead } from "./CippHead"; export const CippTablePage = (props) => { const { @@ -28,9 +29,7 @@ export const CippTablePage = (props) => { const tenant = useSettings().currentTenant; return ( <> - - {title} - + diff --git a/src/components/CippComponents/CippTenantSelector.jsx b/src/components/CippComponents/CippTenantSelector.jsx index 4471a2442415..9db78af9b6b4 100644 --- a/src/components/CippComponents/CippTenantSelector.jsx +++ b/src/components/CippComponents/CippTenantSelector.jsx @@ -58,6 +58,7 @@ export const CippTenantSelector = (props) => { settings.handleUpdate({ currentTenant: currentTenant.value, }); + //if we have a tenantfilter, we add the tenantfilter to the title of the tab/page so its "Tenant - original title". } }, [currentTenant?.value]); diff --git a/src/components/CippFormPages/CippFormPage.jsx b/src/components/CippFormPages/CippFormPage.jsx index baae183502a4..d22877dfb139 100644 --- a/src/components/CippFormPages/CippFormPage.jsx +++ b/src/components/CippFormPages/CippFormPage.jsx @@ -16,6 +16,7 @@ import { ApiPostCall } from "../../api/ApiCall"; import { CippApiResults } from "../CippComponents/CippApiResults"; import { useEffect } from "react"; import { useFormState } from "react-hook-form"; +import { CippHead } from "../CippComponents/CippHead"; const CippFormPage = (props) => { const { @@ -86,9 +87,7 @@ const CippFormPage = (props) => { }; return ( <> - - {title} - + { {addedButtons && addedButtons} } title="Report Settings" > - + {/* First item for Report Name and Layout Mode */} - - Layout Mode - - + - - {/* Third item for Buttons */} - {layoutMode === "Tenant" && ( - - - - - - )} - {/* Canvas Area */} - - Canvas - + + Fields + + {blockCards.map((block, index) => ( @@ -269,16 +270,16 @@ const Page = () => { key={block.id} > handleRemoveBlock(block.id)} // Remove block on click - > - - - ) + handleRemoveBlock(block.id)} // Remove block on click + > + + } > {/* Form inside each card */} @@ -310,7 +311,8 @@ const Page = () => { @@ -477,13 +479,17 @@ const Page = () => { type="autoComplete" formControl={formControl} multiple={false} - api={{ - queryKey: `ListBPA`, - url: "/api/ListBPA", - dataKey: "Keys", - labelField: (option) => `${option}`, - valueField: (option) => `${option}`, - }} + options={ + bpaTemplateList.data + ?.flatMap( + (template) => template.Fields?.map((field) => field.name) ?? [] + ) + .filter( + (value, index, self) => value && self.indexOf(value) === index + ) + .map((field) => ({ label: field, value: field })) + .sort((a, b) => a.label.localeCompare(b.label)) ?? [] + } /> From 65e06bcd6508b79c3ebc6832302eb7ad5002f1e5 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 1 Mar 2025 14:06:19 +0100 Subject: [PATCH 64/90] corrected tthe head --- src/components/CippComponents/CippHead.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CippComponents/CippHead.jsx b/src/components/CippComponents/CippHead.jsx index f71bce87349d..f48eb6b09321 100644 --- a/src/components/CippComponents/CippHead.jsx +++ b/src/components/CippComponents/CippHead.jsx @@ -5,7 +5,7 @@ export const CippHead = ({ title }) => { const tenant = useSettings().currentTenant; return ( - {tenant ? `${tenant} - ${title}` : title} + {tenant ? `${title} - ${tenant}` : title} ); }; From 01e8f52128a832c96fc11d680af5ed29df738604 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 1 Mar 2025 21:07:07 -0500 Subject: [PATCH 65/90] update help text for viva --- src/data/standards.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/standards.json b/src/data/standards.json index de8a4c8a2724..441c0a3d9b2e 100644 --- a/src/data/standards.json +++ b/src/data/standards.json @@ -1207,7 +1207,7 @@ "name": "standards.DisableViva", "cat": "Exchange Standards", "tag": [], - "helpText": "Disables the daily viva reports for all users.", + "helpText": "Disables the daily viva reports for all users. This standard requires the CIPP-SAM application to have the Company Administrator (Global Admin) role in the tenant. Enable this using CIPP > Advanced > Super Admin > SAM App Roles. Activate the roles with a CPV refresh.", "docsDescription": "", "addedComponent": [], "label": "Disable daily Insight/Viva reports", From ee660aedc5eb694f7f32a4c9bfafb209d8826cc7 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 2 Mar 2025 13:46:38 -0500 Subject: [PATCH 66/90] fix: remove required property on field mapping --- .../CippIntegrations/CippIntegrationFieldMapping.jsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx b/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx index 8b46afd209f7..54ace0e41464 100644 --- a/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx +++ b/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx @@ -140,12 +140,6 @@ const CippIntegrationFieldMapping = () => { fullWidth isFetching={fieldMapping.isFetching} disableClearable={true} - required={true} - validators={{ - validate: (value) => { - return value ? true : "Please select a value"; - }, - }} /> From dd2b13950b52fccd42dc48d481d90fa786644b11 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 2 Mar 2025 14:01:02 -0500 Subject: [PATCH 67/90] chore: update Grid to use mui/system --- .../CippIntegrationFieldMapping.jsx | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx b/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx index 54ace0e41464..0d8c98d4000f 100644 --- a/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx +++ b/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx @@ -1,12 +1,10 @@ import { Box, - Grid, CardContent, Skeleton, Typography, Divider, Tooltip, - IconButton, Button, Alert, } from "@mui/material"; @@ -18,7 +16,7 @@ import extensions from "/src/data/Extensions.json"; import React, { useEffect, useState } from "react"; import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; import { Sync } from "@mui/icons-material"; -import { Stack } from "@mui/system"; +import { Stack, Grid } from "@mui/system"; const CippIntegrationFieldMapping = () => { const router = useRouter(); @@ -113,35 +111,33 @@ const CippIntegrationFieldMapping = () => { )} - + {fieldMapping?.data?.CIPPFields?.filter( (field) => field.FieldType === header.FieldType ).map((field, fieldIndex) => ( - - - - (integrationField?.type === field.Type && - integrationField?.FieldType === field.FieldType) || - integrationField?.type === "unset" - )?.map((integrationField) => { - return { - label: integrationField?.name, - value: integrationField?.value, - }; - })} - formControl={formControl} - multiple={false} - creatable={false} - fullWidth - isFetching={fieldMapping.isFetching} - disableClearable={true} - /> - + + + (integrationField?.type === field.Type && + integrationField?.FieldType === field.FieldType) || + integrationField?.type === "unset" + )?.map((integrationField) => { + return { + label: integrationField?.name, + value: integrationField?.value, + }; + })} + formControl={formControl} + multiple={false} + creatable={false} + fullWidth + isFetching={fieldMapping.isFetching} + disableClearable={true} + /> ))} From 71d98ef8d1de25b3c2bd3a531a599fc6ca8973c2 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 2 Mar 2025 14:41:32 -0500 Subject: [PATCH 68/90] feat: improve cippformcondition add the ability to disable cippformcondition externally --- .../CippComponents/CippFormCondition.jsx | 19 ++++++++++++++++--- .../CippIntegrationSettings.jsx | 4 ++-- src/data/Extensions.json | 8 +++++++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/components/CippComponents/CippFormCondition.jsx b/src/components/CippComponents/CippFormCondition.jsx index 45ea1c016cac..8cf9a1040728 100644 --- a/src/components/CippComponents/CippFormCondition.jsx +++ b/src/components/CippComponents/CippFormCondition.jsx @@ -3,7 +3,15 @@ import isEqual from "lodash/isEqual"; // lodash for deep comparison import React from "react"; export const CippFormCondition = (props) => { - let { field, compareType = "is", compareValue, action = 'hide', children, formControl } = props; + let { + field, + compareType = "is", + compareValue, + action = "hide", + children, + formControl, + disabled = false, + } = props; if ( field === undefined || @@ -26,18 +34,23 @@ export const CippFormCondition = (props) => { const disableChildren = (children) => { return React.Children.map(children, (child) => { if (React.isValidElement(child)) { - if (child.props?.children && child.type.name !== "CippFormCondition") { + if (child.props?.children) { return React.cloneElement(child, { children: disableChildren(child.props.children), disabled: true, }); + } else { + return React.cloneElement(child, { disabled: true }); } - return React.cloneElement(child, { disabled: true }); } return child; }); }; + if (disabled) { + return disableChildren(children); + } + switch (compareType) { case "regex": if (watcher?.match(new RegExp(compareValue))) { diff --git a/src/components/CippIntegrations/CippIntegrationSettings.jsx b/src/components/CippIntegrations/CippIntegrationSettings.jsx index 07731168d0be..47b99c451510 100644 --- a/src/components/CippIntegrations/CippIntegrationSettings.jsx +++ b/src/components/CippIntegrations/CippIntegrationSettings.jsx @@ -26,6 +26,7 @@ const CippIntegrationSettings = ({ children }) => { }); const extension = extensions.find((extension) => extension.id === router.query.id); + const enabled = formControl.watch(`${extension?.id}.Enabled`); var logo = extension?.logo; if (preferredTheme === "dark" && extension?.logoDark) { @@ -54,12 +55,11 @@ const CippIntegrationSettings = ({ children }) => { resetForm={false} > {children} - {extension.SettingOptions.map((setting, index) => ( {setting?.condition ? ( - + s.name === `${extension.id}.Enabled`) && !enabled}> Date: Sun, 2 Mar 2025 19:32:13 -0500 Subject: [PATCH 69/90] test invalidate auth querykey on redirect --- src/api/ApiCall.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/api/ApiCall.jsx b/src/api/ApiCall.jsx index b8a38648769a..e7feb6f5748f 100644 --- a/src/api/ApiCall.jsx +++ b/src/api/ApiCall.jsx @@ -3,7 +3,6 @@ import axios, { isAxiosError } from "axios"; import { useDispatch } from "react-redux"; import { showToast } from "../store/toasts"; import { getCippError } from "../utils/get-cipp-error"; -import { useRouter } from "next/router"; export function ApiGetCall(props) { const { @@ -29,6 +28,12 @@ export function ApiGetCall(props) { returnRetry = false; } if (isAxiosError(error) && HTTP_STATUS_TO_NOT_RETRY.includes(error.response?.status ?? 0)) { + if ( + error.response?.status === 302 && + error.response?.headers.get("location").includes("/.auth/login/aad") + ) { + queryClient.invalidateQueries({ queryKey: ["authmecipp"] }); + } returnRetry = false; } if (returnRetry === false && toast) { From e6873838fea2e97d1d526f4e979ec8cac3d2f174 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 2 Mar 2025 21:10:32 -0500 Subject: [PATCH 70/90] fix: addtogroup functionality --- .../CippFormPages/CippAddEditUser.jsx | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/components/CippFormPages/CippAddEditUser.jsx b/src/components/CippFormPages/CippAddEditUser.jsx index f772ae0e8e0e..5aeab622c02c 100644 --- a/src/components/CippFormPages/CippAddEditUser.jsx +++ b/src/components/CippFormPages/CippAddEditUser.jsx @@ -291,7 +291,6 @@ const CippAddEditUser = (props) => { multiple={false} /> - {/* Schedule User Creation */} { multiple={false} /> + {formType === "edit" && ( + + + + )} + {/* Schedule User Creation */} {formType === "add" && ( Date: Mon, 3 Mar 2025 12:42:52 +0100 Subject: [PATCH 71/90] usability --- .../CippComponents/CippCentralSearch.jsx | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/CippComponents/CippCentralSearch.jsx b/src/components/CippComponents/CippCentralSearch.jsx index c710a8d2d49b..6a90c4e35b9d 100644 --- a/src/components/CippComponents/CippCentralSearch.jsx +++ b/src/components/CippComponents/CippCentralSearch.jsx @@ -9,6 +9,7 @@ import { Grid, Card, CardContent, + CardActionArea, Typography, Box, } from "@mui/material"; @@ -107,15 +108,19 @@ export const CippCentralSearch = ({ handleClose, open }) => { handleCardClick(item.path)} + sx={{ height: "100%" }} > - - {highlightMatch(item.title)} - - Path: {highlightMatch(item.path)} - - + handleCardClick(item.path)} + aria-label={`Navigate to ${item.title}`} + > + + {highlightMatch(item.title)} + + Path: {highlightMatch(item.path)} + + + ))} From 766e14e4ae2a5ca3faf35bb9d5db3037dbb97ac6 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 3 Mar 2025 11:40:47 -0500 Subject: [PATCH 72/90] fix: boolean support for cippapidialog --- src/components/CippComponents/CippApiDialog.jsx | 2 ++ src/components/CippSettings/CippCacheSettings.jsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/CippComponents/CippApiDialog.jsx b/src/components/CippComponents/CippApiDialog.jsx index a85e0e5a4830..347fa1eb9476 100644 --- a/src/components/CippComponents/CippApiDialog.jsx +++ b/src/components/CippComponents/CippApiDialog.jsx @@ -97,6 +97,8 @@ export const CippApiDialog = (props) => { } else { newData[key] = value; } + } else if (typeof value === 'boolean') { + newData[key] = value; } else if (typeof value === "object" && value !== null) { const processedValue = processActionData(value, row, replacementBehaviour); if (replacementBehaviour !== "removeNulls" || Object.keys(processedValue).length > 0) { diff --git a/src/components/CippSettings/CippCacheSettings.jsx b/src/components/CippSettings/CippCacheSettings.jsx index 5a2e97622056..a427ddd3acfe 100644 --- a/src/components/CippSettings/CippCacheSettings.jsx +++ b/src/components/CippSettings/CippCacheSettings.jsx @@ -69,8 +69,8 @@ const CippCacheSettings = () => { url: "/api/ListTenants", confirmText: "This will clear the cache used by CIPP. This will slow down some aspects of the application, and should only be used when instructed to do so by support.", - type: "GET", - data: { ClearCache: "!true", TenantsOnly: "tenantsOnly" }, + type: "POST", + data: { ClearCache: true }, replacementBehaviour: "removeNulls", }} row={{}} From b86fa06a14f9cf3444ea9104cf3023ae4f3c080b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 3 Mar 2025 11:41:02 -0500 Subject: [PATCH 73/90] fix: add redirect url to unauthenticated page --- src/pages/unauthenticated.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/unauthenticated.js b/src/pages/unauthenticated.js index 5543103d52d5..c9999fa4c155 100644 --- a/src/pages/unauthenticated.js +++ b/src/pages/unauthenticated.js @@ -50,10 +50,10 @@ const Page = () => { 0 ? "Return" : "Login"} - link={userRoles.length > 0 ? "/" : "/.auth/login/aad"} + linkText={userRoles.length > 0 ? "Return to Home" : "Login"} + link={userRoles.length > 0 ? "/" : `/.auth/login/aad?post_login_redirect_uri=${encodeURIComponent(window.location.href)}`} /> )} From d6732b5d03666b9b9a953ff5edbf10549cec0abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 3 Mar 2025 18:24:13 +0100 Subject: [PATCH 74/90] feat: add functionality to enable auto-expanding archive for users --- .../email/administration/mailboxes/index.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/pages/email/administration/mailboxes/index.js b/src/pages/email/administration/mailboxes/index.js index 716f1abb4c53..c4014ca25d38 100644 --- a/src/pages/email/administration/mailboxes/index.js +++ b/src/pages/email/administration/mailboxes/index.js @@ -2,8 +2,6 @@ import { Layout as DashboardLayout } from "/src/layouts/index.js"; import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"; import Link from "next/link"; import { Button } from "@mui/material"; -import { Add, Mail } from "@mui/icons-material"; - import { Archive, MailOutline, @@ -13,6 +11,8 @@ import { VisibilityOff, PhonelinkLock, Key, + PostAdd, + Add, } from "@mui/icons-material"; import { TrashIcon, MagnifyingGlassIcon, PlayCircleIcon } from "@heroicons/react/24/outline"; @@ -85,11 +85,22 @@ const Page = () => { type: "POST", icon: , url: "/api/ExecEnableArchive", - data: { ID: "UPN" }, + data: { ID: "Id", username: "UPN" }, confirmText: "Are you sure you want to enable the online archive for this user?", multiPost: false, condition: (row) => row.ArchiveGuid === "00000000-0000-0000-0000-000000000000", }, + { + label: "Enable Auto-Expanding Archive", + type: "POST", + icon: , + url: "/api/ExecEnableAutoExpandingArchive", + data: { ID: "Id", username: "UPN" }, + confirmText: + "Are you sure you want to enable auto-expanding archive for this user? The archive must already be enabled.", + multiPost: false, + condition: (row) => row.ArchiveGuid !== "00000000-0000-0000-0000-000000000000", + }, { label: "Hide from Global Address List", type: "POST", From 976dfb309a04be46dc5a39fcf6e1b91b27cdddba Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 3 Mar 2025 13:26:10 -0500 Subject: [PATCH 75/90] feat: add bookmarks --- src/layouts/index.js | 13 +- src/layouts/side-nav-item.js | 244 +++++++++++++++++++++-------------- src/layouts/side-nav.js | 50 +++---- src/layouts/top-nav.js | 80 +++++++++++- 4 files changed, 262 insertions(+), 125 deletions(-) diff --git a/src/layouts/index.js b/src/layouts/index.js index 892e54e4c485..fa6e9812d5b6 100644 --- a/src/layouts/index.js +++ b/src/layouts/index.js @@ -135,14 +135,23 @@ export const Layout = (props) => { useEffect(() => { if (userSettingsAPI.isSuccess && !userSettingsAPI.isFetching && !userSettingsComplete) { - //if usersettingsAPI.data contains offboardingDefaults.user, delete that specific key. + //if userSettingsAPI.data contains offboardingDefaults.user, delete that specific key. if (userSettingsAPI.data.offboardingDefaults?.user) { delete userSettingsAPI.data.offboardingDefaults.user; } if (userSettingsAPI?.data?.currentTheme) { delete userSettingsAPI.data.currentTheme; } - settings.handleUpdate(userSettingsAPI.data); + // get current devtools settings + var showDevtools = settings.showDevtools; + // get current bookmarks + var bookmarks = settings.bookmarks; + + settings.handleUpdate({ + ...userSettingsAPI.data, + bookmarks, + showDevtools, + }); setUserSettingsComplete(true); } }, [ diff --git a/src/layouts/side-nav-item.js b/src/layouts/side-nav-item.js index 750dcbf3f653..05bc97972da2 100644 --- a/src/layouts/side-nav-item.js +++ b/src/layouts/side-nav-item.js @@ -4,7 +4,10 @@ import PropTypes from "prop-types"; import ChevronRightIcon from "@heroicons/react/24/outline/ChevronRightIcon"; import ChevronDownIcon from "@heroicons/react/24/outline/ChevronDownIcon"; import ArrowTopRightOnSquareIcon from "@heroicons/react/24/outline/ArrowTopRightOnSquareIcon"; -import { Box, ButtonBase, Collapse, SvgIcon } from "@mui/material"; +import { Box, ButtonBase, Collapse, SvgIcon, Stack } from "@mui/material"; +import BookmarkBorderIcon from "@mui/icons-material/BookmarkBorder"; +import BookmarkIcon from "@mui/icons-material/Bookmark"; +import { useSettings } from "../hooks/use-settings"; export const SideNavItem = (props) => { const { @@ -20,11 +23,26 @@ export const SideNavItem = (props) => { } = props; const [open, setOpen] = useState(openImmediately); + const [hovered, setHovered] = useState(false); + const { handleUpdate, bookmarks = [] } = useSettings(); + const isBookmarked = bookmarks.some((bookmark) => bookmark.path === path); const handleToggle = useCallback(() => { setOpen((prevOpen) => !prevOpen); }, []); + const handleBookmarkToggle = useCallback( + (event) => { + event.stopPropagation(); + handleUpdate({ + bookmarks: isBookmarked + ? bookmarks.filter((bookmark) => bookmark.path !== path) + : [...bookmarks, { label: title, path }], + }); + }, + [isBookmarked, bookmarks, handleUpdate, path, title] + ); + // Dynamic spacing and font sizing based on depth const indent = depth > 0 ? depth * 1.5 : 1; // adjust multiplication factor as needed const fontSize = depth === 0 ? 14 : 13; // top-level 14, nested 13 @@ -32,8 +50,109 @@ export const SideNavItem = (props) => { if (children) { return (
  • + setHovered(true)} + onMouseLeave={() => setHovered(false)} + > + theme.typography.fontFamily, + fontSize: fontSize, + fontWeight: 500, + justifyContent: "flex-start", + px: `${indent * 6}px`, + py: "12px", + textAlign: "left", + whiteSpace: "nowrap", + width: "100%", + }} + > + + {icon} + + + {title} + + + {open ? : } + + + + + {children} + +
  • + ); + } + + // Leaf + const linkProps = path + ? external + ? { + component: "a", + href: path, + target: "_blank", + } + : { + component: NextLink, + href: path, + } + : {}; + + return ( +
  • + setHovered(true)} + onMouseLeave={() => setHovered(false)} + sx={{ + display: "flex", + alignItems: "center", + }} + > { whiteSpace: "nowrap", width: "100%", }} + {...linkProps} > { sx={{ color: depth === 0 ? "text.primary" : "text.secondary", flexGrow: 1, - fontSize: fontSize, mx: "12px", transition: "opacity 250ms ease-in-out", ...(active && { @@ -82,106 +201,35 @@ export const SideNavItem = (props) => { > {title} - - {open ? : } - + {external && ( + + + + )} - - {children} - -
  • - ); - } - - // Leaf - const linkProps = path - ? external - ? { - component: "a", - href: path, - target: "_blank", - } - : { - component: NextLink, - href: path, - } - : {}; - - return ( -
  • - theme.typography.fontFamily, - fontSize: fontSize, - fontWeight: 500, - justifyContent: "flex-start", - px: `${indent * 6}px`, - py: "12px", - textAlign: "left", - whiteSpace: "nowrap", - width: "100%", - }} - {...linkProps} - > - - {icon} - - - {title} - - {external && ( - - - - )} - + {isBookmarked ? : } + +
  • ); }; diff --git a/src/layouts/side-nav.js b/src/layouts/side-nav.js index b2967a01a548..ca6d32b13ed8 100644 --- a/src/layouts/side-nav.js +++ b/src/layouts/side-nav.js @@ -5,6 +5,7 @@ import { Box, Divider, Drawer, Stack, Typography } from "@mui/material"; import { Scrollbar } from "../components/scrollbar"; import { SideNavItem } from "./side-nav-item"; import { useSettings } from "../hooks/use-settings"; +import { ApiGetCall } from "../api/ApiCall.jsx"; const SIDE_NAV_WIDTH = 270; const SIDE_NAV_COLLAPSED_WIDTH = 73; // icon size + padding + border right @@ -106,6 +107,7 @@ export const SideNav = (props) => { const pathname = usePathname(); const [hovered, setHovered] = useState(false); const collapse = !(pinned || hovered); + const { data: profile } = ApiGetCall({ url: "/.auth/me", queryKey: "authmecipp" }); // Preprocess items to mark which should be open const processedItems = markOpenItems(items, pathname); @@ -212,28 +214,32 @@ export const SideNav = (props) => { pathname, })}
    - - - This application is sponsored by - - - sponsor window.open(randomimg.link)} - width={"100px"} - /> - + {profile?.clientPrincipal && ( + <> + + + This application is sponsored by + + + sponsor window.open(randomimg.link)} + width={"100px"} + /> + + + )} diff --git a/src/layouts/top-nav.js b/src/layouts/top-nav.js index b92b1ace3d31..73e66f841a26 100644 --- a/src/layouts/top-nav.js +++ b/src/layouts/top-nav.js @@ -1,10 +1,23 @@ -import { useCallback, useEffect } from "react"; +import { useCallback, useEffect, useState } from "react"; import NextLink from "next/link"; import PropTypes from "prop-types"; import Bars3Icon from "@heroicons/react/24/outline/Bars3Icon"; import MoonIcon from "@heroicons/react/24/outline/MoonIcon"; import SunIcon from "@heroicons/react/24/outline/SunIcon"; -import { Box, Divider, IconButton, Stack, SvgIcon, useMediaQuery } from "@mui/material"; +import BookmarkIcon from "@mui/icons-material/Bookmark"; +import { + Box, + Divider, + IconButton, + Stack, + SvgIcon, + useMediaQuery, + Popover, + List, + ListItem, + ListItemText, + Typography, +} from "@mui/material"; import { Logo } from "../components/logo"; import { useSettings } from "../hooks/use-settings"; import { paths } from "../paths"; @@ -12,7 +25,7 @@ import { AccountPopover } from "./account-popover"; import { CippTenantSelector } from "../components/CippComponents/CippTenantSelector"; import { NotificationsPopover } from "./notifications-popover"; import { useDialog } from "../hooks/use-dialog"; -import { MagnifyingGlassCircleIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; +import { MagnifyingGlassIcon } from "@heroicons/react/24/outline"; import { CippCentralSearch } from "../components/CippComponents/CippCentralSearch"; const TOP_NAV_HEIGHT = 64; @@ -28,6 +41,19 @@ export const TopNav = (props) => { }); }, [settings]); + const [anchorEl, setAnchorEl] = useState(null); + + const handleBookmarkClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleBookmarkClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "bookmark-popover" : undefined; + useEffect(() => { const handleKeyDown = (event) => { if ((event.metaKey || event.ctrlKey) && event.key === "k") { @@ -111,8 +137,56 @@ export const TopNav = (props) => { + + + + + + + + {(settings.bookmarks || []).length === 0 ? ( + + No bookmarks added yet
    + } + /> + + ) : ( + settings.bookmarks.map((bookmark, idx) => ( + + {bookmark.label}
    + } + /> + + )) + )} + + + Date: Mon, 3 Mar 2025 14:34:12 -0500 Subject: [PATCH 76/90] add close nav --- src/layouts/top-nav.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layouts/top-nav.js b/src/layouts/top-nav.js index 73e66f841a26..ea2e7d4d0a86 100644 --- a/src/layouts/top-nav.js +++ b/src/layouts/top-nav.js @@ -173,6 +173,7 @@ export const TopNav = (props) => { href={bookmark.path} key={idx} sx={{ color: "inherit" }} + onClick={() => handleBookmarkClose()} > Date: Mon, 3 Mar 2025 20:40:02 +0100 Subject: [PATCH 77/90] feat: add disable forwarding functionality in CippWizardOffboarding --- .../CippWizard/CippWizardOffboarding.jsx | 81 ++++++++++++------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/src/components/CippWizard/CippWizardOffboarding.jsx b/src/components/CippWizard/CippWizardOffboarding.jsx index bfc00908777d..64ac7cdc602f 100644 --- a/src/components/CippWizard/CippWizardOffboarding.jsx +++ b/src/components/CippWizard/CippWizardOffboarding.jsx @@ -13,6 +13,7 @@ export const CippWizardOffboarding = (props) => { const selectedUsers = useWatch({ control: formControl.control, name: "user" }); const [showAlert, setShowAlert] = useState(false); const userSettingsDefaults = useSettings().userSettingsDefaults; + const disableForwarding = useWatch({ control: formControl.control, name: "disableForwarding" }); useEffect(() => { if (selectedUsers.length >= 4) { @@ -29,6 +30,13 @@ export const CippWizardOffboarding = (props) => { } }, [userSettingsDefaults]); + useEffect(() => { + if (disableForwarding) { + formControl.setValue("forward", null); + formControl.setValue("keepCopy", false); + } + }, [disableForwarding, formControl]); + return ( @@ -210,36 +218,50 @@ export const CippWizardOffboarding = (props) => { Email Forwarding `${option.displayName} (${option.userPrincipalName})`, - valueField: "id", - url: "/api/ListGraphRequest", - dataKey: "Results", - data: { - Endpoint: "users", - manualPagination: true, - $select: "id,userPrincipalName,displayName", - $count: true, - $orderby: "displayName", - $top: 999, - }, - }} /> - + field={"disableForwarding"} + compareType="isNot" + compareValue={true} + > + `${option.displayName} (${option.userPrincipalName})`, + valueField: "id", + url: "/api/ListGraphRequest", + dataKey: "Results", + data: { + Endpoint: "users", + manualPagination: true, + $select: "id,userPrincipalName,displayName", + $count: true, + $orderby: "displayName", + $top: 999, + }, + }} + /> + + + { type="switch" formControl={formControl} /> - + From 0b6eebab879da517ae8e1d05df4b3e909689cc55 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 3 Mar 2025 20:21:40 -0500 Subject: [PATCH 78/90] fix: casing --- src/pages/tenant/standards/bpa-report/builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/tenant/standards/bpa-report/builder.js b/src/pages/tenant/standards/bpa-report/builder.js index b943e243ec21..e36427aaa479 100644 --- a/src/pages/tenant/standards/bpa-report/builder.js +++ b/src/pages/tenant/standards/bpa-report/builder.js @@ -352,7 +352,7 @@ const Page = () => { From 9a73a158165684163163756923a602a0f5a2ab01 Mon Sep 17 00:00:00 2001 From: Esco Date: Tue, 4 Mar 2025 14:50:10 +0100 Subject: [PATCH 79/90] feat: display manager in view user --- src/components/CippCards/CippUserInfoCard.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/CippCards/CippUserInfoCard.jsx b/src/components/CippCards/CippUserInfoCard.jsx index 49c0ec716ab1..f0de3777f71a 100644 --- a/src/components/CippCards/CippUserInfoCard.jsx +++ b/src/components/CippCards/CippUserInfoCard.jsx @@ -112,10 +112,14 @@ export const CippUserInfoCard = (props) => { value={isFetching ? : user?.jobTitle || "N/A"} /> : user?.department || "N/A"} /> + : user?.manager?.displayName || "N/A"} + /> Date: Tue, 4 Mar 2025 09:41:08 -0500 Subject: [PATCH 80/90] feat: add application roles to permission check --- .../CippSettings/CippPermissionResults.jsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/CippSettings/CippPermissionResults.jsx b/src/components/CippSettings/CippPermissionResults.jsx index 57745d6d6760..2031b267d70d 100644 --- a/src/components/CippSettings/CippPermissionResults.jsx +++ b/src/components/CippSettings/CippPermissionResults.jsx @@ -231,6 +231,21 @@ export const CippPermissionResults = (props) => { /> )} + {results?.Results?.ApplicationTokenDetails?.Roles.length > 0 && ( + <> + { + return { + Role: role, + }; + })} + simpleColumns={["Role"]} + /> + + )} )} From 98d817d6ba3ad6455fb747876210de1b89b6ed5b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 4 Mar 2025 09:43:52 -0500 Subject: [PATCH 81/90] fix: remove internal link routing from useEffect --- .../CippComponents/CippApiDialog.jsx | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/CippComponents/CippApiDialog.jsx b/src/components/CippComponents/CippApiDialog.jsx index 347fa1eb9476..3a49fbee62be 100644 --- a/src/components/CippComponents/CippApiDialog.jsx +++ b/src/components/CippComponents/CippApiDialog.jsx @@ -275,22 +275,32 @@ export const CippApiDialog = (props) => { .reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj); }; - // Handling link navigation + // Handling external link navigation useEffect(() => { if (api.link && createDialog.open) { const linkWithRowData = api.link.replace(/\[([^\]]+)\]/g, (_, key) => { return getNestedValue(row, key) || `[${key}]`; }); - if (linkWithRowData.startsWith("/")) { - router.push(linkWithRowData, undefined, { shallow: true }); - } else { + if (!linkWithRowData.startsWith("/")) { window.open(linkWithRowData, api.target || "_blank"); + createDialog.handleClose(); } - createDialog.handleClose(); } }, [api.link, createDialog.open]); + // Handling internal link navigation + if (api.link && createDialog.open) { + const linkWithRowData = api.link.replace(/\[([^\]]+)\]/g, (_, key) => { + return getNestedValue(row, key) || `[${key}]`; + }); + + if (linkWithRowData.startsWith("/")) { + router.push(linkWithRowData, undefined, { shallow: true }); + createDialog.handleClose(); + } + } + useEffect(() => { if (api.noConfirm) { formHook.handleSubmit(onSubmit)(); // Submits the form on mount From 4a319e214262953c26f3c3d3ddd12705238143b1 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 4 Mar 2025 10:00:24 -0500 Subject: [PATCH 82/90] fix: tenant list links --- .../tenant/administration/tenants/index.js | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/pages/tenant/administration/tenants/index.js b/src/pages/tenant/administration/tenants/index.js index 1fba7f387944..ee07d9b30096 100644 --- a/src/pages/tenant/administration/tenants/index.js +++ b/src/pages/tenant/administration/tenants/index.js @@ -6,28 +6,6 @@ import { useEffect } from "react"; const Page = () => { //this page is special and requires us to craft the columns and DashboardLayout const pageTitle = "Tenants"; - const tenantData = ApiGetCall({ - url: "/api/listTenants", - queryKey: "ListTenants", - }); - - useEffect(() => { - if (tenantData.isSuccess) { - tenantData.data.forEach((tenant) => { - Object.assign(tenant, { - portal_m365: `https://admin.microsoft.com/Partner/BeginClientSession.aspx?CTID=${tenant.customerId}&CSDEST=o365admincenter`, - portal_exchange: `https://admin.exchange.microsoft.com/?landingpage=homepage&form=mac_sidebar&delegatedOrg=${tenant.defaultDomainName}`, - portal_entra: `https://entra.microsoft.com/${tenant.defaultDomainName}`, - portal_teams: `https://admin.teams.microsoft.com/?delegatedOrg=${tenant.defaultDomainName}`, - portal_azure: `https://portal.azure.com/${tenant.defaultDomainName}`, - portal_intune: `https://intune.microsoft.com/${tenant.defaultDomainName}`, - portal_security: `https://security.microsoft.com/?tid=${tenant.customerId}`, - portal_compliance: `https://purview.microsoft.com/?tid=${tenant.customerId}`, - portal_sharepoint: `https://admin.microsoft.com/Partner/beginclientsession.aspx?CTID=${tenant.customerId}&CSDEST=SharePoint`, - }); - }); - } - }, [tenantData.isSuccess]); const simpleColumns = [ "displayName", @@ -46,7 +24,12 @@ const Page = () => { title={pageTitle} tenantInTitle={false} simpleColumns={simpleColumns} - data={tenantData.data} + apiUrl="/api/ListTenants" + queryKey="TenantListPage" + apiData={{ + Mode: "TenantList", + tenantFilter: null, + }} /> ); }; From 21e555ab6d8ee7cdd814af1a29ac753a39e88ff3 Mon Sep 17 00:00:00 2001 From: Esco Date: Tue, 4 Mar 2025 12:30:20 +0100 Subject: [PATCH 83/90] feat: added set sponsor in edit user chore: make setSponsor a userAttributes fix --- src/components/CippFormPages/CippAddEditUser.jsx | 11 +++++++++++ src/pages/cipp/preferences.js | 1 + 2 files changed, 12 insertions(+) diff --git a/src/components/CippFormPages/CippAddEditUser.jsx b/src/components/CippFormPages/CippAddEditUser.jsx index 5aeab622c02c..0a4d57feba1d 100644 --- a/src/components/CippFormPages/CippAddEditUser.jsx +++ b/src/components/CippFormPages/CippAddEditUser.jsx @@ -291,6 +291,17 @@ const CippAddEditUser = (props) => { multiple={false} /> + {userSettingsDefaults?.userAttributes?.some(attribute => attribute.value === "sponsor") && ( + + + + )} { { value: "otherMails", label: "otherMails" }, { value: "showInAddressList", label: "showInAddressList" }, { value: "state", label: "state" }, + { value: "sponsor", label: "sponsor" }, ]; const pageSizes = [ From a121a37e6d43f959686c9fda71a217b293bc4957 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 4 Mar 2025 11:07:30 -0500 Subject: [PATCH 84/90] chore: cleanup user preferences --- src/pages/cipp/preferences.js | 37 ++++++++--------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/pages/cipp/preferences.js b/src/pages/cipp/preferences.js index 2653b577399d..fa8d47b65746 100644 --- a/src/pages/cipp/preferences.js +++ b/src/pages/cipp/preferences.js @@ -65,30 +65,15 @@ const Page = () => { - ), - }, { label: "Default new user usage location", value: ( { value: ( { ), }, { - label: "Menu Favourites", + label: "Added Attributes when creating a new user", value: ( ), }, @@ -293,10 +272,10 @@ const Page = () => { !['anonymous', 'authenticated'].includes(role)) + .filter((role) => !["anonymous", "authenticated"].includes(role)) .map((role) => ({ label: "", - value: getCippFormatting(role,"role"), + value: getCippFormatting(role, "role"), }))} showDivider={false} /> From 364349191f2148be5d22a2e6c963fa2bbc774389 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 4 Mar 2025 12:06:57 -0500 Subject: [PATCH 85/90] chore: add license page back --- src/pages/_app.js | 33 +- src/pages/license.js | 714 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 740 insertions(+), 7 deletions(-) create mode 100644 src/pages/license.js diff --git a/src/pages/_app.js b/src/pages/_app.js index 00cfbe97275a..ba282a7fb405 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -25,11 +25,14 @@ import { BugReport as BugReportIcon, Feedback as FeedbackIcon, AutoStories, + Gavel, } from "@mui/icons-material"; import { SvgIcon } from "@mui/material"; import discordIcon from "../../public/discord-mark-blue.svg"; import React from "react"; import { usePathname } from "next/navigation"; +import { icon } from "leaflet"; +import { useRouter } from "next/router"; TimeAgo.addDefaultLocale(en); const ReactQueryDevtoolsProduction = React.lazy(() => @@ -45,39 +48,55 @@ const App = (props) => { const getLayout = Component.getLayout ?? ((page) => page); const preferredTheme = useMediaPredicate("(prefers-color-scheme: dark)") ? "dark" : "light"; const pathname = usePathname(); + const route = useRouter(); const speedDialActions = [ + { + id: "license", + icon: , + name: "License", + href: "/license", + onClick: () => route.push("/license"), + }, { id: "bug-report", icon: , name: "Report Bug", href: "https://github.com/KelvinTegelaar/CIPP/issues/new?template=bug.yml", - onClick: () => window.open("https://github.com/KelvinTegelaar/CIPP/issues/new?template=bug.yml", "_blank") + onClick: () => + window.open("https://github.com/KelvinTegelaar/CIPP/issues/new?template=bug.yml", "_blank"), }, { id: "feature-request", icon: , name: "Request Feature", href: "https://github.com/KelvinTegelaar/CIPP/issues/new?template=feature.yml", - onClick: () => window.open("https://github.com/KelvinTegelaar/CIPP/issues/new?template=feature.yml", "_blank") + onClick: () => + window.open( + "https://github.com/KelvinTegelaar/CIPP/issues/new?template=feature.yml", + "_blank" + ), }, { id: "discord", icon: ( - - + ), name: "Join the Discord!", href: "https://discord.gg/cyberdrain", - onClick: () => window.open("https://discord.gg/cyberdrain", "_blank") + onClick: () => window.open("https://discord.gg/cyberdrain", "_blank"), }, { id: "documentation", icon: , name: "Check the Documentation", href: `https://docs.cipp.app/user-documentation/${pathname}`, - onClick: () => window.open(`https://docs.cipp.app/user-documentation/${pathname}`, "_blank") - } + onClick: () => window.open(`https://docs.cipp.app/user-documentation/${pathname}`, "_blank"), + }, ]; return ( diff --git a/src/pages/license.js b/src/pages/license.js new file mode 100644 index 000000000000..442aede25829 --- /dev/null +++ b/src/pages/license.js @@ -0,0 +1,714 @@ +import { Container } from "@mui/system"; +import { Layout as DashboardLayout } from "/src/layouts/index.js"; +import { Link } from "@mui/material"; + +const Page = () => { + const pageTitle = "License"; + + return ( + +

    GNU AFFERO GENERAL PUBLIC LICENSE

    +

    Version 3, 19 November 2007

    + +

    + Copyright © 2007 Free Software Foundation, Inc. < + https://fsf.org/> +
    + Everyone is permitted to copy and distribute verbatim copies of this license document, but + changing it is not allowed. +

    + +

    Preamble

    + +

    + The GNU Affero General Public License is a free, copyleft license for software and other + kinds of works, specifically designed to ensure cooperation with the community in the case + of network server software. +

    + +

    + The licenses for most software and other practical works are designed to take away your + freedom to share and change the works. By contrast, our General Public Licenses are intended + to guarantee your freedom to share and change all versions of a program--to make sure it + remains free software for all its users. +

    + +

    + When we speak of free software, we are referring to freedom, not price. Our General Public + Licenses are designed to make sure that you have the freedom to distribute copies of free + software (and charge for them if you wish), that you receive source code or can get it if + you want it, that you can change the software or use pieces of it in new free programs, and + that you know you can do these things. +

    + +

    + Developers that use our General Public Licenses protect your rights with two steps: (1) + assert copyright on the software, and (2) offer you this License which gives you legal + permission to copy, distribute and/or modify the software. +

    + +

    + A secondary benefit of defending all users' freedom is that improvements made in + alternate versions of the program, if they receive widespread use, become available for + other developers to incorporate. Many developers of free software are heartened and + encouraged by the resulting cooperation. However, in the case of software used on network + servers, this result may fail to come about. The GNU General Public License permits making a + modified version and letting the public access it on a server without ever releasing its + source code to the public. +

    + +

    + The GNU Affero General Public License is designed specifically to ensure that, in such + cases, the modified source code becomes available to the community. It requires the operator + of a network server to provide the source code of the modified version running there to the + users of that server. Therefore, public use of a modified version, on a publicly accessible + server, gives the public access to the source code of the modified version. +

    + +

    + An older license, called the Affero General Public License and published by Affero, was + designed to accomplish similar goals. This is a different license, not a version of the + Affero GPL, but Affero has released a new version of the Affero GPL which permits + relicensing under this license. +

    + +

    The precise terms and conditions for copying, distribution and modification follow.

    + +

    TERMS AND CONDITIONS

    + +

    0. Definitions.

    + +

    "This License" refers to version 3 of the GNU Affero General Public License.

    + +

    + "Copyright" also means copyright-like laws that apply to other kinds of works, + such as semiconductor masks. +

    + +

    + "The Program" refers to any copyrightable work licensed under this License. Each + licensee is addressed as "you". "Licensees" and "recipients" + may be individuals or organizations. +

    + +

    + To "modify" a work means to copy from or adapt all or part of the work in a + fashion requiring copyright permission, other than the making of an exact copy. The + resulting work is called a "modified version" of the earlier work or a work + "based on" the earlier work. +

    + +

    + A "covered work" means either the unmodified Program or a work based on the + Program. +

    + +

    + To "propagate" a work means to do anything with it that, without permission, would + make you directly or secondarily liable for infringement under applicable copyright law, + except executing it on a computer or modifying a private copy. Propagation includes copying, + distribution (with or without modification), making available to the public, and in some + countries other activities as well. +

    + +

    + To "convey" a work means any kind of propagation that enables other parties to + make or receive copies. Mere interaction with a user through a computer network, with no + transfer of a copy, is not conveying. +

    + +

    + An interactive user interface displays "Appropriate Legal Notices" to the extent + that it includes a convenient and prominently visible feature that (1) displays an + appropriate copyright notice, and (2) tells the user that there is no warranty for the work + (except to the extent that warranties are provided), that licensees may convey the work + under this License, and how to view a copy of this License. If the interface presents a list + of user commands or options, such as a menu, a prominent item in the list meets this + criterion. +

    + +

    1. Source Code.

    + +

    + The "source code" for a work means the preferred form of the work for making + modifications to it. "Object code" means any non-source form of a work. +

    + +

    + A "Standard Interface" means an interface that either is an official standard + defined by a recognized standards body, or, in the case of interfaces specified for a + particular programming language, one that is widely used among developers working in that + language. +

    + +

    + The "System Libraries" of an executable work include anything, other than the work + as a whole, that (a) is included in the normal form of packaging a Major Component, but + which is not part of that Major Component, and (b) serves only to enable use of the work + with that Major Component, or to implement a Standard Interface for which an implementation + is available to the public in source code form. A "Major Component", in this + context, means a major essential component (kernel, window system, and so on) of the + specific operating system (if any) on which the executable work runs, or a compiler used to + produce the work, or an object code interpreter used to run it. +

    + +

    + The "Corresponding Source" for a work in object code form means all the source + code needed to generate, install, and (for an executable work) run the object code and to + modify the work, including scripts to control those activities. However, it does not include + the work's System Libraries, or general-purpose tools or generally available free + programs which are used unmodified in performing those activities but which are not part of + the work. For example, Corresponding Source includes interface definition files associated + with source files for the work, and the source code for shared libraries and dynamically + linked subprograms that the work is specifically designed to require, such as by intimate + data communication or control flow between those subprograms and other parts of the work. +

    + +

    + The Corresponding Source need not include anything that users can regenerate automatically + from other parts of the Corresponding Source. +

    + +

    The Corresponding Source for a work in source code form is that same work.

    + +

    2. Basic Permissions.

    + +

    + All rights granted under this License are granted for the term of copyright on the Program, + and are irrevocable provided the stated conditions are met. This License explicitly affirms + your unlimited permission to run the unmodified Program. The output from running a covered + work is covered by this License only if the output, given its content, constitutes a covered + work. This License acknowledges your rights of fair use or other equivalent, as provided by + copyright law. +

    + +

    + You may make, run and propagate covered works that you do not convey, without conditions so + long as your license otherwise remains in force. You may convey covered works to others for + the sole purpose of having them make modifications exclusively for you, or provide you with + facilities for running those works, provided that you comply with the terms of this License + in conveying all material for which you do not control copyright. Those thus making or + running the covered works for you must do so exclusively on your behalf, under your + direction and control, on terms that prohibit them from making any copies of your + copyrighted material outside their relationship with you. +

    + +

    + Conveying under any other circumstances is permitted solely under the conditions stated + below. Sublicensing is not allowed; section 10 makes it unnecessary. +

    + +

    3. Protecting Users' Legal Rights From Anti-Circumvention Law.

    + +

    + No covered work shall be deemed part of an effective technological measure under any + applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted + on 20 December 1996, or similar laws prohibiting or restricting circumvention of such + measures. +

    + +

    + When you convey a covered work, you waive any legal power to forbid circumvention of + technological measures to the extent such circumvention is effected by exercising rights + under this License with respect to the covered work, and you disclaim any intention to limit + operation or modification of the work as a means of enforcing, against the work's + users, your or third parties' legal rights to forbid circumvention of technological + measures. +

    + +

    4. Conveying Verbatim Copies.

    + +

    + You may convey verbatim copies of the Program's source code as you receive it, in any + medium, provided that you conspicuously and appropriately publish on each copy an + appropriate copyright notice; keep intact all notices stating that this License and any + non-permissive terms added in accord with section 7 apply to the code; keep intact all + notices of the absence of any warranty; and give all recipients a copy of this License along + with the Program. +

    + +

    + You may charge any price or no price for each copy that you convey, and you may offer + support or warranty protection for a fee. +

    + +

    5. Conveying Modified Source Versions.

    + +

    + You may convey a work based on the Program, or the modifications to produce it from the + Program, in the form of source code under the terms of section 4, provided that you also + meet all of these conditions: +

    + +
      +
    • + a) The work must carry prominent notices stating that you modified it, and giving a + relevant date. +
    • + +
    • + b) The work must carry prominent notices stating that it is released under this License + and any conditions added under section 7. This requirement modifies the requirement in + section 4 to "keep intact all notices". +
    • + +
    • + c) You must license the entire work, as a whole, under this License to anyone who comes + into possession of a copy. This License will therefore apply, along with any applicable + section 7 additional terms, to the whole of the work, and all its parts, regardless of how + they are packaged. This License gives no permission to license the work in any other way, + but it does not invalidate such permission if you have separately received it. +
    • + +
    • + d) If the work has interactive user interfaces, each must display Appropriate Legal + Notices; however, if the Program has interactive interfaces that do not display + Appropriate Legal Notices, your work need not make them do so. +
    • +
    + +

    + A compilation of a covered work with other separate and independent works, which are not by + their nature extensions of the covered work, and which are not combined with it such as to + form a larger program, in or on a volume of a storage or distribution medium, is called an + "aggregate" if the compilation and its resulting copyright are not used to limit + the access or legal rights of the compilation's users beyond what the individual works + permit. Inclusion of a covered work in an aggregate does not cause this License to apply to + the other parts of the aggregate. +

    + +

    6. Conveying Non-Source Forms.

    + +

    + You may convey a covered work in object code form under the terms of sections 4 and 5, + provided that you also convey the machine-readable Corresponding Source under the terms of + this License, in one of these ways: +

    + +
      +
    • + a) Convey the object code in, or embodied in, a physical product (including a physical + distribution medium), accompanied by the Corresponding Source fixed on a durable physical + medium customarily used for software interchange. +
    • + +
    • + b) Convey the object code in, or embodied in, a physical product (including a physical + distribution medium), accompanied by a written offer, valid for at least three years and + valid for as long as you offer spare parts or customer support for that product model, to + give anyone who possesses the object code either (1) a copy of the Corresponding Source + for all the software in the product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no more than your reasonable + cost of physically performing this conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. +
    • + +
    • + c) Convey individual copies of the object code with a copy of the written offer to provide + the Corresponding Source. This alternative is allowed only occasionally and + noncommercially, and only if you received the object code with such an offer, in accord + with subsection 6b. +
    • + +
    • + d) Convey the object code by offering access from a designated place (gratis or for a + charge), and offer equivalent access to the Corresponding Source in the same way through + the same place at no further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to copy the object code is a + network server, the Corresponding Source may be on a different server (operated by you or + a third party) that supports equivalent copying facilities, provided you maintain clear + directions next to the object code saying where to find the Corresponding Source. + Regardless of what server hosts the Corresponding Source, you remain obligated to ensure + that it is available for as long as needed to satisfy these requirements. +
    • + +
    • + e) Convey the object code using peer-to-peer transmission, provided you inform other peers + where the object code and Corresponding Source of the work are being offered to the + general public at no charge under subsection 6d. +
    • +
    + +

    + A separable portion of the object code, whose source code is excluded from the Corresponding + Source as a System Library, need not be included in conveying the object code work. +

    + +

    + A "User Product" is either (1) a "consumer product", which means any + tangible personal property which is normally used for personal, family, or household + purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining + whether a product is a consumer product, doubtful cases shall be resolved in favor of + coverage. For a particular product received by a particular user, "normally used" + refers to a typical or common use of that class of product, regardless of the status of the + particular user or of the way in which the particular user actually uses, or expects or is + expected to use, the product. A product is a consumer product regardless of whether the + product has substantial commercial, industrial or non-consumer uses, unless such uses + represent the only significant mode of use of the product. +

    + +

    + "Installation Information" for a User Product means any methods, procedures, + authorization keys, or other information required to install and execute modified versions + of a covered work in that User Product from a modified version of its Corresponding Source. + The information must suffice to ensure that the continued functioning of the modified object + code is in no case prevented or interfered with solely because modification has been made. +

    + +

    + If you convey an object code work under this section in, or with, or specifically for use + in, a User Product, and the conveying occurs as part of a transaction in which the right of + possession and use of the User Product is transferred to the recipient in perpetuity or for + a fixed term (regardless of how the transaction is characterized), the Corresponding Source + conveyed under this section must be accompanied by the Installation Information. But this + requirement does not apply if neither you nor any third party retains the ability to install + modified object code on the User Product (for example, the work has been installed in ROM). +

    + +

    + The requirement to provide Installation Information does not include a requirement to + continue to provide support service, warranty, or updates for a work that has been modified + or installed by the recipient, or for the User Product in which it has been modified or + installed. Access to a network may be denied when the modification itself materially and + adversely affects the operation of the network or violates the rules and protocols for + communication across the network. +

    + +

    + Corresponding Source conveyed, and Installation Information provided, in accord with this + section must be in a format that is publicly documented (and with an implementation + available to the public in source code form), and must require no special password or key + for unpacking, reading or copying. +

    + +

    7. Additional Terms.

    + +

    + "Additional permissions" are terms that supplement the terms of this License by + making exceptions from one or more of its conditions. Additional permissions that are + applicable to the entire Program shall be treated as though they were included in this + License, to the extent that they are valid under applicable law. If additional permissions + apply only to part of the Program, that part may be used separately under those permissions, + but the entire Program remains governed by this License without regard to the additional + permissions. +

    + +

    + When you convey a copy of a covered work, you may at your option remove any additional + permissions from that copy, or from any part of it. (Additional permissions may be written + to require their own removal in certain cases when you modify the work.) You may place + additional permissions on material, added by you to a covered work, for which you have or + can give appropriate copyright permission. +

    + +

    + Notwithstanding any other provision of this License, for material you add to a covered work, + you may (if authorized by the copyright holders of that material) supplement the terms of + this License with terms: +

    + +
      +
    • + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 + and 16 of this License; or +
    • + +
    • + b) Requiring preservation of specified reasonable legal notices or author attributions in + that material or in the Appropriate Legal Notices displayed by works containing it; or +
    • + +
    • + c) Prohibiting misrepresentation of the origin of that material, or requiring that + modified versions of such material be marked in reasonable ways as different from the + original version; or +
    • + +
    • + d) Limiting the use for publicity purposes of names of licensors or authors of the + material; or +
    • + +
    • + e) Declining to grant rights under trademark law for use of some trade names, trademarks, + or service marks; or +
    • + +
    • + f) Requiring indemnification of licensors and authors of that material by anyone who + conveys the material (or modified versions of it) with contractual assumptions of + liability to the recipient, for any liability that these contractual assumptions directly + impose on those licensors and authors. +
    • +
    + +

    + All other non-permissive additional terms are considered "further restrictions" + within the meaning of section 10. If the Program as you received it, or any part of it, + contains a notice stating that it is governed by this License along with a term that is a + further restriction, you may remove that term. If a license document contains a further + restriction but permits relicensing or conveying under this License, you may add to a + covered work material governed by the terms of that license document, provided that the + further restriction does not survive such relicensing or conveying. +

    + +

    + If you add terms to a covered work in accord with this section, you must place, in the + relevant source files, a statement of the additional terms that apply to those files, or a + notice indicating where to find the applicable terms. +

    + +

    + Additional terms, permissive or non-permissive, may be stated in the form of a separately + written license, or stated as exceptions; the above requirements apply either way. +

    + +

    8. Termination.

    + +

    + You may not propagate or modify a covered work except as expressly provided under this + License. Any attempt otherwise to propagate or modify it is void, and will automatically + terminate your rights under this License (including any patent licenses granted under the + third paragraph of section 11). +

    + +

    + However, if you cease all violation of this License, then your license from a particular + copyright holder is reinstated (a) provisionally, unless and until the copyright holder + explicitly and finally terminates your license, and (b) permanently, if the copyright holder + fails to notify you of the violation by some reasonable means prior to 60 days after the + cessation. +

    + +

    + Moreover, your license from a particular copyright holder is reinstated permanently if the + copyright holder notifies you of the violation by some reasonable means, this is the first + time you have received notice of violation of this License (for any work) from that + copyright holder, and you cure the violation prior to 30 days after your receipt of the + notice. +

    + +

    + Termination of your rights under this section does not terminate the licenses of parties who + have received copies or rights from you under this License. If your rights have been + terminated and not permanently reinstated, you do not qualify to receive new licenses for + the same material under section 10. +

    + +

    9. Acceptance Not Required for Having Copies.

    + +

    + You are not required to accept this License in order to receive or run a copy of the + Program. Ancillary propagation of a covered work occurring solely as a consequence of using + peer-to-peer transmission to receive a copy likewise does not require acceptance. However, + nothing other than this License grants you permission to propagate or modify any covered + work. These actions infringe copyright if you do not accept this License. Therefore, by + modifying or propagating a covered work, you indicate your acceptance of this License to do + so. +

    + +

    10. Automatic Licensing of Downstream Recipients.

    + +

    + Each time you convey a covered work, the recipient automatically receives a license from the + original licensors, to run, modify and propagate that work, subject to this License. You are + not responsible for enforcing compliance by third parties with this License. +

    + +

    + An "entity transaction" is a transaction transferring control of an organization, + or substantially all assets of one, or subdividing an organization, or merging + organizations. If propagation of a covered work results from an entity transaction, each + party to that transaction who receives a copy of the work also receives whatever licenses to + the work the party's predecessor in interest had or could give under the previous + paragraph, plus a right to possession of the Corresponding Source of the work from the + predecessor in interest, if the predecessor has it or can get it with reasonable efforts. +

    + +

    + You may not impose any further restrictions on the exercise of the rights granted or + affirmed under this License. For example, you may not impose a license fee, royalty, or + other charge for exercise of rights granted under this License, and you may not initiate + litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent + claim is infringed by making, using, selling, offering for sale, or importing the Program or + any portion of it. +

    + +

    11. Patents.

    + +

    + A "contributor" is a copyright holder who authorizes use under this License of the + Program or a work on which the Program is based. The work thus licensed is called the + contributor's "contributor version". +

    + +

    + A contributor's "essential patent claims" are all patent claims owned or + controlled by the contributor, whether already acquired or hereafter acquired, that would be + infringed by some manner, permitted by this License, of making, using, or selling its + contributor version, but do not include claims that would be infringed only as a consequence + of further modification of the contributor version. For purposes of this definition, + "control" includes the right to grant patent sublicenses in a manner consistent + with the requirements of this License. +

    + +

    + Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under + the contributor's essential patent claims, to make, use, sell, offer for sale, import + and otherwise run, modify and propagate the contents of its contributor version. +

    + +

    + In the following three paragraphs, a "patent license" is any express agreement or + commitment, however denominated, not to enforce a patent (such as an express permission to + practice a patent or covenant not to sue for patent infringement). To "grant" such + a patent license to a party means to make such an agreement or commitment not to enforce a + patent against the party. +

    + +

    + If you convey a covered work, knowingly relying on a patent license, and the Corresponding + Source of the work is not available for anyone to copy, free of charge and under the terms + of this License, through a publicly available network server or other readily accessible + means, then you must either (1) cause the Corresponding Source to be so available, or (2) + arrange to deprive yourself of the benefit of the patent license for this particular work, + or (3) arrange, in a manner consistent with the requirements of this License, to extend the + patent license to downstream recipients. "Knowingly relying" means you have actual + knowledge that, but for the patent license, your conveying the covered work in a country, or + your recipient's use of the covered work in a country, would infringe one or more + identifiable patents in that country that you have reason to believe are valid. +

    + +

    + If, pursuant to or in connection with a single transaction or arrangement, you convey, or + propagate by procuring conveyance of, a covered work, and grant a patent license to some of + the parties receiving the covered work authorizing them to use, propagate, modify or convey + a specific copy of the covered work, then the patent license you grant is automatically + extended to all recipients of the covered work and works based on it. +

    + +

    + A patent license is "discriminatory" if it does not include within the scope of + its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or + more of the rights that are specifically granted under this License. You may not convey a + covered work if you are a party to an arrangement with a third party that is in the business + of distributing software, under which you make payment to the third party based on the + extent of your activity of conveying the work, and under which the third party grants, to + any of the parties who would receive the covered work from you, a discriminatory patent + license (a) in connection with copies of the covered work conveyed by you (or copies made + from those copies), or (b) primarily for and in connection with specific products or + compilations that contain the covered work, unless you entered into that arrangement, or + that patent license was granted, prior to 28 March 2007. +

    + +

    + Nothing in this License shall be construed as excluding or limiting any implied license or + other defenses to infringement that may otherwise be available to you under applicable + patent law. +

    + +

    12. No Surrender of Others' Freedom.

    + +

    + If conditions are imposed on you (whether by court order, agreement or otherwise) that + contradict the conditions of this License, they do not excuse you from the conditions of + this License. If you cannot convey a covered work so as to satisfy simultaneously your + obligations under this License and any other pertinent obligations, then as a consequence + you may not convey it at all. For example, if you agree to terms that obligate you to + collect a royalty for further conveying from those to whom you convey the Program, the only + way you could satisfy both those terms and this License would be to refrain entirely from + conveying the Program. +

    + +

    + 13. Remote Network Interaction; Use with the GNU General Public License. +

    + +

    + Notwithstanding any other provision of this License, if you modify the Program, your + modified version must prominently offer all users interacting with it remotely through a + computer network (if your version supports such interaction) an opportunity to receive the + Corresponding Source of your version by providing access to the Corresponding Source from a + network server at no charge, through some standard or customary means of facilitating + copying of software. This Corresponding Source shall include the Corresponding Source for + any work covered by version 3 of the GNU General Public License that is incorporated + pursuant to the following paragraph. +

    + +

    + Notwithstanding any other provision of this License, you have permission to link or combine + any covered work with a work licensed under version 3 of the GNU General Public License into + a single combined work, and to convey the resulting work. The terms of this License will + continue to apply to the part which is the covered work, but the work with which it is + combined will remain governed by version 3 of the GNU General Public License. +

    + +

    14. Revised Versions of this License.

    + +

    + The Free Software Foundation may publish revised and/or new versions of the GNU Affero + General Public License from time to time. Such new versions will be similar in spirit to the + present version, but may differ in detail to address new problems or concerns. +

    + +

    + Each version is given a distinguishing version number. If the Program specifies that a + certain numbered version of the GNU Affero General Public License "or any later + version" applies to it, you have the option of following the terms and conditions + either of that numbered version or of any later version published by the Free Software + Foundation. If the Program does not specify a version number of the GNU Affero General + Public License, you may choose any version ever published by the Free Software Foundation. +

    + +

    + If the Program specifies that a proxy can decide which future versions of the GNU Affero + General Public License can be used, that proxy's public statement of acceptance of a + version permanently authorizes you to choose that version for the Program. +

    + +

    + Later license versions may give you additional or different permissions. However, no + additional obligations are imposed on any author or copyright holder as a result of your + choosing to follow a later version. +

    + +

    15. Disclaimer of Warranty.

    + +

    + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM + "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. + SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR + OR CORRECTION. +

    + +

    16. Limitation of Liability.

    + +

    + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT + HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL + DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO + LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES + OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR + OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +

    + +

    17. Interpretation of Sections 15 and 16.

    + +

    + If the disclaimer of warranty and limitation of liability provided above cannot be given + local legal effect according to their terms, reviewing courts shall apply local law that + most closely approximates an absolute waiver of all civil liability in connection with the + Program, unless a warranty or assumption of liability accompanies a copy of the Program in + return for a fee. +

    +
    + ); +}; + +Page.getLayout = (page) => {page}; + +export default Page; From bd034d567a5db745ed3a22b7a1c5afd042bd0cca Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 4 Mar 2025 12:24:41 -0500 Subject: [PATCH 86/90] Update _app.js --- src/pages/_app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/_app.js b/src/pages/_app.js index ba282a7fb405..0b1831c98f73 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -31,7 +31,6 @@ import { SvgIcon } from "@mui/material"; import discordIcon from "../../public/discord-mark-blue.svg"; import React from "react"; import { usePathname } from "next/navigation"; -import { icon } from "leaflet"; import { useRouter } from "next/router"; TimeAgo.addDefaultLocale(en); From 172bdb41b6e940c61f4bd67c37c6c23f649fa59c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 4 Mar 2025 18:37:58 +0100 Subject: [PATCH 87/90] fixes edit user bugs --- src/components/CippFormPages/CippAddEditUser.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/CippFormPages/CippAddEditUser.jsx b/src/components/CippFormPages/CippAddEditUser.jsx index 0a4d57feba1d..5087d40456fa 100644 --- a/src/components/CippFormPages/CippAddEditUser.jsx +++ b/src/components/CippFormPages/CippAddEditUser.jsx @@ -64,7 +64,7 @@ const CippAddEditUser = (props) => { InputProps={{ endAdornment: @, }} - name="mailNickname" + name="username" formControl={formControl} />
    @@ -291,7 +291,7 @@ const CippAddEditUser = (props) => { multiple={false} />
    - {userSettingsDefaults?.userAttributes?.some(attribute => attribute.value === "sponsor") && ( + {userSettingsDefaults?.userAttributes?.some((attribute) => attribute.value === "sponsor") && ( Date: Tue, 4 Mar 2025 12:39:28 -0500 Subject: [PATCH 88/90] fix: bookmarking with long titles --- src/layouts/side-nav-item.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/layouts/side-nav-item.js b/src/layouts/side-nav-item.js index 05bc97972da2..a3f5e73b79eb 100644 --- a/src/layouts/side-nav-item.js +++ b/src/layouts/side-nav-item.js @@ -150,6 +150,9 @@ export const SideNavItem = (props) => { sx={{ display: "flex", alignItems: "center", + width: "100%", + px: `${indent * 6}px`, + py: "12px", }} > { fontSize: fontSize, fontWeight: 500, justifyContent: "flex-start", - px: `${indent * 6}px`, - py: "12px", textAlign: "left", whiteSpace: "nowrap", - width: "100%", + width: "calc(100% - 20px)", // Adjust the width to leave space for the bookmark icon }} {...linkProps} > @@ -191,6 +192,12 @@ export const SideNavItem = (props) => { flexGrow: 1, mx: "12px", transition: "opacity 250ms ease-in-out", + whiteSpace: "nowrap", + ...(hovered && { + maxWidth: "calc(100% - 45px)", // Adjust the width to leave space for the bookmark icon + overflow: "hidden", + textOverflow: "ellipsis", + }), ...(active && { color: "primary.main", }), @@ -223,7 +230,7 @@ export const SideNavItem = (props) => { fontSize: 16, transition: "opacity 250ms ease-in-out", cursor: "pointer", - mx: 1, + mr: 1, display: hovered ? "block" : "none", }} > From dab5f7f48c55527af1a3f0dca6f26a07d49d7bd5 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 4 Mar 2025 18:51:33 +0100 Subject: [PATCH 89/90] up version --- public/version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/version.json b/public/version.json index 542517aee22f..712c1fd057e1 100644 --- a/public/version.json +++ b/public/version.json @@ -1,3 +1,3 @@ { - "version": "7.2.3" + "version": "7.3.0" } From 6a349d74ca4d01a0cb9b0ba67d50a3d020eb732f Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 4 Mar 2025 12:51:53 -0500 Subject: [PATCH 90/90] update confirm text --- src/components/CippSettings/CippCacheSettings.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CippSettings/CippCacheSettings.jsx b/src/components/CippSettings/CippCacheSettings.jsx index a427ddd3acfe..ad736adf604f 100644 --- a/src/components/CippSettings/CippCacheSettings.jsx +++ b/src/components/CippSettings/CippCacheSettings.jsx @@ -68,7 +68,7 @@ const CippCacheSettings = () => { api={{ url: "/api/ListTenants", confirmText: - "This will clear the cache used by CIPP. This will slow down some aspects of the application, and should only be used when instructed to do so by support.", + "This will clear the cache used by CIPP. This will slow down some aspects of the application, and should only be used when instructed to do so by support. This will delete any cache tables including pending audit logs that have not yet been processed. Are you sure you want to continue?", type: "POST", data: { ClearCache: true }, replacementBehaviour: "removeNulls",