init
This commit is contained in:
31
src/middlewares/auth.js
Normal file
31
src/middlewares/auth.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const passport = require('passport');
|
||||
const httpStatus = require('http-status');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
const { roleRights } = require('../config/roles');
|
||||
|
||||
const verifyCallback = (req, resolve, reject, requiredRights) => async (err, user, info) => {
|
||||
if (err || info || !user) {
|
||||
return reject(new ApiError(httpStatus.UNAUTHORIZED, 'Please authenticate'));
|
||||
}
|
||||
req.user = user;
|
||||
|
||||
if (requiredRights.length) {
|
||||
const userRights = roleRights.get(user.role);
|
||||
const hasRequiredRights = requiredRights.every((requiredRight) => userRights.includes(requiredRight));
|
||||
if (!hasRequiredRights && req.params.userId !== user.id) {
|
||||
return reject(new ApiError(httpStatus.FORBIDDEN, 'Forbidden'));
|
||||
}
|
||||
}
|
||||
|
||||
resolve();
|
||||
};
|
||||
|
||||
const auth = (...requiredRights) => async (req, res, next) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
passport.authenticate('jwt', { session: false }, verifyCallback(req, resolve, reject, requiredRights))(req, res, next);
|
||||
})
|
||||
.then(() => next())
|
||||
.catch((err) => next(err));
|
||||
};
|
||||
|
||||
module.exports = auth;
|
||||
44
src/middlewares/error.js
Normal file
44
src/middlewares/error.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const mongoose = require('mongoose');
|
||||
const httpStatus = require('http-status');
|
||||
const config = require('../config/config');
|
||||
const logger = require('../config/logger');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
|
||||
const errorConverter = (err, req, res, next) => {
|
||||
let error = err;
|
||||
if (!(error instanceof ApiError)) {
|
||||
const statusCode =
|
||||
error.statusCode || error instanceof mongoose.Error ? httpStatus.BAD_REQUEST : httpStatus.INTERNAL_SERVER_ERROR;
|
||||
const message = error.message || httpStatus[statusCode];
|
||||
error = new ApiError(statusCode, message, false, err.stack);
|
||||
}
|
||||
next(error);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const errorHandler = (err, req, res, next) => {
|
||||
let { statusCode, message } = err;
|
||||
if (config.env === 'production' && !err.isOperational) {
|
||||
statusCode = httpStatus.INTERNAL_SERVER_ERROR;
|
||||
message = httpStatus[httpStatus.INTERNAL_SERVER_ERROR];
|
||||
}
|
||||
|
||||
res.locals.errorMessage = err.message;
|
||||
|
||||
const response = {
|
||||
code: statusCode,
|
||||
message,
|
||||
...(config.env === 'development' && { stack: err.stack }),
|
||||
};
|
||||
|
||||
if (config.env === 'development') {
|
||||
logger.error(err);
|
||||
}
|
||||
|
||||
res.status(statusCode).send(response);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
errorConverter,
|
||||
errorHandler,
|
||||
};
|
||||
11
src/middlewares/rateLimiter.js
Normal file
11
src/middlewares/rateLimiter.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const rateLimit = require('express-rate-limit');
|
||||
|
||||
const authLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 20,
|
||||
skipSuccessfulRequests: true,
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
authLimiter,
|
||||
};
|
||||
21
src/middlewares/validate.js
Normal file
21
src/middlewares/validate.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const Joi = require('joi');
|
||||
const httpStatus = require('http-status');
|
||||
const pick = require('../utils/pick');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
|
||||
const validate = (schema) => (req, res, next) => {
|
||||
const validSchema = pick(schema, ['params', 'query', 'body']);
|
||||
const object = pick(req, Object.keys(validSchema));
|
||||
const { value, error } = Joi.compile(validSchema)
|
||||
.prefs({ errors: { label: 'key' }, abortEarly: false })
|
||||
.validate(object);
|
||||
|
||||
if (error) {
|
||||
const errorMessage = error.details.map((details) => details.message).join(', ');
|
||||
return next(new ApiError(httpStatus.BAD_REQUEST, errorMessage));
|
||||
}
|
||||
Object.assign(req, value);
|
||||
return next();
|
||||
};
|
||||
|
||||
module.exports = validate;
|
||||
Reference in New Issue
Block a user