From a7d4745f93a0c0326f4554b5d902a25fb261dca4 Mon Sep 17 00:00:00 2001 From: Jan Kahmen <36455663+kah-ja@users.noreply.github.com> Date: Tue, 15 Sep 2026 09:57:22 +0000 Subject: [PATCH 1/3] Only accept http(s) targets for the resource auth redirect The resource auth page copies the redirect query parameter into redirectUrl when its host matches the resource host (src/app/auth/resource/[resourceGuid]/page.tsx:121-150). URL parses a host out of every scheme that uses "//", so a target such as javascript://resource-host/... passes that comparison. The value is handed to ResourceAuthPortal as the redirect prop and assigned to window.location.href after a successful login (src/components/ResourceAuthPortal.tsx:213,247,281). Parse the target once and require http: or https: before the host comparisons. The three branches that assigned the same value are folded into one condition; the accepted set of http(s) targets is unchanged. --- src/app/auth/resource/[resourceGuid]/page.tsx | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/app/auth/resource/[resourceGuid]/page.tsx b/src/app/auth/resource/[resourceGuid]/page.tsx index 318d63517..53217dcfd 100644 --- a/src/app/auth/resource/[resourceGuid]/page.tsx +++ b/src/app/auth/resource/[resourceGuid]/page.tsx @@ -122,11 +122,20 @@ export default async function ResourceAuthPage(props: { if (searchParams.redirect) { try { + const redirectTarget = new URL(searchParams.redirect); const serverResourceHost = new URL(authInfo.url).host; - const redirectHost = new URL(searchParams.redirect).host; - const redirectPort = new URL(searchParams.redirect).port; + const redirectHost = redirectTarget.host; + const redirectPort = redirectTarget.port; const serverResourceHostWithPort = `${serverResourceHost}:${redirectPort}`; + // URL parses a host out of any scheme that uses "//", so a target + // like javascript://resource-host/... matches the comparisons + // below. The target is later assigned to window.location, so only + // http(s) is accepted here. + const isHttpTarget = + redirectTarget.protocol === "http:" || + redirectTarget.protocol === "https:"; + const wildcardMatchesRedirect = ( wildcardDomain: string, host: string @@ -136,14 +145,16 @@ export default async function ResourceAuthPage(props: { return host.endsWith(suffix) && host.length > suffix.length; }; - if (serverResourceHost === redirectHost) { - redirectUrl = searchParams.redirect; - } else if (serverResourceHostWithPort === redirectHost) { - redirectUrl = searchParams.redirect; - } else if ( - authInfo.wildcard && - authInfo.fullDomain && - wildcardMatchesRedirect(authInfo.fullDomain, redirectHost) + if ( + isHttpTarget && + (serverResourceHost === redirectHost || + serverResourceHostWithPort === redirectHost || + (authInfo.wildcard && + authInfo.fullDomain && + wildcardMatchesRedirect( + authInfo.fullDomain, + redirectHost + ))) ) { redirectUrl = searchParams.redirect; } From 032eeb26565be87f057b40db01198d7cab5a18f2 Mon Sep 17 00:00:00 2001 From: Alex Benthem Date: Sat, 19 Sep 2026 12:28:16 +0200 Subject: [PATCH 2/3] fix: use idp variant for resource auth login page icons The resource auth login page (auth/resource/[resourceGuid]) loads IdPs via the global /idp list in the non-saas/non-org path and passed idp.type as the icon variant. Since type is always 'oidc' for OIDC-backed providers (Google, Azure), the branded logos were never selected, showing the generic OIDC icon instead. Use idp.variant (with type as fallback), matching the fix already applied to the main login page (auth/login) and org login page (auth/org/[orgId]). Fixes #3631 --- src/app/auth/resource/[resourceGuid]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/auth/resource/[resourceGuid]/page.tsx b/src/app/auth/resource/[resourceGuid]/page.tsx index 318d63517..4d6f101de 100644 --- a/src/app/auth/resource/[resourceGuid]/page.tsx +++ b/src/app/auth/resource/[resourceGuid]/page.tsx @@ -283,7 +283,7 @@ export default async function ResourceAuthPage(props: { loginIdps = idpsRes.data.data.idps.map((idp) => ({ idpId: idp.idpId, name: idp.name, - variant: idp.type + variant: idp.variant ?? idp.type })) as LoginFormIDP[]; } From d4488ec12510f27ec02395d03fa45e85b6c46092 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Mon, 21 Sep 2026 09:57:03 -0400 Subject: [PATCH 3/3] update ios identifiers --- server/db/ios_models.json | 125 +++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/server/db/ios_models.json b/server/db/ios_models.json index 99fcbea17..43dfe5687 100644 --- a/server/db/ios_models.json +++ b/server/db/ios_models.json @@ -4,42 +4,18 @@ "iPad2,2": "iPad 2", "iPad2,3": "iPad 2", "iPad2,4": "iPad 2", - "iPad3,1": "iPad 3rd Gen", - "iPad3,3": "iPad 3rd Gen", - "iPad3,2": "iPad 3rd Gen", - "iPad3,4": "iPad 4th Gen", - "iPad3,5": "iPad 4th Gen", - "iPad3,6": "iPad 4th Gen", - "iPad6,11": "iPad 9.7 5th Gen", - "iPad6,12": "iPad 9.7 5th Gen", - "iPad7,5": "iPad 9.7 6th Gen", - "iPad7,6": "iPad 9.7 6th Gen", - "iPad7,11": "iPad 10.2 7th Gen", - "iPad7,12": "iPad 10.2 7th Gen", - "iPad11,6": "iPad 10.2 8th Gen", - "iPad11,7": "iPad 10.2 8th Gen", - "iPad12,1": "iPad 10.2 9th Gen", - "iPad12,2": "iPad 10.2 9th Gen", - "iPad13,18": "iPad 10.9 10th Gen", - "iPad13,19": "iPad 10.9 10th Gen", - "iPad4,1": "iPad Air", - "iPad4,2": "iPad Air", - "iPad4,3": "iPad Air", - "iPad5,3": "iPad Air 2", - "iPad5,4": "iPad Air 2", - "iPad11,3": "iPad Air 3rd Gen", - "iPad11,4": "iPad Air 3rd Gen", - "iPad13,1": "iPad Air 4th Gen", - "iPad13,2": "iPad Air 4th Gen", - "iPad13,16": "iPad Air 5th Gen", - "iPad13,17": "iPad Air 5th Gen", - "iPad14,8": "iPad Air M2 11", - "iPad14,9": "iPad Air M2 11", - "iPad14,10": "iPad Air M2 13", - "iPad14,11": "iPad Air M2 13", "iPad2,5": "iPad mini", "iPad2,6": "iPad mini", "iPad2,7": "iPad mini", + "iPad3,1": "iPad 3rd Gen", + "iPad3,2": "iPad 3rd Gen", + "iPad3,3": "iPad 3rd Gen", + "iPad3,4": "iPad 4th Gen", + "iPad3,5": "iPad 4th Gen", + "iPad3,6": "iPad 4th Gen", + "iPad4,1": "iPad Air", + "iPad4,2": "iPad Air", + "iPad4,3": "iPad Air", "iPad4,4": "iPad mini 2", "iPad4,5": "iPad mini 2", "iPad4,6": "iPad mini 2", @@ -48,18 +24,22 @@ "iPad4,9": "iPad mini 3", "iPad5,1": "iPad mini 4", "iPad5,2": "iPad mini 4", - "iPad11,1": "iPad mini 5th Gen", - "iPad11,2": "iPad mini 5th Gen", - "iPad14,1": "iPad mini 6th Gen", - "iPad14,2": "iPad mini 6th Gen", - "iPad6,7": "iPad Pro 12.9", - "iPad6,8": "iPad Pro 12.9", + "iPad5,3": "iPad Air 2", + "iPad5,4": "iPad Air 2", "iPad6,3": "iPad Pro 9.7", "iPad6,4": "iPad Pro 9.7", - "iPad7,3": "iPad Pro 10.5", - "iPad7,4": "iPad Pro 10.5", + "iPad6,7": "iPad Pro 12.9", + "iPad6,8": "iPad Pro 12.9", + "iPad6,11": "iPad 9.7 5th Gen", + "iPad6,12": "iPad 9.7 5th Gen", "iPad7,1": "iPad Pro 12.9", "iPad7,2": "iPad Pro 12.9", + "iPad7,3": "iPad Pro 10.5", + "iPad7,4": "iPad Pro 10.5", + "iPad7,5": "iPad 9.7 6th Gen", + "iPad7,6": "iPad 9.7 6th Gen", + "iPad7,11": "iPad 10.2 7th Gen", + "iPad7,12": "iPad 10.2 7th Gen", "iPad8,1": "iPad Pro 11", "iPad8,2": "iPad Pro 11", "iPad8,3": "iPad Pro 11", @@ -72,6 +52,16 @@ "iPad8,10": "iPad Pro 11", "iPad8,11": "iPad Pro 12.9", "iPad8,12": "iPad Pro 12.9", + "iPad11,1": "iPad mini 5th Gen", + "iPad11,2": "iPad mini 5th Gen", + "iPad11,3": "iPad Air 3rd Gen", + "iPad11,4": "iPad Air 3rd Gen", + "iPad11,6": "iPad 10.2 8th Gen", + "iPad11,7": "iPad 10.2 8th Gen", + "iPad12,1": "iPad 10.2 9th Gen", + "iPad12,2": "iPad 10.2 9th Gen", + "iPad13,1": "iPad Air 4th Gen", + "iPad13,2": "iPad Air 4th Gen", "iPad13,4": "iPad Pro 11", "iPad13,5": "iPad Pro 11", "iPad13,6": "iPad Pro 11", @@ -80,14 +70,40 @@ "iPad13,9": "iPad Pro 12.9", "iPad13,10": "iPad Pro 12.9", "iPad13,11": "iPad Pro 12.9", + "iPad13,16": "iPad Air M1 5th Gen", + "iPad13,17": "iPad Air M1 5th Gen", + "iPad13,18": "iPad 10.9 10th Gen", + "iPad13,19": "iPad 10.9 10th Gen", + "iPad14,1": "iPad mini 6th Gen", + "iPad14,2": "iPad mini 6th Gen", "iPad14,3": "iPad Pro 11", "iPad14,4": "iPad Pro 11", "iPad14,5": "iPad Pro 12.9", "iPad14,6": "iPad Pro 12.9", + "iPad14,8": "iPad Air M2 11", + "iPad14,9": "iPad Air M2 11", + "iPad14,10": "iPad Air M2 13", + "iPad14,11": "iPad Air M2 13", + "iPad15,3": "iPad Air M3 11", + "iPad15,4": "iPad Air M3 11", + "iPad15,5": "iPad Air M3 13", + "iPad15,6": "iPad Air M3 13", + "iPad15,7": "iPad A16 - 11th Gen", + "iPad15,8": "iPad A16 - 11th Gen", + "iPad16,1": "iPad mini A17 Pro - 7th Gen", + "iPad16,2": "iPad mini A17 Pro - 7th Gen", "iPad16,3": "iPad Pro M4 11", "iPad16,4": "iPad Pro M4 11", "iPad16,5": "iPad Pro M4 13", "iPad16,6": "iPad Pro M4 13", + "iPad16,8": "iPad Air M4 11", + "iPad16,9": "iPad Air M4 11", + "iPad16,10": "iPad Air M4 13", + "iPad16,11": "iPad Air M4 13", + "iPad17,1": "iPad Pro M5 11", + "iPad17,2": "iPad Pro M5 11", + "iPad17,3": "iPad Pro M5 13", + "iPad17,4": "iPad Pro M5 13", "iPhone1,1": "iPhone", "iPhone1,2": "iPhone 3G", "iPhone2,1": "iPhone 3GS", @@ -101,20 +117,20 @@ "iPhone5,4": "iPhone 5c", "iPhone6,1": "iPhone 5s", "iPhone6,2": "iPhone 5s", - "iPhone7,2": "iPhone 6", "iPhone7,1": "iPhone 6 Plus", + "iPhone7,2": "iPhone 6", "iPhone8,1": "iPhone 6s", "iPhone8,2": "iPhone 6s Plus", "iPhone8,4": "iPhone SE", "iPhone9,1": "iPhone 7", - "iPhone9,3": "iPhone 7", "iPhone9,2": "iPhone 7 Plus", + "iPhone9,3": "iPhone 7", "iPhone9,4": "iPhone 7 Plus", "iPhone10,1": "iPhone 8", - "iPhone10,4": "iPhone 8", "iPhone10,2": "iPhone 8 Plus", - "iPhone10,5": "iPhone 8 Plus", "iPhone10,3": "iPhone X", + "iPhone10,4": "iPhone 8", + "iPhone10,5": "iPhone 8 Plus", "iPhone10,6": "iPhone X", "iPhone11,2": "iPhone Xs", "iPhone11,6": "iPhone Xs Max", @@ -127,10 +143,10 @@ "iPhone13,2": "iPhone 12", "iPhone13,3": "iPhone 12 Pro", "iPhone13,4": "iPhone 12 Pro Max", - "iPhone14,4": "iPhone 13 mini", - "iPhone14,5": "iPhone 13", "iPhone14,2": "iPhone 13 Pro", "iPhone14,3": "iPhone 13 Pro Max", + "iPhone14,4": "iPhone 13 mini", + "iPhone14,5": "iPhone 13", "iPhone14,6": "iPhone SE", "iPhone14,7": "iPhone 14", "iPhone14,8": "iPhone 14 Plus", @@ -140,6 +156,19 @@ "iPhone15,5": "iPhone 15 Plus", "iPhone16,1": "iPhone 15 Pro", "iPhone16,2": "iPhone 15 Pro Max", + "iPhone17,1": "iPhone 16 Pro", + "iPhone17,2": "iPhone 16 Pro Max", + "iPhone17,3": "iPhone 16", + "iPhone17,4": "iPhone 16 Plus", + "iPhone17,5": "iPhone 16e", + "iPhone18,1": "iPhone 17 Pro", + "iPhone18,2": "iPhone 17 Pro Max", + "iPhone18,3": "iPhone 17", + "iPhone18,4": "iPhone Air", + "iPhone18,5": "iPhone 17e", + "iPhone19,2": "iPhone 18 Pro", + "iPhone19,3": "iPhone 18 Pro Max", + "iPhone19,7": "iPhone 18 Pro Max", "iPod1,1": "iPod touch Original", "iPod2,1": "iPod touch 2nd", "iPod3,1": "iPod touch 3rd Gen", @@ -147,4 +176,4 @@ "iPod5,1": "iPod touch 5th", "iPod7,1": "iPod touch 6th Gen", "iPod9,1": "iPod touch 7th Gen" -} \ No newline at end of file +}