@infomaker/service-authorization-lib
Version:
IMID Service Authorization Library
189 lines (169 loc) • 5.51 kB
JavaScript
/*eslint-env node, jasmine */
'use strict'
const jwt = require('jsonwebtoken')
const authLib = require('./../src/index')
const testData = require('./lib/test-data')
const sharedTests = require('./lib/shared-tests')
const MockRequest = require('./lib/express-mock/request')
const MockResponse = require('./lib/express-mock/response')
const MockNext = require('./lib/express-mock/next')
const ServiceAuthorizationMiddleware = authLib.expressMiddleware
/**
* Tests specific to Express
*/
describe('Express specific tests', () => {
it('authorize should pass on errors to next', async () => {
const expectedError = new Error('test-error')
const serviceToken = jwt.sign(testData.VALID_SERVICE_TOKEN_PAYLOAD_A, testData.VALID_SERVICE_TOKEN_SIGN_SECRET, {expiresIn: '1h'})
const middleware = new ServiceAuthorizationMiddleware({serviceTokenSignSecret: testData.VALID_SERVICE_TOKEN_SIGN_SECRET})
const mockRequest = new MockRequest({serviceToken})
const mockResponse = new MockResponse()
const mockNext = () => { throw expectedError }
const authorizeFunc = middleware.authorize({})
expect.assertions(1)
try {
await authorizeFunc(mockRequest, mockResponse, mockNext)
} catch (err) {
expect({err}).toEqual({err: expectedError})
}
})
})
/**
* Setup shared tests
*/
const expectFunctionRunner = async ({authParams, noServiceToken=false, serviceToken, serviceTokenPayload, expectFunc, expectFuncParams={}}) => {
if (typeof serviceToken === 'undefined') {
if (typeof serviceTokenPayload === 'undefined') {
serviceTokenPayload = testData.VALID_SERVICE_TOKEN_PAYLOAD_A
}
serviceToken = jwt.sign(serviceTokenPayload, testData.VALID_SERVICE_TOKEN_SIGN_SECRET, {expiresIn: '1h'})
}
const middleware = new ServiceAuthorizationMiddleware({
serviceTokenSignSecret: testData.VALID_SERVICE_TOKEN_SIGN_SECRET
})
const params = {
serviceToken
}
if (noServiceToken) {
delete params.serviceToken
} else {
expectFuncParams.serviceTokenPayload = serviceTokenPayload
}
const mockRequest = new MockRequest(params)
const mockResponse = new MockResponse()
const mockNext = MockNext({requestReference: mockRequest})
try {
const authorizeFunc = middleware.authorize(authParams) // => middleware
await authorizeFunc(mockRequest, mockResponse, mockNext)
} catch (err) {
expect({err}).toEqual(null)
}
// If next has been called, pass on to error handler
if (mockRequest.internals.nextCalled) {
mockRequest.internals.nextCalled = false
ServiceAuthorizationMiddleware.errorHandler(mockRequest.internals.err, mockRequest, mockResponse, mockNext)
}
return expectFunc(mockRequest, mockResponse, expectFuncParams)
}
const expectValidationError = (req, res, params) => {
// Done!
const err = req.internals.err
expect({
nextCalled: req.internals.nextCalled,
statusCode: err.httpCode,
errorMessage: err.message,
internalErrorMessage: err.internalData.msg
}).toEqual({
nextCalled: true,
statusCode: 500,
errorMessage: 'Internal Server Error',
internalErrorMessage: params.internalErrorMessage
})
}
const expectAuthError = (req, res, params) => {
const err = req.internals.err
let expectedCredentials = null
if (!params.noCredentials) {
expectedCredentials = {
serviceToken: Object.assign({}, params.serviceTokenPayload, {
iat: expect.any(Number),
exp: expect.any(Number)
})
}
}
expect({
credentials: req.auth.credentials,
nextCalled: req.internals.nextCalled,
errorMessage: err.publicMessage,
errorId: err.errorId,
statusCode: err.httpCode
}).toEqual({
credentials: expectedCredentials,
nextCalled: true,
errorMessage: params.errorMessage,
errorId: expect.any(String),
statusCode: params.statusCode
})
}
const expectLoginToBeTriggered = (req, res, params) => {
const err = req.internals.err
expect({
nextCalled: req.internals.nextCalled,
errorMessage: err.publicMessage,
statusCode: res.statusCode,
headers: res.headers
}).toEqual({
nextCalled: false,
errorMessage: params.errorMessage,
statusCode: params.statusCode,
headers: {'x-imid-login-redirect-organization': testData.ORG_B}
})
}
const expectSystemError = (req, res, params) => {
const err = req.internals.err
expect({
nextCalled: req.internals.nextCalled,
statusCode: err.httpCode,
errorMessage: err.message,
internalError: err.internalData.originalError
}).toEqual({
nextCalled: true,
statusCode: 500,
errorMessage: 'Internal Server Error',
internalError: params.internalError
})
}
const expectCredentialsToBeAddedToRequest = (req, res, params) => {
expect({
nextCalled: req.internals.nextCalled,
credentials: req.auth.credentials,
artifacts: req.auth.artifacts,
error: req.internals.err,
errorStack: req.internals.err ? req.internals.err.stack : null
}).toEqual({
nextCalled: true,
credentials: params.credentials,
artifacts: params.artifacts,
error: null,
errorStack: null
})
}
const expectModifiedRequest = (req, res, params) => {
expect({
'request.temp': req.temp
}).toEqual({
'request.temp': params.expectedRequestString
})
}
/**
* Shared tests
*/
sharedTests({
expectFunctionRunner,
expectValidationError,
expectAuthError,
expectLoginToBeTriggered,
expectSystemError,
expectCredentialsToBeAddedToRequest,
expectModifiedRequest
})