forked from UKSOURCE/cms.hailearning.edu.vn
239 lines
6.4 KiB
JavaScript
239 lines
6.4 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const User = require('../models/User');
|
|
const crypto = require('crypto');
|
|
const bcrypt = require('bcryptjs');
|
|
|
|
// Login page
|
|
router.get('/login', (req, res) => {
|
|
if (req.session.isAuthenticated) {
|
|
return res.redirect('/admin/dashboard');
|
|
}
|
|
|
|
res.render('auth/login', {
|
|
title: 'Login',
|
|
layout: false
|
|
});
|
|
});
|
|
|
|
// Login handle
|
|
router.post('/login', async (req, res) => {
|
|
const { username, password } = req.body;
|
|
|
|
try {
|
|
// Check database user
|
|
const user = await User.findOne({ username });
|
|
|
|
if (!user) {
|
|
req.flash('error_msg', 'Invalid username or password');
|
|
return res.redirect('/auth/login');
|
|
}
|
|
|
|
const isMatch = await user.comparePassword(password);
|
|
|
|
if (!isMatch) {
|
|
req.flash('error_msg', 'Invalid username or password');
|
|
return res.redirect('/auth/login');
|
|
}
|
|
|
|
// Login success
|
|
req.session.user = {
|
|
id: user._id,
|
|
username: user.username,
|
|
email: user.email,
|
|
name: user.name,
|
|
role: user.role
|
|
};
|
|
req.session.isAuthenticated = true;
|
|
req.flash('success_msg', 'Login successful');
|
|
res.redirect('/admin/dashboard');
|
|
|
|
} catch (err) {
|
|
console.error(err);
|
|
req.flash('error_msg', 'An error occurred during login');
|
|
res.redirect('/auth/login');
|
|
}
|
|
});
|
|
|
|
// Register page
|
|
router.get('/register', (req, res) => {
|
|
if (req.session.isAuthenticated) {
|
|
return res.redirect('/admin/dashboard');
|
|
}
|
|
res.render('auth/register', {
|
|
title: 'Create Account',
|
|
layout: false
|
|
});
|
|
});
|
|
|
|
// Register handle
|
|
router.post('/register', async (req, res) => {
|
|
const { username, email, password, confirm_password, name } = req.body;
|
|
let errors = [];
|
|
|
|
if (!username || !email || !password || !confirm_password || !name) {
|
|
errors.push({ msg: 'Please enter all fields' });
|
|
}
|
|
|
|
if (password !== confirm_password) {
|
|
errors.push({ msg: 'Passwords do not match' });
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
errors.push({ msg: 'Password must be at least 6 characters' });
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
res.render('auth/register', {
|
|
errors,
|
|
username,
|
|
email,
|
|
name,
|
|
title: 'Create Account',
|
|
layout: false
|
|
});
|
|
} else {
|
|
try {
|
|
// Check if user exists
|
|
const existingUser = await User.findOne({ $or: [{ email }, { username }] });
|
|
|
|
if (existingUser) {
|
|
errors.push({ msg: 'Email or Username already exists' });
|
|
return res.render('auth/register', {
|
|
errors,
|
|
username,
|
|
email,
|
|
name,
|
|
title: 'Create Account',
|
|
layout: false
|
|
});
|
|
}
|
|
|
|
const newUser = new User({
|
|
username,
|
|
email,
|
|
name,
|
|
password
|
|
});
|
|
|
|
await newUser.save();
|
|
req.flash('success_msg', 'You are now registered and can log in');
|
|
res.redirect('/auth/login');
|
|
} catch (err) {
|
|
console.error(err);
|
|
errors.push({ msg: 'An error occurred during registration' });
|
|
res.render('auth/register', {
|
|
errors,
|
|
username,
|
|
email,
|
|
name,
|
|
title: 'Create Account',
|
|
layout: false
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// Change Password Page
|
|
router.get('/change-password', (req, res) => {
|
|
res.render('auth/change-password', {
|
|
title: 'Change Password',
|
|
layout: false
|
|
});
|
|
});
|
|
|
|
// Change Password Handle
|
|
router.post('/change-password', async (req, res) => {
|
|
const { email } = req.body;
|
|
try {
|
|
const user = await User.findOne({ email });
|
|
if (!user) {
|
|
req.flash('error_msg', 'No account with that email address exists.');
|
|
return res.redirect('/auth/change-password');
|
|
}
|
|
|
|
const token = crypto.randomBytes(20).toString('hex');
|
|
|
|
user.resetPasswordToken = token;
|
|
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
|
|
|
|
await user.save();
|
|
|
|
// Direct flow as requested: Enter email -> Submit -> Enter new password
|
|
// Redirect directly to the reset password page with the generated token
|
|
res.redirect(`/auth/reset-password/${token}`);
|
|
|
|
} catch (err) {
|
|
console.error(err);
|
|
req.flash('error_msg', 'Error processing request');
|
|
res.redirect('/auth/change-password');
|
|
}
|
|
});
|
|
|
|
// Reset Password Page
|
|
router.get('/reset-password/:token', async (req, res) => {
|
|
try {
|
|
const user = await User.findOne({
|
|
resetPasswordToken: req.params.token,
|
|
resetPasswordExpires: { $gt: Date.now() }
|
|
});
|
|
|
|
if (!user) {
|
|
req.flash('error_msg', 'Password reset token is invalid or has expired.');
|
|
return res.redirect('/auth/change-password');
|
|
}
|
|
|
|
res.render('auth/reset-password', {
|
|
title: 'Reset Password',
|
|
layout: false,
|
|
token: req.params.token
|
|
});
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.redirect('/auth/change-password');
|
|
}
|
|
});
|
|
|
|
// Reset Password Handle
|
|
router.post('/reset-password/:token', async (req, res) => {
|
|
try {
|
|
const user = await User.findOne({
|
|
resetPasswordToken: req.params.token,
|
|
resetPasswordExpires: { $gt: Date.now() }
|
|
});
|
|
|
|
if (!user) {
|
|
req.flash('error_msg', 'Password reset token is invalid or has expired.');
|
|
return res.redirect('/auth/change-password');
|
|
}
|
|
|
|
if (req.body.password !== req.body.confirm_password) {
|
|
req.flash('error_msg', 'Passwords do not match.');
|
|
return res.redirect('back');
|
|
}
|
|
|
|
user.password = req.body.password;
|
|
user.resetPasswordToken = undefined;
|
|
user.resetPasswordExpires = undefined;
|
|
|
|
await user.save();
|
|
|
|
req.flash('success_msg', 'Success! Your password has been changed.');
|
|
res.redirect('/auth/login');
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.redirect('back');
|
|
}
|
|
});
|
|
|
|
router.get('/logout', (req, res) => {
|
|
req.session.destroy((err) => {
|
|
if (err) {
|
|
console.error('Error when logout:', err);
|
|
}
|
|
res.redirect('/');
|
|
});
|
|
});
|
|
|
|
module.exports = router;
|