89 lines
2.4 KiB
JavaScript
89 lines
2.4 KiB
JavaScript
export function getCurrentRelativeUrl() {
|
|
return `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
|
}
|
|
|
|
export function buildLoginUrl(nextPath = getCurrentRelativeUrl()) {
|
|
const loginUrl = new URL('/login.html', window.location.origin);
|
|
if (nextPath) {
|
|
loginUrl.searchParams.set('next', nextPath);
|
|
}
|
|
|
|
return `${loginUrl.pathname}${loginUrl.search}`;
|
|
}
|
|
|
|
export function buildSetupUrl(nextPath = getCurrentRelativeUrl()) {
|
|
const setupUrl = new URL('/setup.html', window.location.origin);
|
|
if (nextPath) {
|
|
setupUrl.searchParams.set('next', nextPath);
|
|
}
|
|
|
|
return `${setupUrl.pathname}${setupUrl.search}`;
|
|
}
|
|
|
|
export function redirectToLogin(nextPath = getCurrentRelativeUrl()) {
|
|
window.location.assign(buildLoginUrl(nextPath));
|
|
}
|
|
|
|
export function redirectToSetup(nextPath = getCurrentRelativeUrl()) {
|
|
window.location.assign(buildSetupUrl(nextPath));
|
|
}
|
|
|
|
export function readNextPath(fallback = '/') {
|
|
const nextPath = new URLSearchParams(window.location.search).get('next');
|
|
if (!nextPath || !nextPath.startsWith('/') || nextPath.startsWith('//')) {
|
|
return fallback;
|
|
}
|
|
|
|
return nextPath;
|
|
}
|
|
|
|
export function redirectToNextPath(fallback = '/') {
|
|
window.location.assign(readNextPath(fallback));
|
|
}
|
|
|
|
export async function loadAuthState() {
|
|
const response = await fetch('/api/auth/state');
|
|
const payload = await response.json().catch(() => ({}));
|
|
if (!response.ok) {
|
|
throw new Error(`${payload.error?.code ?? 'AUTH_STATE_FAILED'}: ${payload.error?.message ?? 'Failed to load auth state.'}`);
|
|
}
|
|
|
|
return payload.auth;
|
|
}
|
|
|
|
export async function logoutCurrentSession() {
|
|
const response = await fetch('/api/auth/logout', {
|
|
method: 'POST'
|
|
});
|
|
const payload = await response.json().catch(() => ({ ok: false }));
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`${payload.error?.code ?? 'LOGOUT_FAILED'}: ${payload.error?.message ?? 'Logout failed.'}`);
|
|
}
|
|
|
|
return payload;
|
|
}
|
|
|
|
export function bindLogoutButton(button, labelElement, fallbackLabel = '已登录') {
|
|
if (!button) {
|
|
return;
|
|
}
|
|
|
|
button.addEventListener('click', async () => {
|
|
button.disabled = true;
|
|
if (labelElement) {
|
|
labelElement.textContent = 'Signing out...';
|
|
}
|
|
|
|
try {
|
|
await logoutCurrentSession();
|
|
} finally {
|
|
redirectToLogin('/');
|
|
}
|
|
});
|
|
|
|
if (labelElement && !labelElement.textContent.trim()) {
|
|
labelElement.textContent = fallbackLabel;
|
|
}
|
|
}
|