Files
crank/apps/ui/js/auth.js
T
2026-03-31 16:09:10 +03:00

169 lines
4.2 KiB
JavaScript

(function() {
var STORAGE_KEY = 'crank_user';
var sessionCache = null;
var sessionPromise = null;
function isLoginPage() {
return /\/html\/login\.html$/.test(window.location.pathname);
}
function loginUrl() {
return (window.APP_BASE || '') + 'html/login.html';
}
function homeUrl() {
return (window.APP_BASE || '') + 'index.html';
}
function clearUserMirror() {
sessionCache = null;
sessionPromise = null;
try {
localStorage.removeItem(STORAGE_KEY);
} catch (_error) {}
}
function primaryMembership(session) {
if (!(session && session.memberships && session.memberships.length)) {
return null;
}
if (session.current_workspace_id) {
var currentMembership = session.memberships.find(function(item) {
return item.workspace && item.workspace.id === session.current_workspace_id;
});
if (currentMembership) {
return currentMembership;
}
}
if (window.getCurrentWorkspace) {
var currentWorkspace = window.getCurrentWorkspace();
if (currentWorkspace) {
var matched = session.memberships.find(function(item) {
return item.workspace && item.workspace.id === currentWorkspace.id;
});
if (matched) {
return matched;
}
}
}
return session.memberships[0];
}
function initials(displayName, email) {
var source = displayName || email || 'Crank';
return source
.split(/\s+/)
.filter(Boolean)
.slice(0, 2)
.map(function(part) { return part.charAt(0).toUpperCase(); })
.join('') || 'CR';
}
function persistUserMirror(session) {
var membership = primaryMembership(session);
var user = {
id: session.user.id,
name: session.user.display_name,
email: session.user.email,
role: membership ? String(membership.role || '').replace(/^\w/, function(char) { return char.toUpperCase(); }) : 'Viewer',
workspace: membership ? membership.workspace.slug : '',
workspaceId: membership ? membership.workspace.id : '',
initials: initials(session.user.display_name, session.user.email),
};
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(user));
} catch (_error) {}
}
function replaceSession(session) {
sessionCache = session;
persistUserMirror(session);
return session;
}
async function fetchSession(force) {
if (!force && sessionCache) {
return sessionCache;
}
if (!force && sessionPromise) {
return sessionPromise;
}
sessionPromise = window.CrankApi.getSession()
.then(function(session) {
return replaceSession(session);
})
.catch(function(error) {
clearUserMirror();
throw error;
})
.finally(function() {
sessionPromise = null;
});
return sessionPromise;
}
async function guardProtectedPage() {
try {
return await fetchSession(false);
} catch (error) {
if (error && error.status === 401) {
window.location.replace(loginUrl());
return null;
}
throw error;
}
}
async function guardLoginPage() {
try {
await fetchSession(false);
window.location.replace(homeUrl());
} catch (error) {
if (!error || error.status !== 401) {
throw error;
}
}
}
async function login(email, password) {
var session = await window.CrankApi.login({
email: email,
password: password,
});
replaceSession(session);
window.location.href = homeUrl();
}
async function logout() {
try {
await window.CrankApi.logout();
} finally {
clearUserMirror();
window.location.href = loginUrl();
}
}
function handleUnauthorized() {
if (isLoginPage()) {
clearUserMirror();
return;
}
clearUserMirror();
window.location.replace(loginUrl());
}
window.CrankAuth = {
fetchSession: fetchSession,
replaceSession: replaceSession,
getCachedSession: function() { return sessionCache; },
guardProtectedPage: guardProtectedPage,
guardLoginPage: guardLoginPage,
login: login,
logout: logout,
handleUnauthorized: handleUnauthorized,
};
}());