Files
homeschool/public/js/auth.js
T
2025-07-15 10:16:59 -04:00

131 lines
3.9 KiB
JavaScript

// 🔐 Password hashing using jsSHA
function hashPassword(password) {
try {
if (typeof jsSHA === 'undefined') {
console.error('jsSHA library not loaded');
throw new Error('jsSHA library not available');
}
const shaObj = new jsSHA("SHA-256", "TEXT");
shaObj.update(password);
return shaObj.getHash("HEX");
} catch (error) {
console.error('Error hashing password:', error);
// Fallback: simple hash (not secure, but for debugging)
let hash = 0;
for (let i = 0; i < password.length; i++) {
const char = password.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return Math.abs(hash).toString(16);
}
}
// 🌐 Load users from server
let users = [];
// 🔓 Verify user login
async function verifyLogin() {
const uname = document.getElementById('username').value.trim();
const pw = document.getElementById('password').value;
const msg = document.getElementById('loginMessage');
if (!uname || !pw) {
msg.textContent = "Please enter both username and password.";
msg.style.color = 'var(--error)';
return;
}
try {
console.log('Attempting login for:', uname);
const hash = hashPassword(pw);
console.log('Generated hash:', hash);
const res = await fetch('/verifyUser', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: uname, hash })
});
const responseText = await res.text();
console.log('Server response:', res.status, responseText);
if (!res.ok) {
msg.textContent = "Invalid username or password.";
msg.style.color = 'var(--error)';
return;
}
const user = JSON.parse(responseText);
console.log('Login successful for user:', user);
localStorage.setItem('loggedInUser', JSON.stringify(user));
msg.textContent = '';
setupSession(user);
} catch (err) {
console.error("Login error:", err);
msg.textContent = "Login failed. Please try again.";
msg.style.color = 'var(--error)';
}
}
// 🚪 Log out user
function logoutUser() {
localStorage.removeItem('loggedInUser');
// Hide all panels
document.getElementById('adminPanel')?.classList.add('hidden');
document.getElementById('studentPanel')?.classList.add('hidden');
document.getElementById('nav')?.classList.add('hidden');
// Show login panel
const loginPanel = document.getElementById('loginPanel');
loginPanel?.classList.remove('hidden');
// Clear login form
const usernameField = document.getElementById('username');
const passwordField = document.getElementById('password');
const loginMessage = document.getElementById('loginMessage');
if (usernameField) usernameField.value = '';
if (passwordField) passwordField.value = '';
if (loginMessage) {
loginMessage.textContent = '';
loginMessage.style.color = '';
}
// Reset banner
const roleBanner = document.getElementById('roleBanner');
if (roleBanner) {
roleBanner.classList.add('hidden');
roleBanner.classList.remove('admin', 'student');
roleBanner.textContent = '';
}
// Focus on username field
if (usernameField) {
setTimeout(() => usernameField.focus(), 100);
}
showToast('Logged out successfully');
}
// Add Enter key support for login form
document.addEventListener('DOMContentLoaded', () => {
const loginForm = document.querySelector('#loginPanel form');
const usernameField = document.getElementById('username');
const passwordField = document.getElementById('password');
if (loginForm && usernameField && passwordField) {
// Focus username field on page load
usernameField.focus();
// Add Enter key support
[usernameField, passwordField].forEach(field => {
field.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
verifyLogin();
}
});
});
}
});