import { externalRequest, rememberExternalCsrfToken } from "./client.js"; import { arrayValue, asRecord, textValue } from "./normalizers.js"; // These external-session auth routes intentionally have no main-admin OpenAPI operation. const EXTERNAL_AUTH_PATHS = Object.freeze({ changePassword: "/auth/change-password", login: "/auth/login", logout: "/auth/logout", me: "/auth/me" }); export async function loginExternal(payload) { const data = await externalRequest(EXTERNAL_AUTH_PATHS.login, { body: { account: String(payload.account || "").trim(), password: String(payload.password || "") }, method: "POST", notifyUnauthorized: false }); rememberExternalCsrfToken(asRecord(data).csrfToken); return normalizeSession(data); } export async function getExternalSession() { const data = await externalRequest(EXTERNAL_AUTH_PATHS.me, { notifyUnauthorized: false }); rememberExternalCsrfToken(asRecord(data).csrfToken); return normalizeSession(data); } export async function logoutExternal() { try { await externalRequest(EXTERNAL_AUTH_PATHS.logout, { method: "POST", notifyUnauthorized: false }); } finally { rememberExternalCsrfToken(""); } } export async function changeExternalPassword(payload) { const data = await externalRequest(EXTERNAL_AUTH_PATHS.changePassword, { body: { currentPassword: payload.oldPassword, newPassword: payload.newPassword }, method: "POST" }); return data ? normalizeSession(data) : null; } export function normalizeSession(data) { const root = asRecord(data); const accountRecord = asRecord(root.account); const linkedUser = asRecord(root.user || root.linkedUser || root.linked_user); const legacyAccount = asRecord(root.externalAdminUser || root.external_admin_user); const app = asRecord(root.app || linkedUser.app || accountRecord.app); const capabilities = [ ...arrayValue(root.capabilities), ...arrayValue(root.permissions), ...arrayValue(accountRecord.capabilities, accountRecord.permissions), ...arrayValue(linkedUser.capabilities, linkedUser.permissions) ] .map(String) .filter(Boolean); return { account: textValue(accountRecord.username, accountRecord.account, legacyAccount.username, legacyAccount.account, root.accountName, typeof root.account === "string" ? root.account : "", root.username), appCode: textValue(root.appCode, root.app_code, app.appCode, app.app_code, accountRecord.appCode, accountRecord.app_code, linkedUser.appCode, linkedUser.app_code), appName: textValue(app.name, app.appName, app.app_name, root.appName, root.app_name), logoUrl: textValue(app.logoUrl, app.logo_url, root.logoUrl, root.logo_url), capabilities: [...new Set(capabilities)], displayName: textValue(linkedUser.displayName, linkedUser.display_name, linkedUser.name, linkedUser.username, accountRecord.username, legacyAccount.username, root.displayName), id: textValue(accountRecord.id, accountRecord.externalAdminUserId, accountRecord.external_admin_user_id, legacyAccount.id, root.accountId, root.account_id), passwordChangeRequired: Boolean( root.passwordChangeRequired ?? root.password_change_required ?? accountRecord.passwordChangeRequired ?? accountRecord.password_change_required ) }; }