1
0
forked from baron/baron-sso
Files
baron-sso/devfront/src/lib/authConfig.ts
2026-05-14 10:56:23 +09:00

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);
}