UNPKG

authorizevi2018

Version:
239 lines (208 loc) 7.04 kB
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 };