Files
GameList/wwwroot/js/app-auth-handlers.js

214 lines
6.5 KiB
JavaScript

import { api } from "./api.js";
import { t } from "./i18n.js";
import { state, clearUserState, setSavedUsername } from "./state.js";
import { $, toast } from "./dom.js";
import {
handleAuthError,
openNewSuggestionModal,
setAuthMode,
setAuthUI,
} from "./ui.js";
function setupConsentRows() {
const hasConsent = () =>
document.cookie
.split(";")
.some((c) => c.trim().startsWith("cookie_consent=1"));
const setConsent = () => {
document.cookie =
"cookie_consent=1; path=/; max-age=31536000; SameSite=Lax";
};
const consentRows = document.querySelectorAll(".consent-row");
const toggleConsentRows = () => {
const hide = hasConsent();
consentRows.forEach((row) => row.classList.toggle("hidden", hide));
};
toggleConsentRows();
["login-consent", "register-consent"].forEach((id) => {
const box = $(id);
if (box) {
box.checked = hasConsent();
}
});
return { hasConsent, setConsent, toggleConsentRows };
}
function setupAuthModeToggle() {
const toggleAuth = $("auth-toggle");
if (toggleAuth) {
toggleAuth.addEventListener("click", (e) => {
e.preventDefault();
setAuthMode(state.authMode === "login" ? "register" : "login");
});
}
setAuthMode(state.authMode);
}
function applyRegistrationOptions(ownerExists) {
state.ownerExists = !!ownerExists;
const adminKeyField = $("register-admin-key-field");
const adminKeyInput = $("register-adminkey");
if (!adminKeyField || !adminKeyInput) return;
const hideAdminKeyInput = state.ownerExists;
adminKeyField.classList.toggle("hidden", hideAdminKeyInput);
adminKeyInput.disabled = hideAdminKeyInput;
if (hideAdminKeyInput) {
adminKeyInput.value = "";
}
}
async function refreshRegistrationOptions() {
try {
const options = await api.authOptions();
applyRegistrationOptions(options?.ownerExists);
} catch {
applyRegistrationOptions(false);
}
}
function setupLoginUserEditingHint() {
const loginUser = $("login-username");
if (!loginUser) return;
const markEditing = () => {
loginUser.dataset.userEditing = "1";
};
["focus", "input", "keydown"].forEach((evt) =>
loginUser.addEventListener(evt, markEditing),
);
loginUser.addEventListener("blur", () => {
delete loginUser.dataset.userEditing;
});
}
function setupLoginFormHandlers({
hasConsent,
setConsent,
toggleConsentRows,
runSerializedRefresh,
}) {
const loginForm = $("login-form");
if (!loginForm) return;
loginForm.addEventListener("submit", async (e) => {
e.preventDefault();
const username = $("login-username").value.trim();
const password = $("login-password").value;
if (!username || !password)
return toast(t("auth.needCredentials"), true);
if (!hasConsent() && !$("login-consent")?.checked)
return toast(t("auth.cookieRequired"), true);
try {
await api.login({ username, password });
setConsent();
toggleConsentRows();
setSavedUsername(username);
state.isAuthenticated = true;
setAuthUI(true);
await runSerializedRefresh();
toast(t("toast.loggedIn"));
} catch (err) {
if (err?.status === 401)
return toast(t("auth.invalidCredentials"), true);
if (handleAuthError(err, clearUserState)) return;
}
});
}
function setupRegisterFormHandlers({
hasConsent,
setConsent,
toggleConsentRows,
runSerializedRefresh,
}) {
const registerForm = $("register-form");
if (!registerForm) return;
registerForm.addEventListener("submit", async (e) => {
e.preventDefault();
const username = $("register-username").value.trim();
const password = $("register-password").value;
const displayName = $("register-displayName").value.trim();
const adminKey = $("register-adminkey").value.trim();
if (!displayName)
return toast(
t("toast.displayNameRequired") || "Display name is required.",
true,
);
if (!username || !password)
return toast(t("auth.needCredentials"), true);
if (!hasConsent() && !$("register-consent")?.checked)
return toast(t("auth.cookieRequired"), true);
try {
await api.register({ username, password, displayName, adminKey });
await refreshRegistrationOptions();
setConsent();
toggleConsentRows();
setSavedUsername(username);
state.isAuthenticated = true;
setAuthUI(true);
await runSerializedRefresh();
toast(t("toast.registered"));
} catch (err) {
if (handleAuthError(err, clearUserState)) return;
toast(err.message, true);
}
});
}
function setupLogoutHandler() {
const logoutBtn = $("logout");
if (!logoutBtn) return;
logoutBtn.addEventListener("click", async (e) => {
e.preventDefault();
try {
await api.logout();
} catch (err) {
toast(err.message, true);
}
document.querySelectorAll(".auth-form").forEach((form) => form.reset());
setAuthMode("login");
setSavedUsername("");
clearUserState();
state.isAuthenticated = false;
setAuthUI(false);
await refreshRegistrationOptions();
});
}
function setupSuggestionEntryButtons() {
const openSuggestBtn = $("open-suggest-modal");
if (openSuggestBtn) {
openSuggestBtn.addEventListener("click", (e) => {
e.preventDefault();
if (openSuggestBtn.disabled) return;
if (state.phase !== "Suggest") return;
openNewSuggestionModal();
});
}
const openJokerBtn = $("open-joker-modal");
if (openJokerBtn) {
openJokerBtn.addEventListener("click", (e) => {
e.preventDefault();
if (state.phase !== "Vote" || !state.hasJoker) return;
openNewSuggestionModal();
});
}
}
export function setupAuthHandlers({ runSerializedRefresh }) {
setupAuthModeToggle();
refreshRegistrationOptions();
const consent = setupConsentRows();
setupLoginUserEditingHint();
setupLoginFormHandlers({ ...consent, runSerializedRefresh });
setupRegisterFormHandlers({ ...consent, runSerializedRefresh });
setupSuggestionEntryButtons();
setupLogoutHandler();
}