notXCS/routes/auth.js

105 lines
3.3 KiB
JavaScript

const express = require('express');
const bcrypt = require('bcryptjs');
const router = express.Router();
let db;
module.exports = (dbInit) => {
db = dbInit;
return router;
};
router.post('/register', (req, res) => {
const { username, password } = req.body || {};
if (!username || !password) {
return res.status(400).json({ success: false, message: "Username and password are required" });
}
if (typeof username !== 'string' || typeof password !== 'string' || username.trim().length < 3 || password.length < 6) {
return res.status(400).json({ success: false, message: "Username must be at least 3 characters and password at least 6 characters" });
}
db.get(`SELECT id FROM users WHERE username = ?`, [username], (err, existing) => {
if (err) {
console.error('Failed to check for existing user:', err.message);
return res.status(500).json({ success: false, message: "Internal server error" });
}
if (existing) {
return res.status(409).json({ success: false, message: "Username is already taken" });
}
bcrypt.hash(password, 10, (err, hash) => {
if (err) {
console.error('Failed to hash password:', err.message);
return res.status(500).json({ success: false, message: "Internal server error" });
}
db.run(`INSERT INTO users (username, password) VALUES (?, ?)`, [username, hash], function (err) {
if (err) {
console.error('Failed to create user:', err.message);
return res.status(500).json({ success: false, message: "Internal server error" });
}
req.session.userId = this.lastID;
req.session.username = username;
res.json({ success: true, user: { id: this.lastID, username } });
});
});
});
});
router.post('/login', (req, res) => {
const { username, password } = req.body || {};
if (!username || !password) {
return res.status(400).json({ success: false, message: "Username and password are required" });
}
db.get(`SELECT * FROM users WHERE username = ?`, [username], (err, user) => {
if (err) {
console.error('Failed to retrieve user:', err.message);
return res.status(500).json({ success: false, message: "Internal server error" });
}
if (!user) {
return res.status(401).json({ success: false, message: "Invalid username or password" });
}
bcrypt.compare(password, user.password, (err, matches) => {
if (err) {
console.error('Failed to verify password:', err.message);
return res.status(500).json({ success: false, message: "Internal server error" });
}
if (!matches) {
return res.status(401).json({ success: false, message: "Invalid username or password" });
}
req.session.userId = user.id;
req.session.username = user.username;
res.json({ success: true, user: { id: user.id, username: user.username } });
});
});
});
router.post('/logout', (req, res) => {
req.session.destroy((err) => {
if (err) {
console.error('Failed to destroy session:', err.message);
return res.status(500).json({ success: false, message: "Internal server error" });
}
res.clearCookie('connect.sid');
res.json({ success: true });
});
});
router.get('/me', (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ success: false, message: "Not authenticated" });
}
res.json({ success: true, user: { id: req.session.userId, username: req.session.username } });
});