Files
testRestApi/node/middleware/auth.js
T

47 lines
1.5 KiB
JavaScript

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 };