forked from baron/baron-sso
89 lines
2.0 KiB
TypeScript
89 lines
2.0 KiB
TypeScript
export interface DevFrontAuthRedirectUris {
|
|
redirectUri: string;
|
|
postLogoutRedirectUri: string;
|
|
popupRedirectUri: string;
|
|
}
|
|
|
|
export const DEVFRONT_AUTH_CALLBACK_PATH = "/auth/callback";
|
|
|
|
export function resolveDevFrontPublicOrigin(
|
|
configuredOrigin: string | undefined,
|
|
browserOrigin: string,
|
|
) {
|
|
const trimmed = configuredOrigin?.trim();
|
|
if (!trimmed) {
|
|
return browserOrigin;
|
|
}
|
|
|
|
try {
|
|
return new URL(trimmed).origin;
|
|
} catch {
|
|
return browserOrigin;
|
|
}
|
|
}
|
|
|
|
export function buildDevFrontAuthRedirectUris(
|
|
publicOrigin: string,
|
|
): DevFrontAuthRedirectUris {
|
|
return {
|
|
redirectUri: `${publicOrigin}${DEVFRONT_AUTH_CALLBACK_PATH}`,
|
|
postLogoutRedirectUri: publicOrigin,
|
|
popupRedirectUri: `${publicOrigin}${DEVFRONT_AUTH_CALLBACK_PATH}`,
|
|
};
|
|
}
|
|
|
|
export type BrowserPkceLoginCheck = {
|
|
isSecureContext?: boolean;
|
|
origin?: string;
|
|
cryptoSubtleAvailable?: boolean;
|
|
};
|
|
|
|
const devTrustedPkceHosts = new Set([
|
|
"localhost",
|
|
"127.0.0.1",
|
|
"::1",
|
|
"host.docker.internal",
|
|
]);
|
|
|
|
function isPrivateIPv4(hostname: string) {
|
|
const parts = hostname.split(".").map((part) => Number.parseInt(part, 10));
|
|
if (
|
|
parts.length !== 4 ||
|
|
parts.some((part) => Number.isNaN(part) || part < 0 || part > 255)
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
const [first, second] = parts;
|
|
return (
|
|
first === 10 ||
|
|
(first === 172 && second >= 16 && second <= 31) ||
|
|
(first === 192 && second === 168)
|
|
);
|
|
}
|
|
|
|
function isDevTrustedPkceOrigin(origin: string) {
|
|
try {
|
|
const hostname = new URL(origin).hostname;
|
|
return devTrustedPkceHosts.has(hostname) || isPrivateIPv4(hostname);
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function canStartBrowserPkceLogin({
|
|
isSecureContext = window.isSecureContext,
|
|
origin = window.location.origin,
|
|
cryptoSubtleAvailable = Boolean(window.crypto?.subtle),
|
|
}: BrowserPkceLoginCheck = {}) {
|
|
if (!cryptoSubtleAvailable) {
|
|
return false;
|
|
}
|
|
|
|
if (isSecureContext) {
|
|
return true;
|
|
}
|
|
|
|
return isDevTrustedPkceOrigin(origin);
|
|
}
|