UNPKG

@infomaker/service-authorization-lib

Version:

IMID Service Authorization Library

168 lines (147 loc) 5 kB
/* eslint-env node */ 'use-strict' const jwt = require('jsonwebtoken') /** * Module with helper functions for the Tokens. * @module TokenUtils */ /** * Extracts and decodes a service token from a raw request * @function * @param {http.IncomingMessage} request * @returns {Object} serviceToken - The service token */ const extractServiceTokenFromRequest = (request) => { if (request.auth && request.auth.credentials && request.auth.credentials.serviceToken) { return request.auth.credentials.serviceToken } // Get raw request to normalize handling between express and hapi const rawRequest = (request.raw && request.raw.req) ? request.raw.req : request let rawServiceToken = null Object.keys(rawRequest.headers).forEach(header => { if (header.toLowerCase() === 'authorization') { rawServiceToken = rawRequest.headers[header].replace(/bearer /i, '') } }) if (rawServiceToken) { return jwt.decode(rawServiceToken) } throw new Error('Service token not present in request') } /** * Extracts IMID token from a raw request if present * @function * @param {http.IncomingMessage} request * @returns {String|null} imidToken - The IMID token if present */ const extractImidTokenFromRequest = (request) => { if (request.auth && request.auth.credentials && request.auth.credentials.imidToken) { return request.auth.credentials.imidToken } // Get raw request to normalize handling between express and hapi const rawRequest = (request.raw && request.raw.req) ? request.raw.req : request let imidToken = null Object.keys(rawRequest.headers).forEach(header => { if (header.toLowerCase() === 'x-imid-token') { imidToken = rawRequest.headers[header] } }) return imidToken } /** * Get the subject from the service token * @function * @param {http.IncomingMessage} request * @returns {String} organization - The subject identifier set on the service token */ const getSubject = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return serviceToken.sub } /** * Get the subject's organization * @function * @param {http.IncomingMessage} request * @returns {String} organization - The organization the subject belongs to */ const getOrganization = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return serviceToken.org } /** * Get the subject's mapped units * @function * @param {http.IncomingMessage} request * @returns {Array<String>} units - An array of all units the subject belongs to */ const getUnits = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return Object.keys(serviceToken.permissions.units) } /** * Get the subject's selected unit * @function * @param {http.IncomingMessage} request * @returns {(null|String)} unit - The subject's selected unit, null if no unit selected */ const getSelectedUnit = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return serviceToken.unit } /** * Get the subject's organization permissions * * Organization permissions are located under permissions.org * @function * @param {http.IncomingMessage} request * @returns {Array<String>}} permissions - The subject's org permissions */ const getOrgPermissions = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return serviceToken.permissions.org } /** * Get the subject's permissions for the specified unit * * Unit permissions are located under permissions.units[unit] * @function * @param {http.IncomingMessage} request * @param {String} unit - The unit permissions should be checked in * @returns {Array<String>} permissions - The subject's permissions for the specified unit */ const getUnitPermissions = (request, unit) => { const serviceToken = extractServiceTokenFromRequest(request) const unitPermissions = serviceToken.permissions.units[unit] if (!Array.isArray(unitPermissions)) { return [] } const permissions = new Set(serviceToken.permissions.org) unitPermissions.forEach(permission => permissions.add(permission)) return Array.from(permissions) } /** * Checks if a token belogs to an admin for the service * @function * @param {http.IncomingMessage} request * @returns {Boolean} isServiceAdmin - True if the token belongs to an admin for the service */ const isServiceAdmin = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return serviceToken.service_admin === true } /** * Get the subject's userinfo * @function * @param {http.IncomingMessage} request * @returns {Object} userinfo - The userinfo object set on the subject */ const getUserinfo = (request) => { const serviceToken = extractServiceTokenFromRequest(request) return serviceToken.userinfo } module.exports = { extractServiceTokenFromRequest, getSubject, getOrganization, getUnits, getSelectedUnit, getOrgPermissions, getUnitPermissions, isServiceAdmin, getUserinfo, extractImidTokenFromRequest }