const bcrypt = require('bcryptjs'); const { User } = require('../models'); function unauthorized(res) { res.set('WWW-Authenticate', 'Basic realm="REST API", charset="UTF-8"'); return res.status(401).json({ success: false, error: { code: 401, message: 'Invalid login or password.' }, }); } async function authenticate(req, res, next) { const header = req.get('authorization') || ''; const match = /^Basic\s+([A-Za-z0-9+/]+={0,2})$/i.exec(header); if (!match) return unauthorized(res); const decoded = Buffer.from(match[1], 'base64').toString('utf8'); const separator = decoded.indexOf(':'); if (separator < 1) return unauthorized(res); const login = decoded.slice(0, separator); const password = decoded.slice(separator + 1); const user = await User.unscoped().findOne({ attributes: ['id', 'login', 'password', 'role', 'active', 'email', 'first_name', 'last_name', 'last_login', 'created', 'modified'], where: { login }, }); if (!user || !user.active) return unauthorized(res); const compatibleHash = user.password.replace(/^\$2y\$/, '$2b$'); if (!(await bcrypt.compare(password, compatibleHash))) return unauthorized(res); req.user = user; next(); } function requireAdmin(req, res, next) { if (req.user.role !== 'admin') { return res.status(403).json({ success: false, error: { code: 403, message: 'This action requires the admin role.' }, }); } next(); } module.exports = { authenticate, requireAdmin };