const STORAGE_KEY = "baron_sso_session"; const PENDING_LOGIN_KEY = "baron_sso_pending_login"; const STATE_KEY = "baron_sso_state"; const VERIFIER_KEY = "baron_sso_code_verifier"; const RETURN_TO_KEY = "baron_sso_return_to"; const FORCE_LOGIN_KEY = "baron_sso_force_login"; const OVERLAY_ID = "baron-sso-overlay"; const STYLE_ID = "baron-sso-style"; const messages = { ko: { loadingTitle: "BARON SSO 확인 중", loadingDescription: "접근 권한을 확인하고 있습니다.", redirectTitle: "BARON SSO 로그인으로 이동합니다", redirectDescription: "내부 사용자 인증이 필요합니다.", redirectAction: "다시 로그인", unauthorizedTitle: "접근 권한이 없습니다", unauthorizedDescription: "BARON 내부 사용자 계정으로 로그인해야 합니다.", retryAction: "다시 로그인", configTitle: "BARON SSO 설정이 필요합니다", configDescription: "clientId, authorizeUrl, tokenUrl 값을 먼저 설정하세요.", exchangeTitle: "로그인 처리에 실패했습니다", exchangeDescription: "인증 응답을 처리하지 못했습니다. 다시 로그인해 주세요.", logoutAction: "로그아웃", }, en: { loadingTitle: "Checking BARON SSO", loadingDescription: "Verifying your access.", redirectTitle: "Redirecting to BARON SSO", redirectDescription: "Internal user authentication is required.", redirectAction: "Sign in again", unauthorizedTitle: "Access denied", unauthorizedDescription: "You must sign in with an internal BARON account.", retryAction: "Sign in again", configTitle: "BARON SSO configuration required", configDescription: "Set clientId, authorizeUrl, and tokenUrl before enabling the gate.", exchangeTitle: "Login failed", exchangeDescription: "The authentication response could not be processed. Please try again.", logoutAction: "Logout", }, }; async function mergeConfig(overrides = {}) { const module = await import("./baron-sso-config.js?v=20260721-worker2"); const baseConfig = module.default || {}; const windowConfig = window.BARON_SSO_CONFIG || {}; const config = { ...baseConfig, ...windowConfig, ...overrides, }; config.allowedEmailDomains = normalizeArray(config.allowedEmailDomains); config.allowedEmails = normalizeArray(config.allowedEmails); config.requiredGroups = normalizeArray(config.requiredGroups); config.publicPaths = normalizeArray(config.publicPaths); config.extraAuthorizeParams = config.extraAuthorizeParams || {}; config.extraTokenParams = config.extraTokenParams || {}; config.locale = config.locale || detectLocale(); return config; } function normalizeArray(value) { return Array.isArray(value) ? value.filter(Boolean) : []; } function getRootPrefix(pathname = window.location.pathname) { const pathSegments = pathname.split("/").filter(Boolean); const rootMarkerSegments = ["ko", "en", "callback", "assets", "protected", "public", "recruit"]; return pathSegments.length && !rootMarkerSegments.includes(pathSegments[0]) ? `/${pathSegments[0]}` : ""; } function normalizePath(path) { if (!path) { return "/"; } const normalizedPath = path.replace(/\/index\.html$/i, "/"); if (normalizedPath.length > 1 && normalizedPath.endsWith("/")) { return normalizedPath.slice(0, -1); } return normalizedPath; } function matchesPublicPath(path, entry) { const normalizedPath = normalizePath(path); const normalizedEntry = normalizePath(entry); if (normalizedEntry.endsWith("_")) { return normalizedPath.startsWith(normalizedEntry); } return normalizedPath === normalizedEntry || normalizedPath.startsWith(`${normalizedEntry}/`); } function detectLocale() { return window.location.pathname.startsWith("/en/") ? "en" : "ko"; } function isLocalEnvironment() { return window.location.hostname !== "baroncs.co.kr"; } function getMessage(config, key) { const localeMessages = messages[config.locale] || messages.ko; return localeMessages[key]; } function getWorkerManagedAuth() { const workerAuth = window.BARON_WORKER_AUTH; if (!workerAuth || workerAuth.mode !== "worker") { return null; } return workerAuth; } function attachWorkerManagedLogout(workerAuth) { window.baronSsoLogout = () => { const logoutUrl = workerAuth?.logoutUrl || "/auth/logout"; window.location.assign(logoutUrl); }; } function installStyles() { if (document.getElementById(STYLE_ID)) { return; } const style = document.createElement("style"); style.id = STYLE_ID; style.textContent = ` html[data-baron-auth-pending="true"] body > :not(#${OVERLAY_ID}) { visibility: hidden; } #${OVERLAY_ID} { position: fixed; inset: 0; z-index: 99999; display: none; align-items: center; justify-content: center; padding: 24px; background: rgba(9, 17, 27, 0.78); font-family: "Pretendard", "Noto Sans KR", sans-serif; } #${OVERLAY_ID}.is-visible { display: flex; } #${OVERLAY_ID} .baron-sso-panel { width: min(480px, 100%); padding: 32px 28px; border-radius: 20px; background: #ffffff; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.18); color: #111827; text-align: center; } #${OVERLAY_ID} .baron-sso-title { margin: 0; font-size: 28px; font-weight: 700; line-height: 1.3; } #${OVERLAY_ID} .baron-sso-description { margin: 12px 0 0; font-size: 16px; line-height: 1.6; color: #4b5563; } #${OVERLAY_ID} .baron-sso-actions { display: flex; gap: 12px; justify-content: center; margin-top: 24px; flex-wrap: wrap; } #${OVERLAY_ID} button { min-width: 160px; padding: 12px 18px; border: 0; border-radius: 999px; background: #101828; color: #ffffff; font-size: 15px; font-weight: 600; cursor: pointer; } #${OVERLAY_ID} button.baron-sso-secondary { background: #e5e7eb; color: #111827; } `; document.head.appendChild(style); } function waitForBody() { if (document.body) { return Promise.resolve(); } return new Promise((resolve) => { document.addEventListener("DOMContentLoaded", resolve, { once: true }); }); } function setPending(isPending) { document.documentElement.toggleAttribute("data-baron-auth-pending", isPending); } function ensureOverlay() { let overlay = document.getElementById(OVERLAY_ID); if (!overlay) { overlay = document.createElement("div"); overlay.id = OVERLAY_ID; overlay.innerHTML = `
`; document.body.appendChild(overlay); } return overlay; } function renderOverlay(config, options) { installStyles(); const overlay = ensureOverlay(); const title = overlay.querySelector(".baron-sso-title"); const description = overlay.querySelector(".baron-sso-description"); const actions = overlay.querySelector(".baron-sso-actions"); title.textContent = options.title; description.textContent = options.description; actions.innerHTML = ""; (options.actions || []).forEach((action) => { const button = document.createElement("button"); button.type = "button"; button.textContent = action.label; if (action.secondary) { button.className = "baron-sso-secondary"; } button.addEventListener("click", action.onClick); actions.appendChild(button); }); overlay.classList.add("is-visible"); setPending(true); } function hideOverlay() { const overlay = document.getElementById(OVERLAY_ID); if (overlay) { overlay.classList.remove("is-visible"); } setPending(false); } function isConfigured(config) { return Boolean(config.clientId && config.authorizeUrl && config.tokenUrl); } function isPublicPath(config) { const currentPath = normalizePath(window.location.pathname); return config.publicPaths.some((entry) => matchesPublicPath(currentPath, entry)); } function buildRedirectUri(config) { return config.redirectUri || `${window.location.origin}${window.location.pathname}`; } function getCallbackPaths(config) { const configuredPath = normalizePath(new URL(buildRedirectUri(config)).pathname); const rootPrefix = getRootPrefix(); const candidatePaths = [ configuredPath, `${rootPrefix}/callback.html`, `${rootPrefix}/callback/index.html`, ]; return [...new Set(candidatePaths)]; } function buildReturnToUrl() { const currentUrl = new URL(window.location.href); currentUrl.search = ""; currentUrl.hash = ""; return currentUrl.toString(); } function isCallbackPath(config) { return getCallbackPaths(config).includes(normalizePath(window.location.pathname)); } function getCryptoObject() { return window.crypto || window.msCrypto || null; } function fillRandomValues(bytes) { const cryptoObject = getCryptoObject(); if (cryptoObject?.getRandomValues) { cryptoObject.getRandomValues(bytes); return bytes; } for (let index = 0; index < bytes.length; index += 1) { bytes[index] = Math.floor(Math.random() * 256); } return bytes; } function rightRotate(value, amount) { return (value >>> amount) | (value << (32 - amount)); } function sha256Fallback(message) { const constants = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, ]; const initialHash = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, ]; const bytes = new TextEncoder().encode(message); const bitLength = bytes.length * 8; const paddedLength = (((bytes.length + 9 + 63) >> 6) << 6); const padded = new Uint8Array(paddedLength); padded.set(bytes); padded[bytes.length] = 0x80; const bitLengthHigh = Math.floor(bitLength / 0x100000000); const bitLengthLow = bitLength >>> 0; padded[padded.length - 8] = (bitLengthHigh >>> 24) & 0xff; padded[padded.length - 7] = (bitLengthHigh >>> 16) & 0xff; padded[padded.length - 6] = (bitLengthHigh >>> 8) & 0xff; padded[padded.length - 5] = bitLengthHigh & 0xff; padded[padded.length - 4] = (bitLengthLow >>> 24) & 0xff; padded[padded.length - 3] = (bitLengthLow >>> 16) & 0xff; padded[padded.length - 2] = (bitLengthLow >>> 8) & 0xff; padded[padded.length - 1] = bitLengthLow & 0xff; const words = new Uint32Array(64); const hash = initialHash.slice(); for (let offset = 0; offset < padded.length; offset += 64) { for (let index = 0; index < 16; index += 1) { const position = offset + index * 4; words[index] = ( (padded[position] << 24) | (padded[position + 1] << 16) | (padded[position + 2] << 8) | padded[position + 3] ) >>> 0; } for (let index = 16; index < 64; index += 1) { const sigma0 = rightRotate(words[index - 15], 7) ^ rightRotate(words[index - 15], 18) ^ (words[index - 15] >>> 3); const sigma1 = rightRotate(words[index - 2], 17) ^ rightRotate(words[index - 2], 19) ^ (words[index - 2] >>> 10); words[index] = (words[index - 16] + sigma0 + words[index - 7] + sigma1) >>> 0; } let a = hash[0]; let b = hash[1]; let c = hash[2]; let d = hash[3]; let e = hash[4]; let f = hash[5]; let g = hash[6]; let h = hash[7]; for (let index = 0; index < 64; index += 1) { const sigma1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25); const choice = (e & f) ^ (~e & g); const temp1 = (h + sigma1 + choice + constants[index] + words[index]) >>> 0; const sigma0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22); const majority = (a & b) ^ (a & c) ^ (b & c); const temp2 = (sigma0 + majority) >>> 0; h = g; g = f; f = e; e = (d + temp1) >>> 0; d = c; c = b; b = a; a = (temp1 + temp2) >>> 0; } hash[0] = (hash[0] + a) >>> 0; hash[1] = (hash[1] + b) >>> 0; hash[2] = (hash[2] + c) >>> 0; hash[3] = (hash[3] + d) >>> 0; hash[4] = (hash[4] + e) >>> 0; hash[5] = (hash[5] + f) >>> 0; hash[6] = (hash[6] + g) >>> 0; hash[7] = (hash[7] + h) >>> 0; } const digest = new Uint8Array(32); hash.forEach((value, index) => { const position = index * 4; digest[position] = (value >>> 24) & 0xff; digest[position + 1] = (value >>> 16) & 0xff; digest[position + 2] = (value >>> 8) & 0xff; digest[position + 3] = value & 0xff; }); return digest; } function createRandomString(length = 64) { const bytes = new Uint8Array(length); fillRandomValues(bytes); return base64UrlEncode(bytes).slice(0, length); } function base64UrlEncode(input) { const bytes = input instanceof Uint8Array ? input : new TextEncoder().encode(String(input)); let binary = ""; bytes.forEach((byte) => { binary += String.fromCharCode(byte); }); return window.btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); } async function createCodeChallenge(verifier) { const cryptoObject = getCryptoObject(); if (cryptoObject?.subtle?.digest) { const digest = await cryptoObject.subtle.digest("SHA-256", new TextEncoder().encode(verifier)); return base64UrlEncode(new Uint8Array(digest)); } return base64UrlEncode(sha256Fallback(verifier)); } function savePendingLogin(state, verifier, returnTo, redirectUri) { sessionStorage.setItem(STATE_KEY, state); sessionStorage.setItem(VERIFIER_KEY, verifier); sessionStorage.setItem(RETURN_TO_KEY, returnTo); if (redirectUri) { sessionStorage.setItem(`${PENDING_LOGIN_KEY}_redirect_uri`, redirectUri); } localStorage.setItem(PENDING_LOGIN_KEY, JSON.stringify({ state, verifier, returnTo, redirectUri })); } function clearPendingLogin() { sessionStorage.removeItem(STATE_KEY); sessionStorage.removeItem(VERIFIER_KEY); sessionStorage.removeItem(RETURN_TO_KEY); sessionStorage.removeItem(`${PENDING_LOGIN_KEY}_redirect_uri`); localStorage.removeItem(PENDING_LOGIN_KEY); } function loadPendingLogin() { const state = sessionStorage.getItem(STATE_KEY); const verifier = sessionStorage.getItem(VERIFIER_KEY); const returnTo = sessionStorage.getItem(RETURN_TO_KEY); const redirectUri = sessionStorage.getItem(`${PENDING_LOGIN_KEY}_redirect_uri`); if (state && verifier) { return { state, verifier, returnTo, redirectUri, }; } const raw = localStorage.getItem(PENDING_LOGIN_KEY); if (!raw) { return null; } try { const pendingLogin = JSON.parse(raw); if (!pendingLogin?.state || !pendingLogin?.verifier) { localStorage.removeItem(PENDING_LOGIN_KEY); return null; } sessionStorage.setItem(STATE_KEY, pendingLogin.state); sessionStorage.setItem(VERIFIER_KEY, pendingLogin.verifier); if (pendingLogin.returnTo) { sessionStorage.setItem(RETURN_TO_KEY, pendingLogin.returnTo); } if (pendingLogin.redirectUri) { sessionStorage.setItem(`${PENDING_LOGIN_KEY}_redirect_uri`, pendingLogin.redirectUri); } return pendingLogin; } catch { localStorage.removeItem(PENDING_LOGIN_KEY); return null; } } function markForceLogin() { sessionStorage.setItem(FORCE_LOGIN_KEY, "1"); } function consumeForceLogin() { const shouldForce = sessionStorage.getItem(FORCE_LOGIN_KEY) === "1"; sessionStorage.removeItem(FORCE_LOGIN_KEY); return shouldForce; } function saveSession(session) { localStorage.setItem(STORAGE_KEY, JSON.stringify(session)); } function loadSession() { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) { return null; } try { return JSON.parse(raw); } catch { localStorage.removeItem(STORAGE_KEY); return null; } } function clearSession() { localStorage.removeItem(STORAGE_KEY); } function isExpired(session) { if (!session || !session.expiresAt) { return true; } return Date.now() >= Number(session.expiresAt); } function decodeJwt(token) { if (!token || token.split(".").length < 2) { return null; } try { const payload = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"); const normalized = payload.padEnd(payload.length + ((4 - (payload.length % 4)) % 4), "="); return JSON.parse(window.atob(normalized)); } catch { return null; } } async function fetchUserInfo(config, accessToken) { if (!config.userInfoUrl || !accessToken) { return null; } const response = await fetch(config.userInfoUrl, { headers: { Authorization: `Bearer ${accessToken}`, }, }); if (!response.ok) { throw new Error(`User info request failed: ${response.status}`); } return response.json(); } async function resolveProfile(config, tokenResult) { const idTokenClaims = decodeJwt(tokenResult.id_token); const accessTokenClaims = decodeJwt(tokenResult.access_token); if (idTokenClaims) { return idTokenClaims; } if (accessTokenClaims) { return accessTokenClaims; } return fetchUserInfo(config, tokenResult.access_token); } function readProfileEmail(profile) { return ( profile?.email || profile?.preferred_username || profile?.upn || profile?.unique_name || "" ) .trim() .toLowerCase(); } function hasRequiredGroup(config, profile) { if (!config.requiredGroups.length) { return true; } const groupValue = profile?.[config.groupClaim]; const groups = Array.isArray(groupValue) ? groupValue : typeof groupValue === "string" ? [groupValue] : []; return config.requiredGroups.some((group) => groups.includes(group)); } function isAuthorized(config, profile) { if (!profile) { return false; } const email = readProfileEmail(profile); if (config.allowedEmails.length && !config.allowedEmails.includes(email)) { return false; } if (config.allowedEmailDomains.length) { const hasDomain = config.allowedEmailDomains.some((domain) => email.endsWith(`@${domain.toLowerCase()}`)); if (!hasDomain) { return false; } } return hasRequiredGroup(config, profile); } async function exchangeCode(config, code, verifier) { const pendingLogin = loadPendingLogin(); const redirectUri = pendingLogin?.redirectUri || buildRedirectUri(config); const body = new URLSearchParams({ grant_type: "authorization_code", client_id: config.clientId, code, code_verifier: verifier, redirect_uri: redirectUri, }); Object.entries(config.extraTokenParams).forEach(([key, value]) => { if (value !== undefined && value !== null) { body.set(key, String(value)); } }); const response = await fetch(config.tokenUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body, }); if (!response.ok) { let errorDetail = ""; try { const responseText = await response.text(); if (responseText) { errorDetail = responseText; } } catch { errorDetail = ""; } const errorMessage = errorDetail ? `Token request failed: ${response.status} ${errorDetail}` : `Token request failed: ${response.status}`; throw new Error(errorMessage); } return response.json(); } async function handleCallback(config) { const currentUrl = new URL(window.location.href); const code = currentUrl.searchParams.get("code"); const state = currentUrl.searchParams.get("state"); if (!code || !state) { return false; } const pendingLogin = loadPendingLogin(); const expectedState = pendingLogin?.state || null; const verifier = pendingLogin?.verifier || null; const returnTo = pendingLogin?.returnTo || buildRedirectUri(config); if (!expectedState || !verifier || expectedState !== state) { clearPendingLogin(); throw new Error("Invalid OAuth state"); } const tokenResult = await exchangeCode(config, code, verifier); const profile = await resolveProfile(config, tokenResult); if (!isAuthorized(config, profile)) { clearPendingLogin(); clearSession(); throw new Error("User is not authorized"); } const expiresIn = Number(tokenResult.expires_in || 3600); saveSession({ accessToken: tokenResult.access_token, idToken: tokenResult.id_token || "", tokenType: tokenResult.token_type || "Bearer", profile, expiresAt: Date.now() + Math.max(expiresIn - 30, 30) * 1000, }); clearPendingLogin(); return { handled: true, returnTo, }; } async function startLogin(config) { const verifier = createRandomString(96); const state = createRandomString(48); const challenge = await createCodeChallenge(verifier); const returnTo = buildReturnToUrl(); const redirectUri = buildRedirectUri(config); const shouldForceLogin = consumeForceLogin(); savePendingLogin(state, verifier, returnTo, redirectUri); const authorizeUrl = new URL(config.authorizeUrl); authorizeUrl.searchParams.set("response_type", "code"); authorizeUrl.searchParams.set("client_id", config.clientId); authorizeUrl.searchParams.set("redirect_uri", redirectUri); authorizeUrl.searchParams.set("scope", config.scope); authorizeUrl.searchParams.set("state", state); authorizeUrl.searchParams.set("code_challenge", challenge); authorizeUrl.searchParams.set("code_challenge_method", "S256"); Object.entries(config.extraAuthorizeParams).forEach(([key, value]) => { if (value !== undefined && value !== null) { authorizeUrl.searchParams.set(key, String(value)); } }); if (shouldForceLogin && !authorizeUrl.searchParams.has("prompt")) { authorizeUrl.searchParams.set("prompt", "login"); } renderOverlay(config, { title: getMessage(config, "redirectTitle"), description: getMessage(config, "redirectDescription"), actions: [ { label: getMessage(config, "redirectAction"), onClick: () => { window.location.assign(authorizeUrl.toString()); }, }, ], }); window.location.assign(authorizeUrl.toString()); } async function restoreSession(config) { const session = loadSession(); if (!session || isExpired(session)) { clearSession(); return null; } if (!isAuthorized(config, session.profile)) { clearSession(); return null; } return session; } function attachLogout(config) { window.baronSsoLogout = () => { const session = loadSession(); const idTokenHint = session?.idToken; const localRedirectTarget = config.postLogoutRedirectUri || `${window.location.origin}/`; const shouldUseLocalOnlyLogout = isLocalEnvironment() || !config.logoutUrl || !idTokenHint; clearPendingLogin(); clearSession(); window.BARON_SSO_SESSION = null; if (shouldUseLocalOnlyLogout) { markForceLogin(); window.location.assign(localRedirectTarget); return; } const logoutUrl = new URL(config.logoutUrl); logoutUrl.searchParams.set("id_token_hint", idTokenHint); logoutUrl.searchParams.set("client_id", config.clientId); if (config.postLogoutRedirectUri) { logoutUrl.searchParams.set("post_logout_redirect_uri", config.postLogoutRedirectUri); } window.location.assign(logoutUrl.toString()); }; } export async function ensureBaronSsoAuth(overrides = {}) { const currentUrl = new URL(window.location.href); const hasCallbackParams = currentUrl.searchParams.has("code") || currentUrl.searchParams.has("state"); const workerAuth = getWorkerManagedAuth(); const workerPublicPaths = normalizeArray(overrides.publicPaths); const workerPublicPath = workerPublicPaths.some((entry) => matchesPublicPath(window.location.pathname, entry)); const workerForceAuth = Boolean(overrides.forceAuth); if (workerAuth) { attachWorkerManagedLogout(workerAuth); if (workerAuth.authenticated) { const session = { workerManaged: true, profile: workerAuth.profile || {}, expiresAt: Number.MAX_SAFE_INTEGER, }; window.BARON_SSO_SESSION = session; hideOverlay(); return { status: "worker-authenticated", session }; } if (workerForceAuth || !workerPublicPath) { window.location.assign(workerAuth.loginUrl || "/auth/login"); return { status: "worker-redirecting" }; } return { status: "public" }; } const config = await mergeConfig(overrides); const publicPath = isPublicPath(config); if (!config.enabled) { return { status: "disabled" }; } attachLogout(config); if (publicPath && !config.forceAuth) { const session = await restoreSession(config); if (session) { window.BARON_SSO_SESSION = session; hideOverlay(); return { status: "authenticated-public", session }; } return { status: "public" }; } await waitForBody(); renderOverlay(config, { title: getMessage(config, "loadingTitle"), description: getMessage(config, "loadingDescription"), }); if (!isConfigured(config)) { renderOverlay(config, { title: getMessage(config, "configTitle"), description: getMessage(config, "configDescription"), }); return { status: "misconfigured" }; } try { if (isCallbackPath(config) && !hasCallbackParams) { window.location.replace(config.postLogoutRedirectUri || `${window.location.origin}/`); return { status: "callback-idle" }; } const callbackResult = await handleCallback(config); if (callbackResult?.handled) { const destination = callbackResult.returnTo || `${window.location.origin}/`; if (destination !== window.location.href) { window.location.replace(destination); return { status: "redirected", returnTo: destination }; } } const session = await restoreSession(config); if (session) { window.BARON_SSO_SESSION = session; hideOverlay(); return { status: "authenticated", session }; } await startLogin(config); return { status: "redirecting" }; } catch (error) { console.error("BARON SSO authentication failed.", error); const isUnauthorized = error.message === "User is not authorized"; const detailDescription = isUnauthorized ? getMessage(config, "unauthorizedDescription") : isLocalEnvironment() ? `${getMessage(config, "exchangeDescription")} (${error.message})` : getMessage(config, "exchangeDescription"); clearSession(); clearPendingLogin(); renderOverlay(config, { title: getMessage(config, "unauthorizedTitle"), description: detailDescription, actions: [ { label: getMessage(config, "retryAction"), onClick: () => { startLogin(config); }, }, { label: getMessage(config, "logoutAction"), secondary: true, onClick: () => { window.baronSsoLogout(); }, }, ], }); return { status: "failed", error }; } }