@villedemontreal/jwt-validator 5.14.1 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/src/config/configs.d.ts.map +1 -1
- package/dist/src/config/configs.js +3 -2
- package/dist/src/config/configs.js.map +1 -1
- package/dist/src/config/constants.js +1 -1
- package/dist/src/config/constants.js.map +1 -1
- package/dist/src/jwtValidator.d.ts.map +1 -1
- package/dist/src/jwtValidator.js +9 -8
- package/dist/src/jwtValidator.js.map +1 -1
- package/dist/src/jwtValidator.test.js +8 -7
- package/dist/src/jwtValidator.test.js.map +1 -1
- package/dist/src/middleware/jwtMiddleware.test.js +3 -3
- package/dist/src/middleware/jwtMiddleware.test.js.map +1 -1
- package/dist/src/middleware/tokenTransformationMiddleware.js.map +1 -1
- package/dist/src/models/publicKey.d.ts.map +1 -1
- package/dist/src/models/publicKey.js.map +1 -1
- package/dist/src/repositories/cachedPublicKeyRepository.d.ts.map +1 -1
- package/dist/src/repositories/cachedPublicKeyRepository.js +4 -4
- package/dist/src/repositories/cachedPublicKeyRepository.js.map +1 -1
- package/dist/src/userValidator.d.ts.map +1 -1
- package/dist/src/userValidator.js +2 -1
- package/dist/src/userValidator.js.map +1 -1
- package/dist/src/userValidator.test.js +4 -3
- package/dist/src/userValidator.test.js.map +1 -1
- package/dist/src/utils/jwtMock.js +1 -1
- package/dist/src/utils/jwtMock.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -21
- package/src/config/configs.ts +3 -2
- package/src/config/constants.ts +1 -1
- package/src/jwtValidator.test.ts +8 -7
- package/src/jwtValidator.ts +10 -8
- package/src/middleware/jwtMiddleware.test.ts +2 -2
- package/src/middleware/tokenTransformationMiddleware.ts +1 -1
- package/src/models/publicKey.ts +0 -1
- package/src/repositories/cachedPublicKeyRepository.ts +5 -5
- package/src/userValidator.test.ts +5 -4
- package/src/userValidator.ts +2 -1
- package/src/utils/jwtMock.ts +1 -1
package/src/jwtValidator.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/only-throw-error */
|
|
2
|
+
|
|
1
3
|
import { utils } from '@villedemontreal/general-utils';
|
|
2
4
|
import * as jwt from 'jsonwebtoken';
|
|
3
|
-
import
|
|
5
|
+
import { DateTime } from 'luxon';
|
|
4
6
|
import { constants } from './config/constants';
|
|
5
7
|
import { createInvalidAuthHeaderError, createInvalidJwtError } from './models/customError';
|
|
6
8
|
import { IJWTPayload, isJWTPayload } from './models/jwtPayload';
|
|
@@ -123,9 +125,9 @@ class JwtValidator implements IJwtValidator {
|
|
|
123
125
|
|
|
124
126
|
private validateJwtCreationTimestamp(payload: IJWTPayload, key: IPublicKey) {
|
|
125
127
|
// Check the jwt was not created before the creation date of the key
|
|
126
|
-
const payloadIat
|
|
127
|
-
const keyCreatedAt
|
|
128
|
-
if (payloadIat
|
|
128
|
+
const payloadIat = DateTime.fromMillis(payload.iat * 1000).toUTC();
|
|
129
|
+
const keyCreatedAt = DateTime.fromISO(key.createdAt).toUTC();
|
|
130
|
+
if (payloadIat < keyCreatedAt) {
|
|
129
131
|
throw createInvalidJwtError({
|
|
130
132
|
code: constants.errors.codes.INVALID_VALUE,
|
|
131
133
|
target: 'jwt',
|
|
@@ -137,8 +139,8 @@ class JwtValidator implements IJwtValidator {
|
|
|
137
139
|
private validateJwtExpirationTimestamp(payload: IJWTPayload, key: IPublicKey) {
|
|
138
140
|
// Check expiration date
|
|
139
141
|
if (key.expiresAt) {
|
|
140
|
-
const keyexpiresAt
|
|
141
|
-
if (
|
|
142
|
+
const keyexpiresAt = DateTime.fromISO(key.expiresAt).toUTC();
|
|
143
|
+
if (DateTime.utc() > keyexpiresAt) {
|
|
142
144
|
throw createInvalidJwtError({
|
|
143
145
|
code: constants.errors.codes.INVALID_VALUE,
|
|
144
146
|
target: 'jwt',
|
|
@@ -147,8 +149,8 @@ class JwtValidator implements IJwtValidator {
|
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
// Check the jwt was not created after the expiration date of the key
|
|
150
|
-
const payloadIat
|
|
151
|
-
if (payloadIat
|
|
152
|
+
const payloadIat = DateTime.fromMillis(payload.iat * 1000).toUTC();
|
|
153
|
+
if (payloadIat > keyexpiresAt) {
|
|
152
154
|
throw createInvalidJwtError({
|
|
153
155
|
code: constants.errors.codes.INVALID_VALUE,
|
|
154
156
|
target: 'jwt',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as chai from 'chai';
|
|
2
2
|
import { expect } from 'chai';
|
|
3
|
-
import
|
|
3
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
4
4
|
import { Request, Response } from 'express';
|
|
5
5
|
import { createRequest as createRequestMock } from 'node-mocks-http';
|
|
6
6
|
import { SinonSpy, SinonStub, spy, stub } from 'sinon';
|
|
@@ -132,7 +132,7 @@ describe('#jwtValidationMiddleware', () => {
|
|
|
132
132
|
});
|
|
133
133
|
|
|
134
134
|
async function delay(duration: number): Promise<void> {
|
|
135
|
-
return new Promise((resolve
|
|
135
|
+
return new Promise((resolve) => {
|
|
136
136
|
setTimeout(resolve, duration);
|
|
137
137
|
});
|
|
138
138
|
}
|
|
@@ -8,7 +8,7 @@ import { ITokenTtransformationMiddlewareConfig } from '../config/tokenTransforma
|
|
|
8
8
|
import { IInputAccessToken, IInputAccessTokenSource } from '../models/accessToken';
|
|
9
9
|
import { createInvalidJwtError } from '../models/customError';
|
|
10
10
|
import { createLogger } from '../utils/logger';
|
|
11
|
-
import superagent
|
|
11
|
+
import * as superagent from 'superagent';
|
|
12
12
|
|
|
13
13
|
const logger = createLogger('Token transformation middleware');
|
|
14
14
|
|
package/src/models/publicKey.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ApiErrorAndInfo } from '@villedemontreal/general-utils/dist/src';
|
|
2
2
|
import { extend } from 'lodash';
|
|
3
|
-
import
|
|
3
|
+
import { DateTime } from 'luxon';
|
|
4
4
|
import { configs } from '../config/configs';
|
|
5
5
|
import { IPublicKey, IPublicKeys } from '../models/publicKey';
|
|
6
6
|
import { createLogger } from '../utils/logger';
|
|
@@ -21,7 +21,7 @@ export class CachedPublicKeyRepository implements ICachedPublicKeyRepository {
|
|
|
21
21
|
/**
|
|
22
22
|
* Next update
|
|
23
23
|
*/
|
|
24
|
-
private _nextUpdate:
|
|
24
|
+
private _nextUpdate: DateTime;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Cached public keys
|
|
@@ -33,7 +33,7 @@ export class CachedPublicKeyRepository implements ICachedPublicKeyRepository {
|
|
|
33
33
|
*/
|
|
34
34
|
public clearCache(): void {
|
|
35
35
|
this._cachedKeys = {};
|
|
36
|
-
this._nextUpdate =
|
|
36
|
+
this._nextUpdate = DateTime.utc();
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -101,7 +101,7 @@ export class CachedPublicKeyRepository implements ICachedPublicKeyRepository {
|
|
|
101
101
|
* @return {boolean}
|
|
102
102
|
*/
|
|
103
103
|
private isValidCache(): boolean {
|
|
104
|
-
if (!this._nextUpdate ||
|
|
104
|
+
if (!this._nextUpdate || DateTime.utc() >= this._nextUpdate) {
|
|
105
105
|
return false;
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -113,7 +113,7 @@ export class CachedPublicKeyRepository implements ICachedPublicKeyRepository {
|
|
|
113
113
|
* @return
|
|
114
114
|
*/
|
|
115
115
|
private updateNextCacheUpdate(): void {
|
|
116
|
-
this._nextUpdate =
|
|
116
|
+
this._nextUpdate = DateTime.utc().plus({ seconds: configs.getCacheDuration() });
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -9,6 +9,9 @@ import { cachedPublicKeyRepository } from './repositories/cachedPublicKeyReposit
|
|
|
9
9
|
import { UserValidator } from './userValidator';
|
|
10
10
|
import { setTestingConfigurations } from './utils/testingConfigurations';
|
|
11
11
|
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
13
|
+
const mockRequest = require('mock-express-request');
|
|
14
|
+
|
|
12
15
|
// ==========================================
|
|
13
16
|
// Set Testing configurations
|
|
14
17
|
// ==========================================
|
|
@@ -186,8 +189,6 @@ it('User Validator - init app & get jwt public key', async () => {
|
|
|
186
189
|
assert.isTrue(validator.default.isBase64(key));
|
|
187
190
|
});
|
|
188
191
|
|
|
189
|
-
const mockRequest = require('mock-express-request');
|
|
190
|
-
|
|
191
192
|
it('should consider mtlIdentityId field when verifying user', async () => {
|
|
192
193
|
let hasThrown = false;
|
|
193
194
|
|
|
@@ -201,7 +202,7 @@ it('should consider mtlIdentityId field when verifying user', async () => {
|
|
|
201
202
|
|
|
202
203
|
const userValidator: UserValidator = new UserValidator(request);
|
|
203
204
|
userValidator.verifyUser(userId);
|
|
204
|
-
} catch
|
|
205
|
+
} catch {
|
|
205
206
|
hasThrown = true;
|
|
206
207
|
}
|
|
207
208
|
|
|
@@ -222,7 +223,7 @@ it('should throw when either fields are matching', async () => {
|
|
|
222
223
|
|
|
223
224
|
const userValidator: UserValidator = new UserValidator(request);
|
|
224
225
|
userValidator.verifyUser(userId);
|
|
225
|
-
} catch
|
|
226
|
+
} catch {
|
|
226
227
|
hasThrown = true;
|
|
227
228
|
}
|
|
228
229
|
|
package/src/userValidator.ts
CHANGED
|
@@ -33,7 +33,7 @@ export class UserValidator implements IUserValidator {
|
|
|
33
33
|
*/
|
|
34
34
|
public constructor(req: express.Request) {
|
|
35
35
|
if (!isRequestWithJwt(req)) {
|
|
36
|
-
throw new Error(`Expecting a request with a '.jwt' here! : ${req}`);
|
|
36
|
+
throw new Error(`Expecting a request with a '.jwt' here! : ${req.method} ${req.url}`);
|
|
37
37
|
}
|
|
38
38
|
this._request = req;
|
|
39
39
|
}
|
|
@@ -44,6 +44,7 @@ export class UserValidator implements IUserValidator {
|
|
|
44
44
|
|
|
45
45
|
public verifyUser(userId: string) {
|
|
46
46
|
if (this._request.jwt.sub !== userId && this._request.jwt.mtlIdentityId !== userId) {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
47
48
|
throw createInvalidJwtError({
|
|
48
49
|
code: constants.errors.codes.UNAUTHORIZED_ACCESS,
|
|
49
50
|
target: 'jwt',
|
package/src/utils/jwtMock.ts
CHANGED
|
@@ -190,7 +190,7 @@ export class JwtMock {
|
|
|
190
190
|
// Note that we lazy-load the nock module
|
|
191
191
|
// until we really need it, to avoid patching
|
|
192
192
|
// the http module for nothing.
|
|
193
|
-
nock =
|
|
193
|
+
nock = await import('nock');
|
|
194
194
|
}
|
|
195
195
|
nock(configs.getHost(), options).get(pathRegex).once().reply(200, nockListPublicKeys);
|
|
196
196
|
|