authorizevi2018
Version:
ScrollSpy effect for website.
239 lines (208 loc) • 7.04 kB
JavaScript
const httpStatus = require('http-status');
const jsonwebtoken = require('jsonwebtoken');
const APIException = require('./utils/APIException');
/**
* Configuration for user group permission
* @type {Object}
*/
const ConsumerGroups = {
/** Service group with all permissions */
SERVICE: 'service',
/** Staff group with RBAC permissions */
STAFF: 'staff',
/** User group with all permissions if granted */
USER: 'user',
MEMBER: 'member'
};
/**
* Configuration for authentication module
* @type {Object}
*/
const Configs = {
/** Custom header name */
HEADER_NAME: 'Authorization',
/** Include scheme in header */
HEADER_INCLUDE_SCHEME: true,
/** get token rule config */
getTokenRuleConfig: (issuer) => {
const ruleConfigs = {
'auth.quick24.vn/user/web': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhr4KmtA74hlm5SEh5Sxl\nIugsVttXb37Ogu4vFI+SRfOtNZ6BwdY7oi1kuE54IumTr2ViOY+alczjWOyOSXdJ\nbhmRofTmNKvNd1+yeN58tgivsiyayv5NquwsoaRW9wBHWI3dmRykZvevUm0epnyx\nnFY7Hr8ffvbndwMJm0DV2AYVt+tG9VLFMjy2WQyDJUuZwJI9ctHXmNoIsnNHNdnW\nN10mdjv6N3ujPABS0ZIHF38Nat810yviEyt4WuGjqilCCLUs66ToHzrbItFvDByD\nH+HzbmzHU31LoFpwrIZfbgt/UDZdiBsZfzvVnNbasTwlQ+l7UlLQHqppeMjzk9PY\nAQIDAQAB\n-----END PUBLIC KEY-----',
'auth.quick24.vn/user/ios': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhr4KmtA74hlm5SEh5Sxl\nIugsVttXb37Ogu4vFI+SRfOtNZ6BwdY7oi1kuE54IumTr2ViOY+alczjWOyOSXdJ\nbhmRofTmNKvNd1+yeN58tgivsiyayv5NquwsoaRW9wBHWI3dmRykZvevUm0epnyx\nnFY7Hr8ffvbndwMJm0DV2AYVt+tG9VLFMjy2WQyDJUuZwJI9ctHXmNoIsnNHNdnW\nN10mdjv6N3ujPABS0ZIHF38Nat810yviEyt4WuGjqilCCLUs66ToHzrbItFvDByD\nH+HzbmzHU31LoFpwrIZfbgt/UDZdiBsZfzvVnNbasTwlQ+l7UlLQHqppeMjzk9PY\nAQIDAQAB\n-----END PUBLIC KEY-----',
'auth.quick24.vn/user/android': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhr4KmtA74hlm5SEh5Sxl\nIugsVttXb37Ogu4vFI+SRfOtNZ6BwdY7oi1kuE54IumTr2ViOY+alczjWOyOSXdJ\nbhmRofTmNKvNd1+yeN58tgivsiyayv5NquwsoaRW9wBHWI3dmRykZvevUm0epnyx\nnFY7Hr8ffvbndwMJm0DV2AYVt+tG9VLFMjy2WQyDJUuZwJI9ctHXmNoIsnNHNdnW\nN10mdjv6N3ujPABS0ZIHF38Nat810yviEyt4WuGjqilCCLUs66ToHzrbItFvDByD\nH+HzbmzHU31LoFpwrIZfbgt/UDZdiBsZfzvVnNbasTwlQ+l7UlLQHqppeMjzk9PY\nAQIDAQAB\n-----END PUBLIC KEY-----'
};
return ruleConfigs[issuer] ? ruleConfigs[issuer] : null;
},
/** get full permission by user group */
getStaffPermissions: async (userId) => {
/** call to sv permission retrun list permission */
console.log(userId);
return [];
},
/** get full permission denied */
getStaffPermissionDenies: async (userId) => {
console.log(userId);
return [];
}
};
/**
* Get authentication infomation from auth header
*
* @param {*} headerValue
* @returns {Object}
*/
const parseAuthHeader = (headerValue) => {
const HEADER_REGEX = /(\S+)\s+(\S+)/;
if (typeof headerValue !== 'string') return null;
if (Configs.HEADER_INCLUDE_SCHEME) {
const matches = headerValue.match(HEADER_REGEX);
return (
matches && { scheme: matches[1].trim(), value: matches[2].trim() }
);
}
return {
scheme: 'Bearer',
value: headerValue.trim()
};
};
/**
* Get JWT payload from authorization header
*
* @param {Request} req
*/
const getTokenInfo = (req) => {
let jwt = req.get(Configs.HEADER_NAME);
if (!jwt) return null;
jwt = parseAuthHeader(jwt);
if (jwt === null) return null;
jwt.payload = jsonwebtoken.decode(jwt.value, { json: true });
/** verify token valid */
try {
const ruleConfigPubKey = Configs.getTokenRuleConfig(jwt.payload.iss);
jwt.payload = jsonwebtoken.verify(jwt.value, ruleConfigPubKey);
} catch (ex) {
return null;
}
return jwt;
};
/**
* Get User info from jwt payload
*
* @param {Object} jwtPayload
* @returns {Object}
*/
const getUserFromJwtPayload = (jwtPayload) => {
const user = {
id: jwtPayload.id,
name: jwtPayload.name,
phone: jwtPayload.phone,
email: jwtPayload.email,
avatar: jwtPayload.avatar,
group: jwtPayload.group,
username:
jwtPayload.username !== undefined
? jwtPayload.username
: jwtPayload.email
};
return user;
};
/**
* Load token from headers
*
* @param {Request} req
* @param {Response} res
*/
const loadTokenInfo = async (req) => {
let tokenAuth = getTokenInfo(req);
let user = null;
if (tokenAuth === null || !tokenAuth.payload) tokenAuth = null;
else user = getUserFromJwtPayload(tokenAuth.payload);
/** add user on headers */
req.locals = req.locals ? req.locals : {};
req.locals.tokenAuth = tokenAuth;
req.locals.user = user;
};
/**
* Checking Permission From User Group
* @param {Request} req
* @param {Response} res
* @param {Array} permissions
*/
const checkPermission = async (req, permissions) => {
const apiException = new APIException({
message: 'Unauthorized',
status: httpStatus.UNAUTHORIZED,
stack: undefined
});
/** get user from headers */
const user = req.locals.user;
if (!user) {
return apiException;
}
/** setup permission */
const permissionsToCheck = Array.isArray(permissions)
? permissions.slice(0)
: [];
/** allow if require no permission */
if (permissionsToCheck.length === 0) return null;
/** allow if user has permission required */
if (!permissionsToCheck.includes(permissions)) {
return apiException;
}
return null;
};
/**
* Handle JWT token
*
* @param {Request} req
* @param {Response} res
* @param {Function} next
* @param {Array} permissions user-config permission
* @param {Function} additionalCheck additional checking function
*/
const handleJWT = async (
req,
res,
next,
permissions,
additionalCheck = null,
includeCheckPermission = true
) => {
/** load token info from headers */
await loadTokenInfo(req);
/** break checking permission */
if (!includeCheckPermission) return next();
/** checking permission can use request */
const authorizeResult = await checkPermission(req, res, next, permissions, additionalCheck);
if (authorizeResult) return next(authorizeResult);
/** authorized */
return next();
};
/**
* Authenticate middleware with express
*
* @param {Array} permissions
* @param {Function} additionalCheck
* @param {Boolean} includeCheckPermission
*/
const authorize = (permissions, additionalCheck, includeCheckPermission) => (
req,
res,
next
) => handleJWT(
req,
res,
next,
permissions,
additionalCheck,
includeCheckPermission
);
module.exports = {
Configs,
authorize,
getTokenInfo,
loadTokenInfo,
ConsumerGroups,
checkPermission,
// checkStaffPermission,
// checkProviderPermission
};