const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); let db; let JWT_SECRET; function init(database, jwtSecret) { db = database; JWT_SECRET = jwtSecret; } function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) return res.status(401).json({ error: 'Unauthorized' }); jwt.verify(token, JWT_SECRET, (err, user) => { if (err) return res.status(403).json({ error: 'Invalid or expired token' }); req.user = user; next(); }); } function requireAdmin(req, res, next) { if (req.user.role !== 'admin') return res.status(403).json({ error: 'Admin access required' }); next(); } function login(req, res) { const { login, password } = req.body; if (!login || !password) return res.status(400).json({ error: 'Login and password required' }); db.get(`SELECT id, login, password_hash, full_name, email, role FROM users WHERE login = ?`, [login], (err, user) => { if (err) return res.status(500).json({ error: 'Database error' }); if (!user) return res.status(401).json({ error: 'Invalid credentials' }); const match = bcrypt.compareSync(password, user.password_hash); if (!match) return res.status(401).json({ error: 'Invalid credentials' }); const token = jwt.sign({ id: user.id, login: user.login, role: user.role }, JWT_SECRET, { expiresIn: '24h' }); res.json({ token, user: { id: user.id, login: user.login, full_name: user.full_name, email: user.email, role: user.role } }); }); } function updateProfile(req, res) { const { full_name, email } = req.body; db.run(`UPDATE users SET full_name = COALESCE(?, full_name), email = COALESCE(?, email) WHERE id = ?`, [full_name || null, email || null, req.user.id], function(err) { if (err) return res.status(500).json({ error: 'Database error' }); db.get(`SELECT id, login, full_name, email, role FROM users WHERE id = ?`, [req.user.id], (err, row) => { if (err) return res.status(500).json({ error: 'Database error' }); res.json({ message: 'Profile updated', user: row }); }); }); } function changePassword(req, res) { const { current_password, new_password } = req.body; if (!current_password || !new_password) return res.status(400).json({ error: 'Current and new password required' }); if (new_password.length < 4) return res.status(400).json({ error: 'Password must be at least 4 characters' }); db.get(`SELECT password_hash FROM users WHERE id = ?`, [req.user.id], (err, row) => { if (err) return res.status(500).json({ error: 'Database error' }); if (!row) return res.status(404).json({ error: 'User not found' }); const match = bcrypt.compareSync(current_password, row.password_hash); if (!match) return res.status(401).json({ error: 'Current password is incorrect' }); const hash = bcrypt.hashSync(new_password, 10); db.run(`UPDATE users SET password_hash = ? WHERE id = ?`, [hash, req.user.id], (err) => { if (err) return res.status(500).json({ error: 'Database error' }); res.json({ message: 'Password changed successfully' }); }); }); } function setupRoutes(app) { app.post('/api/auth/login', login); app.put('/api/auth/me', authenticateToken, updateProfile); app.post('/api/auth/change-password', authenticateToken, changePassword); } module.exports = { init, setupRoutes, authenticateToken, requireAdmin, login };