All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 29s
121 lines
4.2 KiB
JavaScript
121 lines
4.2 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const { Users } = require('../models');
|
|
|
|
router.get('/login', (req, res) => {
|
|
res.render('auth/login', { title: 'Login', error: null });
|
|
});
|
|
|
|
router.post('/login', (req, res) => {
|
|
const { username, password } = req.body;
|
|
|
|
if (!username || !password) {
|
|
return res.render('auth/login', { title: 'Login', error: 'Username and password are required.' });
|
|
}
|
|
|
|
const user = Users.findByUsername(username);
|
|
if (!user || !Users.verifyPassword(user, password)) {
|
|
return res.render('auth/login', { title: 'Login', error: 'Invalid username or password.' });
|
|
}
|
|
|
|
req.session.userId = user.id;
|
|
req.session.username = user.username;
|
|
req.session.isAdmin = !!user.is_admin;
|
|
req.session.isOrganizer = !!user.is_organizer;
|
|
|
|
const returnTo = req.session.returnTo || '/';
|
|
delete req.session.returnTo;
|
|
res.redirect(returnTo);
|
|
});
|
|
|
|
router.get('/register', (req, res) => {
|
|
res.render('auth/register', { title: 'Register', error: null });
|
|
});
|
|
|
|
router.post('/register', (req, res) => {
|
|
const { username, password, password_confirm } = req.body;
|
|
|
|
if (!username || !password) {
|
|
return res.render('auth/register', { title: 'Register', error: 'Username and password are required.' });
|
|
}
|
|
|
|
if (username.length < 3 || username.length > 24) {
|
|
return res.render('auth/register', { title: 'Register', error: 'Username must be 3-24 characters.' });
|
|
}
|
|
|
|
if (!/^[a-zA-Z0-9_-]+$/.test(username)) {
|
|
return res.render('auth/register', { title: 'Register', error: 'Username can only contain letters, numbers, hyphens and underscores.' });
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
return res.render('auth/register', { title: 'Register', error: 'Password must be at least 6 characters.' });
|
|
}
|
|
|
|
if (password !== password_confirm) {
|
|
return res.render('auth/register', { title: 'Register', error: 'Passwords do not match.' });
|
|
}
|
|
|
|
if (Users.findByUsername(username)) {
|
|
return res.render('auth/register', { title: 'Register', error: 'Username is already taken.' });
|
|
}
|
|
|
|
try {
|
|
const userId = Users.create(username, password);
|
|
req.session.userId = userId;
|
|
req.session.username = username;
|
|
req.session.isAdmin = false;
|
|
req.session.isOrganizer = false;
|
|
req.session.flash = { type: 'success', message: 'Account created! Welcome to Loot Hunt.' };
|
|
|
|
const returnTo = req.session.returnTo || '/';
|
|
delete req.session.returnTo;
|
|
res.redirect(returnTo);
|
|
} catch (err) {
|
|
console.error('Registration error:', err);
|
|
res.render('auth/register', { title: 'Register', error: 'Registration failed. Try a different username.' });
|
|
}
|
|
});
|
|
|
|
router.get('/logout', (req, res) => {
|
|
req.session.destroy(() => {
|
|
res.redirect('/');
|
|
});
|
|
});
|
|
|
|
// ─── Password reset (via admin-generated URL) ────────────
|
|
router.get('/reset/:token', (req, res) => {
|
|
const tokenRecord = Users.findByResetToken(req.params.token);
|
|
if (!tokenRecord) {
|
|
return res.render('error', { title: 'Invalid Link', message: 'This password reset link is invalid or has expired.' });
|
|
}
|
|
res.render('auth/reset', { title: 'Reset Password', token: req.params.token, username: tokenRecord.username, error: null });
|
|
});
|
|
|
|
router.post('/reset/:token', (req, res) => {
|
|
const tokenRecord = Users.findByResetToken(req.params.token);
|
|
if (!tokenRecord) {
|
|
return res.render('error', { title: 'Invalid Link', message: 'This password reset link is invalid or has expired.' });
|
|
}
|
|
|
|
const { password, password_confirm } = req.body;
|
|
|
|
if (!password || password.length < 6) {
|
|
return res.render('auth/reset', { title: 'Reset Password', token: req.params.token, username: tokenRecord.username, error: 'Password must be at least 6 characters.' });
|
|
}
|
|
|
|
if (password !== password_confirm) {
|
|
return res.render('auth/reset', { title: 'Reset Password', token: req.params.token, username: tokenRecord.username, error: 'Passwords do not match.' });
|
|
}
|
|
|
|
Users.setPassword(tokenRecord.user_id, password);
|
|
Users.consumeResetToken(req.params.token);
|
|
|
|
// Log the user in
|
|
req.session.userId = tokenRecord.user_id;
|
|
req.session.username = tokenRecord.username;
|
|
req.session.isAdmin = false; // they can re-check on next load
|
|
res.redirect('/');
|
|
});
|
|
|
|
module.exports = router;
|