From 63b2e196306d4734ef8464c1a9f1e2ba3f71b06f Mon Sep 17 00:00:00 2001 From: Gabriel Hernandez Date: Thu, 15 May 2025 12:38:07 +0100 Subject: [PATCH] allow turning off mdm for iphone and ipad hosts (#29087) For [#23784](https://github.com/fleetdm/fleet/issues/23784) This adds the "turn off mdm" option don't he host details page for iPhone and iPad devices. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [ ] Added/updated automated tests - [ ] Manual QA for all new/changed functionality --- changes/issue-23784-turn-off-mdm-iphone-ipad | 1 + .../HostActionsDropdown.tests.tsx | 2 - .../HostActionsDropdown/helpers.tsx | 10 ++-- .../HostDetailsPage/HostDetailsPage.tsx | 7 ++- .../UnenrollMdmModal/UnenrollMdmModal.tsx | 49 +++++++++++++++---- server/fleet/errors.go | 1 - server/service/apple_mdm.go | 6 --- server/service/integration_mdm_test.go | 14 +----- 8 files changed, 53 insertions(+), 37 deletions(-) create mode 100644 changes/issue-23784-turn-off-mdm-iphone-ipad diff --git a/changes/issue-23784-turn-off-mdm-iphone-ipad b/changes/issue-23784-turn-off-mdm-iphone-ipad new file mode 100644 index 0000000000..c83654873f --- /dev/null +++ b/changes/issue-23784-turn-off-mdm-iphone-ipad @@ -0,0 +1 @@ +- add ability to turn off mdm for iphone and ipad hosts on the hosts details page diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx index 02e1a986ff..9f51a9f3ea 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx @@ -1230,7 +1230,6 @@ describe("Host Actions Dropdown", () => { expect( screen.queryByText("Show disk encryption key") ).not.toBeInTheDocument(); - expect(screen.queryByText("Turn off MDM")).not.toBeInTheDocument(); expect(screen.queryByText("Lock")).not.toBeInTheDocument(); }); @@ -1270,7 +1269,6 @@ describe("Host Actions Dropdown", () => { expect( screen.queryByText("Show disk encryption key") ).not.toBeInTheDocument(); - expect(screen.queryByText("Turn off MDM")).not.toBeInTheDocument(); expect(screen.queryByText("Lock")).not.toBeInTheDocument(); }); }); diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx index bbd2a4a60e..e632d02798 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx @@ -7,6 +7,7 @@ import { isAppleDevice, isMobilePlatform, isAndroid, + isIPadOrIPhone, } from "interfaces/platform"; import { isScriptSupportedPlatform } from "interfaces/script"; @@ -89,7 +90,7 @@ const canTransferTeam = (config: IHostActionConfigOptions) => { return isPremiumTier && (isGlobalAdmin || isGlobalMaintainer); }; -const canEditMdm = (config: IHostActionConfigOptions) => { +const canTurnOffMdm = (config: IHostActionConfigOptions) => { const { hostPlatform, isGlobalAdmin, @@ -102,7 +103,7 @@ const canEditMdm = (config: IHostActionConfigOptions) => { } = config; return ( !isAndroid(hostPlatform) && // TODO(android): confirm can't turn off MDM for windows, iOS, iPadOS? - hostPlatform === "darwin" && + isAppleDevice(hostPlatform) && isMacMdmEnabledAndConfigured && isEnrolledInMdm && isConnectedToFleetMdm && @@ -257,7 +258,7 @@ const removeUnavailableOptions = ( options = options.filter((option) => option.value !== "diskEncryption"); } - if (!canEditMdm(config)) { + if (!canTurnOffMdm(config)) { options = options.filter((option) => option.value !== "mdmOff"); } @@ -339,7 +340,7 @@ const modifyOptions = ( let optionsToDisable: IDropdownOption[] = []; if ( - !isHostOnline || + (!isIPadOrIPhone(hostPlatform) && !isHostOnline) || isDeviceStatusUpdating(hostMdmDeviceStatus) || hostMdmDeviceStatus === "locked" || hostMdmDeviceStatus === "wiped" @@ -386,7 +387,6 @@ const modifyOptions = ( * many variations of the options that are shown/not shown or disabled/enabled * which are all controlled by the configurations options argument. */ -// eslint-disable-next-line import/prefer-default-export export const generateHostActionOptions = (config: IHostActionConfigOptions) => { // deep clone to always start with a fresh copy of the default options. let options: IDropdownOption[] = cloneDeep([...DEFAULT_OPTIONS]); diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx index a32ebe051f..db40da4758 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx @@ -1160,7 +1160,12 @@ const HostDetailsPage = ({ /> )} {showUnenrollMdmModal && !!host && ( - + )} {showDiskEncryptionModal && host && ( void; } const baseClass = "unenroll-mdm-modal"; -const UnenrollMdmModal = ({ hostId, onClose }: IUnenrollMdmModalProps) => { +const UnenrollMdmModal = ({ + hostId, + hostPlatform, + hostName, + onClose, +}: IUnenrollMdmModalProps) => { const [requestState, setRequestState] = useState< undefined | "unenrolling" | "error" >(undefined); @@ -27,28 +36,50 @@ const UnenrollMdmModal = ({ hostId, onClose }: IUnenrollMdmModalProps) => { await mdmAPI.unenrollHostFromMdm(hostId, 5000); renderFlash( "success", - "Turning off MDM or will turn off when the host comes online." + <> + MDM will be turned off for {hostName} next time this host + checks in. + ); - onClose(); } catch (unenrollMdmError: unknown) { - renderFlash("error", "Couldn't turn off MDM. Please try again."); - console.log(unenrollMdmError); - onClose(); + renderFlash( + "error", + <> + Failed to turn off MDM for {hostName}. + + ); } + onClose(); }; const renderModalContent = () => { if (requestState === "error") { return ; } + + const turnOnMDMInstructions = isIPadOrIPhone(hostPlatform) ? ( + <> + invite the end user to{" "} + + + ) : ( + <> + ask the device user to follow the Turn on MDM instructions on + their My device page. + + ); + return ( <>

Settings configured by Fleet will be removed.

- To turn on MDM again, ask the device user to follow the{" "} - Turn on MDM instructions on their My device page. + To turn on MDM again, {turnOnMDMInstructions}