Merge branch 'dev' of github.com:fosrl/pangolin into dev

This commit is contained in:
Owen
2026-09-21 10:48:32 -04:00
2 changed files with 99 additions and 59 deletions
+76 -47
View File
@@ -4,42 +4,18 @@
"iPad2,2": "iPad 2", "iPad2,2": "iPad 2",
"iPad2,3": "iPad 2", "iPad2,3": "iPad 2",
"iPad2,4": "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,5": "iPad mini",
"iPad2,6": "iPad mini", "iPad2,6": "iPad mini",
"iPad2,7": "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,4": "iPad mini 2",
"iPad4,5": "iPad mini 2", "iPad4,5": "iPad mini 2",
"iPad4,6": "iPad mini 2", "iPad4,6": "iPad mini 2",
@@ -48,18 +24,22 @@
"iPad4,9": "iPad mini 3", "iPad4,9": "iPad mini 3",
"iPad5,1": "iPad mini 4", "iPad5,1": "iPad mini 4",
"iPad5,2": "iPad mini 4", "iPad5,2": "iPad mini 4",
"iPad11,1": "iPad mini 5th Gen", "iPad5,3": "iPad Air 2",
"iPad11,2": "iPad mini 5th Gen", "iPad5,4": "iPad Air 2",
"iPad14,1": "iPad mini 6th Gen",
"iPad14,2": "iPad mini 6th Gen",
"iPad6,7": "iPad Pro 12.9",
"iPad6,8": "iPad Pro 12.9",
"iPad6,3": "iPad Pro 9.7", "iPad6,3": "iPad Pro 9.7",
"iPad6,4": "iPad Pro 9.7", "iPad6,4": "iPad Pro 9.7",
"iPad7,3": "iPad Pro 10.5", "iPad6,7": "iPad Pro 12.9",
"iPad7,4": "iPad Pro 10.5", "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,1": "iPad Pro 12.9",
"iPad7,2": "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,1": "iPad Pro 11",
"iPad8,2": "iPad Pro 11", "iPad8,2": "iPad Pro 11",
"iPad8,3": "iPad Pro 11", "iPad8,3": "iPad Pro 11",
@@ -72,6 +52,16 @@
"iPad8,10": "iPad Pro 11", "iPad8,10": "iPad Pro 11",
"iPad8,11": "iPad Pro 12.9", "iPad8,11": "iPad Pro 12.9",
"iPad8,12": "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,4": "iPad Pro 11",
"iPad13,5": "iPad Pro 11", "iPad13,5": "iPad Pro 11",
"iPad13,6": "iPad Pro 11", "iPad13,6": "iPad Pro 11",
@@ -80,14 +70,40 @@
"iPad13,9": "iPad Pro 12.9", "iPad13,9": "iPad Pro 12.9",
"iPad13,10": "iPad Pro 12.9", "iPad13,10": "iPad Pro 12.9",
"iPad13,11": "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,3": "iPad Pro 11",
"iPad14,4": "iPad Pro 11", "iPad14,4": "iPad Pro 11",
"iPad14,5": "iPad Pro 12.9", "iPad14,5": "iPad Pro 12.9",
"iPad14,6": "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,3": "iPad Pro M4 11",
"iPad16,4": "iPad Pro M4 11", "iPad16,4": "iPad Pro M4 11",
"iPad16,5": "iPad Pro M4 13", "iPad16,5": "iPad Pro M4 13",
"iPad16,6": "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,1": "iPhone",
"iPhone1,2": "iPhone 3G", "iPhone1,2": "iPhone 3G",
"iPhone2,1": "iPhone 3GS", "iPhone2,1": "iPhone 3GS",
@@ -101,20 +117,20 @@
"iPhone5,4": "iPhone 5c", "iPhone5,4": "iPhone 5c",
"iPhone6,1": "iPhone 5s", "iPhone6,1": "iPhone 5s",
"iPhone6,2": "iPhone 5s", "iPhone6,2": "iPhone 5s",
"iPhone7,2": "iPhone 6",
"iPhone7,1": "iPhone 6 Plus", "iPhone7,1": "iPhone 6 Plus",
"iPhone7,2": "iPhone 6",
"iPhone8,1": "iPhone 6s", "iPhone8,1": "iPhone 6s",
"iPhone8,2": "iPhone 6s Plus", "iPhone8,2": "iPhone 6s Plus",
"iPhone8,4": "iPhone SE", "iPhone8,4": "iPhone SE",
"iPhone9,1": "iPhone 7", "iPhone9,1": "iPhone 7",
"iPhone9,3": "iPhone 7",
"iPhone9,2": "iPhone 7 Plus", "iPhone9,2": "iPhone 7 Plus",
"iPhone9,3": "iPhone 7",
"iPhone9,4": "iPhone 7 Plus", "iPhone9,4": "iPhone 7 Plus",
"iPhone10,1": "iPhone 8", "iPhone10,1": "iPhone 8",
"iPhone10,4": "iPhone 8",
"iPhone10,2": "iPhone 8 Plus", "iPhone10,2": "iPhone 8 Plus",
"iPhone10,5": "iPhone 8 Plus",
"iPhone10,3": "iPhone X", "iPhone10,3": "iPhone X",
"iPhone10,4": "iPhone 8",
"iPhone10,5": "iPhone 8 Plus",
"iPhone10,6": "iPhone X", "iPhone10,6": "iPhone X",
"iPhone11,2": "iPhone Xs", "iPhone11,2": "iPhone Xs",
"iPhone11,6": "iPhone Xs Max", "iPhone11,6": "iPhone Xs Max",
@@ -127,10 +143,10 @@
"iPhone13,2": "iPhone 12", "iPhone13,2": "iPhone 12",
"iPhone13,3": "iPhone 12 Pro", "iPhone13,3": "iPhone 12 Pro",
"iPhone13,4": "iPhone 12 Pro Max", "iPhone13,4": "iPhone 12 Pro Max",
"iPhone14,4": "iPhone 13 mini",
"iPhone14,5": "iPhone 13",
"iPhone14,2": "iPhone 13 Pro", "iPhone14,2": "iPhone 13 Pro",
"iPhone14,3": "iPhone 13 Pro Max", "iPhone14,3": "iPhone 13 Pro Max",
"iPhone14,4": "iPhone 13 mini",
"iPhone14,5": "iPhone 13",
"iPhone14,6": "iPhone SE", "iPhone14,6": "iPhone SE",
"iPhone14,7": "iPhone 14", "iPhone14,7": "iPhone 14",
"iPhone14,8": "iPhone 14 Plus", "iPhone14,8": "iPhone 14 Plus",
@@ -140,6 +156,19 @@
"iPhone15,5": "iPhone 15 Plus", "iPhone15,5": "iPhone 15 Plus",
"iPhone16,1": "iPhone 15 Pro", "iPhone16,1": "iPhone 15 Pro",
"iPhone16,2": "iPhone 15 Pro Max", "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", "iPod1,1": "iPod touch Original",
"iPod2,1": "iPod touch 2nd", "iPod2,1": "iPod touch 2nd",
"iPod3,1": "iPod touch 3rd Gen", "iPod3,1": "iPod touch 3rd Gen",
+22 -11
View File
@@ -122,11 +122,20 @@ export default async function ResourceAuthPage(props: {
if (searchParams.redirect) { if (searchParams.redirect) {
try { try {
const redirectTarget = new URL(searchParams.redirect);
const serverResourceHost = new URL(authInfo.url).host; const serverResourceHost = new URL(authInfo.url).host;
const redirectHost = new URL(searchParams.redirect).host; const redirectHost = redirectTarget.host;
const redirectPort = new URL(searchParams.redirect).port; const redirectPort = redirectTarget.port;
const serverResourceHostWithPort = `${serverResourceHost}:${redirectPort}`; 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 = ( const wildcardMatchesRedirect = (
wildcardDomain: string, wildcardDomain: string,
host: string host: string
@@ -136,14 +145,16 @@ export default async function ResourceAuthPage(props: {
return host.endsWith(suffix) && host.length > suffix.length; return host.endsWith(suffix) && host.length > suffix.length;
}; };
if (serverResourceHost === redirectHost) { if (
redirectUrl = searchParams.redirect; isHttpTarget &&
} else if (serverResourceHostWithPort === redirectHost) { (serverResourceHost === redirectHost ||
redirectUrl = searchParams.redirect; serverResourceHostWithPort === redirectHost ||
} else if ( (authInfo.wildcard &&
authInfo.wildcard && authInfo.fullDomain &&
authInfo.fullDomain && wildcardMatchesRedirect(
wildcardMatchesRedirect(authInfo.fullDomain, redirectHost) authInfo.fullDomain,
redirectHost
)))
) { ) {
redirectUrl = searchParams.redirect; redirectUrl = searchParams.redirect;
} }
@@ -283,7 +294,7 @@ export default async function ResourceAuthPage(props: {
loginIdps = idpsRes.data.data.idps.map((idp) => ({ loginIdps = idpsRes.data.data.idps.map((idp) => ({
idpId: idp.idpId, idpId: idp.idpId,
name: idp.name, name: idp.name,
variant: idp.type variant: idp.variant ?? idp.type
})) as LoginFormIDP[]; })) as LoginFormIDP[];
} }