refacto: Keeping entrypoints clean and making files by purpose
This commit is contained in:
147
public/src/auth.js
Normal file
147
public/src/auth.js
Normal file
@@ -0,0 +1,147 @@
|
||||
import { apiLogin, apiRegister, apiGetMe } from "./api.js";
|
||||
import { setCurrentTeam, updateTeamSegmented, refreshFromServer } from "./game.js";
|
||||
|
||||
// ── DOM refs ──────────────────────────────────────────────────────────────────
|
||||
|
||||
const authOverlay = document.getElementById("authOverlay");
|
||||
const tabLogin = document.getElementById("tabLogin");
|
||||
const tabRegister = document.getElementById("tabRegister");
|
||||
const loginForm = document.getElementById("loginForm");
|
||||
const registerForm = document.getElementById("registerForm");
|
||||
const loginUsernameEl = document.getElementById("loginUsername");
|
||||
const loginPasswordEl = document.getElementById("loginPassword");
|
||||
const loginErrorEl = document.getElementById("loginError");
|
||||
const regUsernameEl = document.getElementById("regUsername");
|
||||
const regEmailEl = document.getElementById("regEmail");
|
||||
const regPasswordEl = document.getElementById("regPassword");
|
||||
const registerErrorEl = document.getElementById("registerError");
|
||||
const userDisplayEl = document.getElementById("userDisplay");
|
||||
const logoutBtn = document.getElementById("logoutBtn");
|
||||
|
||||
// ── Auth state ────────────────────────────────────────────────────────────────
|
||||
|
||||
export let authToken = localStorage.getItem("authToken") ?? null;
|
||||
export let currentUser = null;
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
function showError(el, msg) { el.textContent = msg; el.classList.remove("hidden"); }
|
||||
function clearError(el) { el.textContent = ""; el.classList.add("hidden"); }
|
||||
|
||||
export function showAuthOverlay() { authOverlay.classList.remove("hidden"); }
|
||||
export function hideAuthOverlay() { authOverlay.classList.add("hidden"); }
|
||||
|
||||
// ── Apply user (after login / register / session restore) ─────────────────────
|
||||
|
||||
export function applyUser(user, token) {
|
||||
currentUser = user;
|
||||
authToken = token;
|
||||
localStorage.setItem("authToken", token);
|
||||
setCurrentTeam(user.team);
|
||||
userDisplayEl.textContent = `${user.username} [${user.team}]`;
|
||||
logoutBtn.classList.remove("hidden");
|
||||
updateTeamSegmented();
|
||||
}
|
||||
|
||||
function logout() {
|
||||
currentUser = null;
|
||||
authToken = null;
|
||||
localStorage.removeItem("authToken");
|
||||
userDisplayEl.textContent = "—";
|
||||
logoutBtn.classList.add("hidden");
|
||||
showAuthOverlay();
|
||||
}
|
||||
|
||||
// ── Session restore ───────────────────────────────────────────────────────────
|
||||
|
||||
export async function tryRestoreSession() {
|
||||
if (!authToken) return false;
|
||||
try {
|
||||
const res = await apiGetMe(authToken);
|
||||
if (!res.ok) { localStorage.removeItem("authToken"); authToken = null; return false; }
|
||||
const data = await res.json();
|
||||
applyUser(data.user, data.token);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Tab switching ─────────────────────────────────────────────────────────────
|
||||
|
||||
tabLogin.addEventListener("click", () => {
|
||||
tabLogin.classList.add("authTab--active");
|
||||
tabRegister.classList.remove("authTab--active");
|
||||
loginForm.classList.remove("hidden");
|
||||
registerForm.classList.add("hidden");
|
||||
clearError(loginErrorEl);
|
||||
});
|
||||
|
||||
tabRegister.addEventListener("click", () => {
|
||||
tabRegister.classList.add("authTab--active");
|
||||
tabLogin.classList.remove("authTab--active");
|
||||
registerForm.classList.remove("hidden");
|
||||
loginForm.classList.add("hidden");
|
||||
clearError(registerErrorEl);
|
||||
});
|
||||
|
||||
// ── Login form ────────────────────────────────────────────────────────────────
|
||||
|
||||
loginForm.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
clearError(loginErrorEl);
|
||||
const username = loginUsernameEl.value.trim();
|
||||
const password = loginPasswordEl.value;
|
||||
if (!username || !password) return;
|
||||
try {
|
||||
const res = await apiLogin(username, password);
|
||||
const data = await res.json();
|
||||
if (!res.ok) {
|
||||
const msgs = { invalid_credentials: "Invalid username or password.", missing_fields: "Please fill in all fields." };
|
||||
showError(loginErrorEl, msgs[data.error] ?? "Login failed.");
|
||||
return;
|
||||
}
|
||||
applyUser(data.user, data.token);
|
||||
hideAuthOverlay();
|
||||
await refreshFromServer();
|
||||
} catch {
|
||||
showError(loginErrorEl, "Network error. Try again.");
|
||||
}
|
||||
});
|
||||
|
||||
// ── Register form ─────────────────────────────────────────────────────────────
|
||||
|
||||
registerForm.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
clearError(registerErrorEl);
|
||||
const username = regUsernameEl.value.trim();
|
||||
const email = regEmailEl.value.trim();
|
||||
const password = regPasswordEl.value;
|
||||
const teamInput = registerForm.querySelector('input[name="regTeam"]:checked');
|
||||
if (!teamInput) { showError(registerErrorEl, "Please choose a team."); return; }
|
||||
try {
|
||||
const res = await apiRegister(username, email, password, teamInput.value);
|
||||
const data = await res.json();
|
||||
if (!res.ok) {
|
||||
const msgs = {
|
||||
username_taken: "This username is already taken.",
|
||||
email_taken: "This email is already registered.",
|
||||
password_too_short:"Password must be at least 6 characters.",
|
||||
invalid_username: "Username must be 2–32 characters.",
|
||||
missing_fields: "Please fill in all fields.",
|
||||
invalid_team: "Invalid team selected.",
|
||||
};
|
||||
showError(registerErrorEl, msgs[data.error] ?? "Registration failed.");
|
||||
return;
|
||||
}
|
||||
applyUser(data.user, data.token);
|
||||
hideAuthOverlay();
|
||||
await refreshFromServer();
|
||||
} catch {
|
||||
showError(registerErrorEl, "Network error. Try again.");
|
||||
}
|
||||
});
|
||||
|
||||
// ── Logout ────────────────────────────────────────────────────────────────────
|
||||
|
||||
logoutBtn.addEventListener("click", logout);
|
||||
Reference in New Issue
Block a user