@villedemontreal/jwt-validator
Version:
Module to validate JWT (JSON Web Tokens)
502 lines • 26.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const src_1 = require("@villedemontreal/general-utils/dist/src");
const chai_1 = require("chai");
const jwt = require("jsonwebtoken");
const nock = require("nock");
const validator = require("validator");
const configs_1 = require("./config/configs");
const constants_1 = require("./config/constants");
const jwtValidator_1 = require("./jwtValidator");
const expressRequest_1 = require("./models/expressRequest");
const cachedPublicKeyRepository_1 = require("./repositories/cachedPublicKeyRepository");
const jwtMock_1 = require("./utils/jwtMock");
const testingConfigurations_1 = require("./utils/testingConfigurations");
// eslint-disable-next-line @typescript-eslint/no-require-imports
const httpMocks = require('node-mocks-http');
// ==========================================
// Set Testing configurations
// ==========================================
(0, testingConfigurations_1.setTestingConfigurations)();
// ==========================================
// JWT Validator
// ==========================================
let date;
let publicKeys;
function createPathRegex() {
const regExpEscape = (s) => {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
};
return new RegExp(`${regExpEscape(configs_1.configs.getEndpoint())}(.*)`);
}
before('JWT Validator - init app & get jwt public key', async () => {
nock.cleanAll();
// Use mock keys
await jwtMock_1.jwtMock.mockPublicKeys();
publicKeys = await cachedPublicKeyRepository_1.cachedPublicKeyRepository.getAll();
chai_1.assert.match(publicKeys[1].publicKey, /^-----BEGIN PUBLIC KEY-----\n/m);
chai_1.assert.match(publicKeys[1].publicKey, /^-----BEGIN PUBLIC KEY-----\n/m);
chai_1.assert.match(publicKeys[1].publicKey, /\n-----END PUBLIC KEY-----$/m);
const key = publicKeys[1].publicKey
.replace(/^-----BEGIN PUBLIC KEY-----\n/m, '')
.replace(/\n-----END PUBLIC KEY-----$/m, '')
.split('\n')
.join('');
chai_1.assert.isTrue(validator.default.isBase64(key));
});
it('JWT Validator - verifyHeader - should reject null header', async () => {
const response = await jwtValidator_1.jwtValidator.verifyAuthorizationHeader(null).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_AUTHORIZATION_HEADER);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid Authorization header');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.NULL_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'Authorization header');
chai_1.assert.strictEqual(err.error.details[0].message, 'Empty Authorization header');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verifyHeader - should reject empty header', async () => {
const response = await jwtValidator_1.jwtValidator.verifyAuthorizationHeader('').catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_AUTHORIZATION_HEADER);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid Authorization header');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.NULL_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'Authorization header');
chai_1.assert.strictEqual(err.error.details[0].message, 'Empty Authorization header');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verifyHeader - should reject unknow authentication scheme', async () => {
const response = await jwtValidator_1.jwtValidator.verifyAuthorizationHeader('Unknow JWT').catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_AUTHORIZATION_HEADER);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid Authorization header');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'Authorization header');
chai_1.assert.strictEqual(err.error.details[0].message, 'Bad authentication scheme, "Bearer" required');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verifyHeader - should reject bad token', async () => {
const response = await jwtValidator_1.jwtValidator.verifyAuthorizationHeader('Bearer JWT').catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt malformed');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verifyHeader - should accept good token', async () => {
date = new Date(publicKeys[5].createdAt);
date.setHours(date.getHours() + 24);
const payload = {
accessToken: 'c9ba5a95-d7f9-41f9-9a24-a7e41882f7ef',
iss: 'Issuer',
inum: 'MyInum',
iat: date.getTime() / 1000,
exp: date.getTime() / 1000 + 3600,
sub: '@!4025.CA62.9BB6.16C5!0001!2212.0010!0000!0000.0001',
keyId: 5,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyAuthorizationHeader(`Bearer ${token}`);
chai_1.assert.deepEqual(response, payload);
});
it('JWT Validator - verify - should reject bad token', async () => {
const response = await jwtValidator_1.jwtValidator.verifyToken('JWT').catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt malformed');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid token: missing signature', async () => {
let token = '';
token += Buffer.from('{}', 'base64').toString();
token += '.';
token += Buffer.from('{}', 'base64').toString();
token += '.';
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt malformed');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid token: empty JSON', async () => {
let token = '';
token += Buffer.from('{}', 'base64').toString();
token += '.';
token += Buffer.from('{}', 'base64').toString();
token += '.';
token += 'TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ';
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt malformed');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid token: missing public key ID', async () => {
const token = jwt.sign('{"a":"a"}', 'key', { algorithm: 'HS256' });
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'missing public key ID');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid token: keyId is no longer active', async () => {
const token = jwt.sign('{"a":"a", "keyId": "1"}', 'key', { algorithm: 'HS256' });
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'this keyId is no longer active');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid token: keyId not found', async () => {
const pathRegex = createPathRegex();
// Intercept request
nock(configs_1.configs.getHost()).get(pathRegex).reply(404);
const token = jwt.sign('{"a":"a", "keyId": "25"}', 'key', { algorithm: 'HS256' });
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'this keyId is no longer active');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid algorithm: bad signature', async () => {
let token = '';
token += Buffer.from('{"alg":"HS256","typ":"JWT"}', 'base64').toString();
token += '.';
token += Buffer.from('{"a":"a", "keyId": 5}', 'base64').toString();
token += '.';
token += 'TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ';
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt malformed');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject invalid algorithm: bad signature (algorithm)', async () => {
const token = jwt.sign('{"a":"a", "keyId": 5}', 'key', { algorithm: 'HS256' });
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'invalid algorithm');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject expired token', async () => {
date = new Date(publicKeys[5].createdAt);
date.setHours(date.getHours() + 24);
const payload = {
b: 'b',
iat: date.getTime() / 1000,
exp: 1,
keyId: 5,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt expired');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject expired public key', async () => {
const payload = {
b: 'b',
keyId: 2,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'this keyId is expired');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject expired public key (by state)', async () => {
const payload = {
b: 'b',
keyId: 1,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'this keyId is no longer active');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject revoked public key', async () => {
const payload = {
b: 'b',
keyId: 3,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'this keyId is no longer active');
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject jwt created after the expiration date of the key', async () => {
date = new Date(publicKeys[4].expiresAt);
date.setHours(date.getHours() + 24);
const payload = {
b: 'b',
iat: date.getTime() / 1000,
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, "this jwt can't be created after the expiration of the public key");
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should reject jwt created before the creation date of the key', async () => {
date = new Date(publicKeys[4].createdAt);
date.setHours(date.getHours() - 48);
const payload = {
b: 'b',
iat: date.getTime() / 1000,
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, "this jwt can't be created before the public key");
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - verify - should accept good token', async () => {
date = new Date();
const payload = {
accessToken: 'c9ba5a95-d7f9-41f9-9a24-a7e41882f7ef',
iss: 'Issuer',
inum: 'MyInum',
iat: date.getTime() / 1000,
exp: date.getTime() / 1000 + 3600,
sub: '@!4025.CA62.9BB6.16C5!0001!2212.0010!0000!0000.0001',
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token);
chai_1.assert.deepEqual(response, payload);
});
it('isRequestWithJwt', async () => {
const req = httpMocks.createRequest({ method: 'GET', url: '/' });
chai_1.assert.isFalse((0, expressRequest_1.isRequestWithJwt)(req));
req[constants_1.constants.requestExtraVariables.JWT] = 'Bonjour la police';
chai_1.assert.isTrue((0, expressRequest_1.isRequestWithJwt)(req));
});
it('JWT Validator - unable to get public key', async () => {
const pathRegex = createPathRegex();
// Intercept request
nock(configs_1.configs.getHost()).get(pathRegex).reply(500);
const token = jwt.sign('{"a":"a", "keyId": "25"}', 'key', { algorithm: 'HS256' });
const response = await jwtValidator_1.jwtValidator.verifyToken(token).catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.UNABLE_TO_GET_PUBLIC_KEY);
chai_1.assert.strictEqual(err.httpStatus, 500);
});
chai_1.assert.isUndefined(response);
});
it('JWT Validator - network error - should accept good token if cached', async function () {
this.timeout(70000); // Timeout should be longer on Windows
// Invalidate cache
const currentNextUpdate = cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate;
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = undefined;
const pathRegex = createPathRegex();
// Intercept request
nock(configs_1.configs.getHost()).get(pathRegex).replyWithError({ code: 'ABORTED' });
date = new Date();
const payload = {
accessToken: 'c9ba5a95-d7f9-41f9-9a24-a7e41882f7ef',
iss: 'Issuer',
inum: 'MyInum',
iat: date.getTime() / 1000,
exp: date.getTime() / 1000 + 3600,
sub: '@!4025.CA62.9BB6.16C5!0001!2212.0010!0000!0000.0001',
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token);
chai_1.assert.deepEqual(response, payload);
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = currentNextUpdate;
});
it('JWT Validator - 500 error from api - should accept good token if cached', async () => {
// Invalidate cache
const currentNextUpdate = cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate;
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = undefined;
const pathRegex = createPathRegex();
// Error from api
// Intercept request
nock(configs_1.configs.getHost())
.get(pathRegex)
.reply(500, (0, src_1.createServerError)('Error while sending request'));
date = new Date();
const payload = {
accessToken: 'c9ba5a95-d7f9-41f9-9a24-a7e41882f7ef',
iss: 'Issuer',
inum: 'MyInum',
iat: date.getTime() / 1000,
exp: date.getTime() / 1000 + 3600,
sub: '@!4025.CA62.9BB6.16C5!0001!2212.0010!0000!0000.0001',
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token);
chai_1.assert.deepEqual(response, payload);
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = currentNextUpdate;
});
it('JWT Validator - 429 error from api - should accept good token if cached', async () => {
// Invalidate cache
const currentNextUpdate = cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate;
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = undefined;
const pathRegex = createPathRegex();
// Error from api
// Intercept request
nock(configs_1.configs.getHost()).get(pathRegex).reply(429);
date = new Date();
const payload = {
accessToken: 'c9ba5a95-d7f9-41f9-9a24-a7e41882f7ef',
iss: 'Issuer',
inum: 'MyInum',
iat: date.getTime() / 1000,
exp: date.getTime() / 1000 + 3600,
sub: '@!4025.CA62.9BB6.16C5!0001!2212.0010!0000!0000.0001',
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
const response = await jwtValidator_1.jwtValidator.verifyToken(token);
chai_1.assert.deepEqual(response, payload);
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = currentNextUpdate;
});
it('JWT Validator - 400 error from api - should reject', async () => {
// Invalidate cache
const currentNextUpdate = cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate;
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = undefined;
const pathRegex = createPathRegex();
// Error from api
// Intercept request
nock(configs_1.configs.getHost())
.get(pathRegex)
.reply(400, (0, src_1.createInvalidParameterError)('Something is wrong'));
date = new Date();
const payload = {
accessToken: 'c9ba5a95-d7f9-41f9-9a24-a7e41882f7ef',
iss: 'Issuer',
inum: 'MyInum',
iat: date.getTime() / 1000,
exp: date.getTime() / 1000 + 3600,
sub: '@!4025.CA62.9BB6.16C5!0001!2212.0010!0000!0000.0001',
keyId: 4,
};
const token = jwt.sign(JSON.stringify(payload), jwtMock_1.jwtMock.getPrivateKey(), {
algorithm: 'RS256',
});
let error;
try {
await jwtValidator_1.jwtValidator.verifyToken(token);
}
catch (e) {
error = e;
}
chai_1.assert.isDefined(error);
chai_1.assert.instanceOf(error, src_1.ApiErrorAndInfo);
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = currentNextUpdate;
});
it('JWT Validator - network error - should reject bad token anyway', async () => {
// Invalidate cache
const currentNextUpdate = cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate;
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = undefined;
const pathRegex = createPathRegex();
// Intercept request
nock(configs_1.configs.getHost()).get(pathRegex).replyWithError({ code: 'ABORTED' });
const response = await jwtValidator_1.jwtValidator.verifyToken('JWT').catch((err) => {
chai_1.assert.strictEqual(err.error.code, constants_1.constants.errors.codes.INVALID_JWT);
chai_1.assert.strictEqual(err.error.target, 'Authorization header');
chai_1.assert.strictEqual(err.error.message, 'Invalid JWT');
chai_1.assert.strictEqual(err.error.details[0].code, constants_1.constants.errors.codes.INVALID_VALUE);
chai_1.assert.strictEqual(err.error.details[0].target, 'jwt');
chai_1.assert.strictEqual(err.error.details[0].message, 'jwt malformed');
});
chai_1.assert.isUndefined(response);
cachedPublicKeyRepository_1.cachedPublicKeyRepository._nextUpdate = currentNextUpdate;
});
//# sourceMappingURL=jwtValidator.test.js.map