193 lines
5.9 KiB
JavaScript
193 lines
5.9 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 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 });
|
|
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();
|
|
const lastUser = state.me?.username;
|
|
try {
|
|
await api.logout();
|
|
} catch (err) {
|
|
toast(err.message, true);
|
|
}
|
|
clearUserState();
|
|
state.isAuthenticated = false;
|
|
setAuthUI(false);
|
|
if (lastUser) {
|
|
setSavedUsername(lastUser);
|
|
const loginUser = $("login-username");
|
|
if (loginUser) loginUser.value = lastUser;
|
|
const loginPass = $("login-password");
|
|
if (loginPass) loginPass.value = "";
|
|
}
|
|
});
|
|
}
|
|
|
|
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();
|
|
const consent = setupConsentRows();
|
|
setupLoginUserEditingHint();
|
|
setupLoginFormHandlers({ ...consent, runSerializedRefresh });
|
|
setupRegisterFormHandlers({ ...consent, runSerializedRefresh });
|
|
setupSuggestionEntryButtons();
|
|
setupLogoutHandler();
|
|
}
|