78 lines
3.2 KiB
JavaScript

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