From 28f58ed465d0284d5b3d82ffec8cea8a7238df40 Mon Sep 17 00:00:00 2001
From: Carlo <1778532+cdcme@users.noreply.github.com>
Date: Fri, 14 Nov 2025 15:54:30 -0500
Subject: [PATCH] Fix iOS/iPadOS self-service UI routing and database errors
(#35739)
Fixes #35722
---
.../DeviceUserError/DeviceUserError.tsx | 4 ++++
.../layouts/UnsupportedScreenSize/helpers.ts | 8 ++++++-
.../details/DeviceUserPage/DeviceUserPage.tsx | 21 ++++++++++++++++---
server/datastore/mysql/software.go | 5 +++--
4 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/frontend/components/DeviceUserError/DeviceUserError.tsx b/frontend/components/DeviceUserError/DeviceUserError.tsx
index 2c86bfba6e..7625128196 100644
--- a/frontend/components/DeviceUserError/DeviceUserError.tsx
+++ b/frontend/components/DeviceUserError/DeviceUserError.tsx
@@ -10,17 +10,21 @@ interface IDeviceUserErrorProps {
/** Modifies error message for iPhone/iPad/Android */
isMobileDevice?: boolean;
isAuthenticationError?: boolean;
+ platform?: string;
}
const DeviceUserError = ({
isMobileView = false,
isMobileDevice = false,
isAuthenticationError = false,
+ platform,
}: IDeviceUserErrorProps): JSX.Element => {
const wrapperClassnames = classNames(baseClass, {
[`${baseClass}__mobile-view`]: isMobileView,
});
+ const isIOSIPadOS = platform === "ios" || platform === "ipados";
+
// Default: "Something went wrong"
let headerContent: React.ReactNode = (
<>
diff --git a/frontend/layouts/UnsupportedScreenSize/helpers.ts b/frontend/layouts/UnsupportedScreenSize/helpers.ts
index 58c6f717e5..29e78048aa 100644
--- a/frontend/layouts/UnsupportedScreenSize/helpers.ts
+++ b/frontend/layouts/UnsupportedScreenSize/helpers.ts
@@ -4,8 +4,14 @@ const deviceSelfServiceRegex = new RegExp(
`^${url_prefix}/device/[^/]+/self-service/?$`
);
+// iOS/iPadOS base device route should support low-width screens
+const deviceIOSIPadOSRegex = new RegExp(`^${url_prefix}/device/[^/]+/?$`);
+
// Define paths that will not show the unsupported screen overlay
-const lowWidthSupportedPathsRegex = [deviceSelfServiceRegex];
+const lowWidthSupportedPathsRegex = [
+ deviceSelfServiceRegex,
+ deviceIOSIPadOSRegex,
+];
const shouldShowUnsupportedScreen = (locationPathname: string) =>
!lowWidthSupportedPathsRegex.some((regex) => regex.test(locationPathname));
diff --git a/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx b/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx
index 200a688b5e..f5fe4612ca 100644
--- a/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx
+++ b/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx
@@ -343,6 +343,7 @@ const DeviceUserPage = ({
} = dupResponse || {};
const isPremiumTier = license?.tier === "premium";
const isAppleHost = isAppleDevice(host?.platform);
+ const isIOSIPadOS = host?.platform === "ios" || host?.platform === "ipados";
const isSetupExperienceSoftwareEnabledPlatform =
isLinuxLike(host?.platform || "") ||
host?.platform === "windows" ||
@@ -595,9 +596,22 @@ const DeviceUserPage = ({
);
}
- if (isMobileView) {
+ // iOS/iPadOS devices or narrow screens should show mobile UI
+ const shouldShowMobileUI = isIOSIPadOS || isMobileView;
+
+ if (shouldShowMobileUI) {
+ // Force redirect to self-service route for iOS/iPadOS devices
+ if (
+ isIOSIPadOS &&
+ !location.pathname.includes("/self-service") &&
+ hasSelfService
+ ) {
+ router.replace(PATHS.DEVICE_USER_DETAILS_SELF_SERVICE(deviceAuthToken));
+ return