blastoise-archive/public/auth.js

129 lines
3.7 KiB
JavaScript

// MusicRoom - Auth module
// Login, signup, logout, guest authentication
(function() {
const M = window.MusicRoom;
// Load current user from session
M.loadCurrentUser = async function() {
try {
const res = await fetch("/api/auth/me");
const data = await res.json();
M.currentUser = data.user;
if (M.currentUser && data.permissions) {
M.currentUser.permissions = data.permissions;
}
M.updateAuthUI();
} catch (e) {
M.currentUser = null;
M.updateAuthUI();
}
};
// Tab switching
M.$("#tab-login").onclick = () => {
M.$("#tab-login").classList.add("active");
M.$("#tab-signup").classList.remove("active");
M.$("#login-fields").classList.remove("hidden");
M.$("#signup-fields").classList.add("hidden");
M.$("#auth-error").textContent = "";
M.$("#signup-error").textContent = "";
};
M.$("#tab-signup").onclick = () => {
M.$("#tab-signup").classList.add("active");
M.$("#tab-login").classList.remove("active");
M.$("#signup-fields").classList.remove("hidden");
M.$("#login-fields").classList.add("hidden");
M.$("#auth-error").textContent = "";
M.$("#signup-error").textContent = "";
};
// Login
M.$("#btn-login").onclick = async () => {
const username = M.$("#login-username").value.trim();
const password = M.$("#login-password").value;
try {
const res = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password })
});
const data = await res.json();
if (!res.ok) {
M.$("#auth-error").textContent = data.error || "Login failed";
return;
}
M.$("#login-username").value = "";
M.$("#login-password").value = "";
await M.loadCurrentUser();
M.loadStreams();
} catch (e) {
M.$("#auth-error").textContent = "Login failed";
}
};
// Signup
M.$("#btn-signup").onclick = async () => {
const username = M.$("#signup-username").value.trim();
const password = M.$("#signup-password").value;
try {
const res = await fetch("/api/auth/signup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password })
});
const data = await res.json();
if (!res.ok) {
M.$("#signup-error").textContent = data.error || "Signup failed";
return;
}
M.$("#signup-username").value = "";
M.$("#signup-password").value = "";
await M.loadCurrentUser();
M.loadStreams();
} catch (e) {
M.$("#signup-error").textContent = "Signup failed";
}
};
// Guest login
M.$("#btn-guest").onclick = async () => {
try {
const res = await fetch("/api/auth/me");
const data = await res.json();
M.currentUser = data.user;
if (M.currentUser && data.permissions) {
M.currentUser.permissions = data.permissions;
}
M.updateAuthUI();
if (M.currentUser) M.loadStreams();
} catch (e) {
M.$("#auth-error").textContent = "Failed to continue as guest";
}
};
// Logout
M.$("#btn-logout").onclick = async () => {
const wasGuest = M.currentUser?.isGuest;
await fetch("/api/auth/logout", { method: "POST" });
M.currentUser = null;
if (wasGuest) {
// Guest clicking "Sign In" - show login panel
M.updateAuthUI();
} else {
// Regular user logging out - reload to get new guest session
M.updateAuthUI();
}
};
// New playlist button
M.$("#btn-new-playlist").onclick = () => {
if (!M.currentUser || M.currentUser.isGuest) {
alert("Sign in to create playlists");
return;
}
M.createNewPlaylist();
};
})();