dms-middleware-auth 1.0.9 → 1.1.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/dist/auth.middleware.d.ts +9 -2
- package/dist/auth.middleware.js +64 -17
- package/package.json +1 -1
- package/src/auth.middleware.ts +74 -25
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NestMiddleware } from '@nestjs/common';
|
|
1
|
+
import { NestMiddleware, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import { Response, NextFunction } from 'express';
|
|
3
3
|
import { Cache } from 'cache-manager';
|
|
4
4
|
interface AuthMiddlewareOptions {
|
|
@@ -10,13 +10,18 @@ interface AuthMiddlewareOptions {
|
|
|
10
10
|
clientUuid: string;
|
|
11
11
|
bypassURL: string;
|
|
12
12
|
}
|
|
13
|
-
export declare class AuthMiddleware implements NestMiddleware {
|
|
13
|
+
export declare class AuthMiddleware implements NestMiddleware, OnModuleInit {
|
|
14
14
|
private cacheManager;
|
|
15
15
|
private readonly options;
|
|
16
16
|
private static licenceExpired;
|
|
17
17
|
private static shutdownTimer;
|
|
18
|
+
private static licenceExpiryTimer;
|
|
19
|
+
private static licenceValidatedUntilMs;
|
|
20
|
+
private static licenceValidationPromise;
|
|
21
|
+
private static shutdownInitiated;
|
|
18
22
|
private static readonly licenceExpiredMessage;
|
|
19
23
|
constructor(cacheManager: Cache, options: AuthMiddlewareOptions);
|
|
24
|
+
onModuleInit(): Promise<void>;
|
|
20
25
|
use(req: any, res: Response, next: NextFunction): Promise<void | Response<any, Record<string, any>>>;
|
|
21
26
|
private clientLogin;
|
|
22
27
|
private getUserDetails;
|
|
@@ -25,6 +30,8 @@ export declare class AuthMiddleware implements NestMiddleware {
|
|
|
25
30
|
private getLicencingDetails;
|
|
26
31
|
private validateLicence;
|
|
27
32
|
private markLicenceExpired;
|
|
33
|
+
private scheduleLicenceShutdown;
|
|
34
|
+
private stopServer;
|
|
28
35
|
private normalizeEpochMs;
|
|
29
36
|
private verifyJwt;
|
|
30
37
|
private decodeAccessToken;
|
package/dist/auth.middleware.js
CHANGED
|
@@ -57,18 +57,21 @@ let AuthMiddleware = AuthMiddleware_1 = class AuthMiddleware {
|
|
|
57
57
|
this.cacheManager = cacheManager;
|
|
58
58
|
this.options = options;
|
|
59
59
|
}
|
|
60
|
+
async onModuleInit() {
|
|
61
|
+
const { publicKey, realm } = this.options;
|
|
62
|
+
const isValid = await this.checkLicenceAndValidate(realm, publicKey);
|
|
63
|
+
}
|
|
60
64
|
async use(req, res, next) {
|
|
61
65
|
const { publicKey, clientId, realm, bypassURL } = this.options;
|
|
62
66
|
try {
|
|
63
67
|
if (AuthMiddleware_1.licenceExpired) {
|
|
68
|
+
this.stopServer();
|
|
64
69
|
return res.status(axios_1.HttpStatusCode.Forbidden).json({ message: AuthMiddleware_1.licenceExpiredMessage });
|
|
65
70
|
}
|
|
66
|
-
|
|
67
|
-
const validate_lic = await this.checkLicenceAndValidate(realm, publicKey);
|
|
68
|
-
if (!validate_lic) {
|
|
71
|
+
if (!AuthMiddleware_1.licenceValidatedUntilMs) {
|
|
69
72
|
return res.status(axios_1.HttpStatusCode.Forbidden).json({ message: AuthMiddleware_1.licenceExpiredMessage });
|
|
70
73
|
}
|
|
71
|
-
|
|
74
|
+
if (req.originalUrl == bypassURL) {
|
|
72
75
|
return next();
|
|
73
76
|
}
|
|
74
77
|
const authHeader = req.headers['authorization'];
|
|
@@ -170,26 +173,30 @@ let AuthMiddleware = AuthMiddleware_1 = class AuthMiddleware {
|
|
|
170
173
|
}
|
|
171
174
|
async checkLicenceAndValidate(realm, publicKey) {
|
|
172
175
|
try {
|
|
173
|
-
// Reuse cached licence when possible; short-circuit if already marked expired.
|
|
174
176
|
if (AuthMiddleware_1.licenceExpired) {
|
|
175
177
|
return false;
|
|
176
178
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
if (AuthMiddleware_1.licenceValidatedUntilMs && AuthMiddleware_1.licenceValidatedUntilMs > Date.now()) {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
if (AuthMiddleware_1.licenceValidationPromise) {
|
|
183
|
+
return await AuthMiddleware_1.licenceValidationPromise;
|
|
184
|
+
}
|
|
185
|
+
AuthMiddleware_1.licenceValidationPromise = (async () => {
|
|
179
186
|
const response = await this.getLicencingDetails(realm);
|
|
180
187
|
if (response.code === axios_1.HttpStatusCode.InternalServerError) {
|
|
181
188
|
return false;
|
|
182
189
|
}
|
|
183
190
|
else {
|
|
184
191
|
const validate = await this.validateLicence(response.data, publicKey);
|
|
185
|
-
if (validate.status && validate.ttl) {
|
|
186
|
-
await this.cacheManager.set('client_Licence_token', response.data, validate.ttl);
|
|
187
|
-
}
|
|
188
192
|
return validate.status;
|
|
189
193
|
}
|
|
194
|
+
})();
|
|
195
|
+
try {
|
|
196
|
+
return await AuthMiddleware_1.licenceValidationPromise;
|
|
190
197
|
}
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
finally {
|
|
199
|
+
AuthMiddleware_1.licenceValidationPromise = null;
|
|
193
200
|
}
|
|
194
201
|
}
|
|
195
202
|
catch (error) {
|
|
@@ -227,6 +234,7 @@ let AuthMiddleware = AuthMiddleware_1 = class AuthMiddleware {
|
|
|
227
234
|
const licEndMs = this.normalizeEpochMs(token?.lic_end);
|
|
228
235
|
// Reject when licence end (epoch) is missing or already in the past.
|
|
229
236
|
if (!licEndMs) {
|
|
237
|
+
this.markLicenceExpired();
|
|
230
238
|
return {
|
|
231
239
|
status: false
|
|
232
240
|
};
|
|
@@ -238,6 +246,8 @@ let AuthMiddleware = AuthMiddleware_1 = class AuthMiddleware {
|
|
|
238
246
|
};
|
|
239
247
|
}
|
|
240
248
|
else {
|
|
249
|
+
AuthMiddleware_1.licenceValidatedUntilMs = licEndMs;
|
|
250
|
+
this.scheduleLicenceShutdown(licEndMs);
|
|
241
251
|
return {
|
|
242
252
|
status: true,
|
|
243
253
|
ttl: (licEndMs - Date.now()) > 0 ? (licEndMs - Date.now()) : null
|
|
@@ -246,18 +256,51 @@ let AuthMiddleware = AuthMiddleware_1 = class AuthMiddleware {
|
|
|
246
256
|
}
|
|
247
257
|
catch (error) {
|
|
248
258
|
this.markLicenceExpired();
|
|
249
|
-
return
|
|
259
|
+
return {
|
|
260
|
+
status: false
|
|
261
|
+
};
|
|
250
262
|
}
|
|
251
263
|
}
|
|
252
264
|
markLicenceExpired() {
|
|
253
265
|
if (!AuthMiddleware_1.licenceExpired) {
|
|
254
266
|
AuthMiddleware_1.licenceExpired = true;
|
|
255
267
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
268
|
+
// this.stopServer();
|
|
269
|
+
}
|
|
270
|
+
scheduleLicenceShutdown(licEndMs) {
|
|
271
|
+
if (!licEndMs) {
|
|
272
|
+
return;
|
|
260
273
|
}
|
|
274
|
+
const delay = licEndMs - Date.now();
|
|
275
|
+
if (delay <= 0) {
|
|
276
|
+
this.markLicenceExpired();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (AuthMiddleware_1.licenceExpiryTimer) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
AuthMiddleware_1.licenceExpiryTimer = setTimeout(() => {
|
|
283
|
+
this.markLicenceExpired();
|
|
284
|
+
}, delay);
|
|
285
|
+
}
|
|
286
|
+
stopServer() {
|
|
287
|
+
if (AuthMiddleware_1.shutdownInitiated) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
AuthMiddleware_1.shutdownInitiated = true;
|
|
291
|
+
setTimeout(() => {
|
|
292
|
+
try {
|
|
293
|
+
process.kill(process.pid, 'SIGTERM');
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
if (!AuthMiddleware_1.shutdownTimer) {
|
|
299
|
+
AuthMiddleware_1.shutdownTimer = setTimeout(() => {
|
|
300
|
+
process.exit(1);
|
|
301
|
+
}, 5000);
|
|
302
|
+
}
|
|
303
|
+
}, 0);
|
|
261
304
|
}
|
|
262
305
|
normalizeEpochMs(epoch) {
|
|
263
306
|
if (!epoch || Number.isNaN(epoch)) {
|
|
@@ -284,6 +327,10 @@ let AuthMiddleware = AuthMiddleware_1 = class AuthMiddleware {
|
|
|
284
327
|
exports.AuthMiddleware = AuthMiddleware;
|
|
285
328
|
AuthMiddleware.licenceExpired = false;
|
|
286
329
|
AuthMiddleware.shutdownTimer = null;
|
|
330
|
+
AuthMiddleware.licenceExpiryTimer = null;
|
|
331
|
+
AuthMiddleware.licenceValidatedUntilMs = null;
|
|
332
|
+
AuthMiddleware.licenceValidationPromise = null;
|
|
333
|
+
AuthMiddleware.shutdownInitiated = false;
|
|
287
334
|
AuthMiddleware.licenceExpiredMessage = "server Licence is expired!. please renew";
|
|
288
335
|
exports.AuthMiddleware = AuthMiddleware = AuthMiddleware_1 = __decorate([
|
|
289
336
|
(0, common_1.Injectable)(),
|
package/package.json
CHANGED
package/src/auth.middleware.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Inject, Injectable, NestMiddleware } from '@nestjs/common';
|
|
1
|
+
import { Inject, Injectable, NestMiddleware, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import { Response, NextFunction } from 'express';
|
|
3
3
|
import * as jwt from 'jsonwebtoken';
|
|
4
4
|
import axios, { HttpStatusCode } from 'axios';
|
|
@@ -16,9 +16,13 @@ interface AuthMiddlewareOptions {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
@Injectable()
|
|
19
|
-
export class AuthMiddleware implements NestMiddleware {
|
|
19
|
+
export class AuthMiddleware implements NestMiddleware, OnModuleInit {
|
|
20
20
|
private static licenceExpired = false;
|
|
21
21
|
private static shutdownTimer: NodeJS.Timeout | null = null;
|
|
22
|
+
private static licenceExpiryTimer: NodeJS.Timeout | null = null;
|
|
23
|
+
private static licenceValidatedUntilMs: number | null = null;
|
|
24
|
+
private static licenceValidationPromise: Promise<boolean> | null = null;
|
|
25
|
+
private static shutdownInitiated = false;
|
|
22
26
|
private static readonly licenceExpiredMessage = "server Licence is expired!. please renew";
|
|
23
27
|
|
|
24
28
|
constructor(
|
|
@@ -26,6 +30,12 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
26
30
|
@Inject('AUTH_MIDDLEWARE_OPTIONS') private readonly options: AuthMiddlewareOptions
|
|
27
31
|
) {}
|
|
28
32
|
|
|
33
|
+
async onModuleInit() {
|
|
34
|
+
const { publicKey, realm } = this.options;
|
|
35
|
+
const isValid = await this.checkLicenceAndValidate(realm, publicKey);
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
async use(req: any, res: Response, next: NextFunction) {
|
|
30
40
|
|
|
31
41
|
|
|
@@ -33,16 +43,17 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
33
43
|
|
|
34
44
|
try {
|
|
35
45
|
if (AuthMiddleware.licenceExpired) {
|
|
46
|
+
|
|
47
|
+
this.stopServer();
|
|
48
|
+
|
|
36
49
|
return res.status(HttpStatusCode.Forbidden).json({ message: AuthMiddleware.licenceExpiredMessage });
|
|
37
50
|
}
|
|
38
51
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (!validate_lic) {
|
|
42
|
-
return res.status(HttpStatusCode.Forbidden).json({message: AuthMiddleware.licenceExpiredMessage});
|
|
52
|
+
if (!AuthMiddleware.licenceValidatedUntilMs) {
|
|
53
|
+
return res.status(HttpStatusCode.Forbidden).json({ message: AuthMiddleware.licenceExpiredMessage });
|
|
43
54
|
}
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
if (req.originalUrl == bypassURL) {
|
|
56
|
+
return next();
|
|
46
57
|
}
|
|
47
58
|
const authHeader = req.headers['authorization'];
|
|
48
59
|
|
|
@@ -165,27 +176,29 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
165
176
|
|
|
166
177
|
private async checkLicenceAndValidate(realm: string, publicKey:string) {
|
|
167
178
|
try {
|
|
168
|
-
// Reuse cached licence when possible; short-circuit if already marked expired.
|
|
169
179
|
if (AuthMiddleware.licenceExpired) {
|
|
170
180
|
return false;
|
|
171
181
|
}
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
if (AuthMiddleware.licenceValidatedUntilMs && AuthMiddleware.licenceValidatedUntilMs > Date.now()) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
if (AuthMiddleware.licenceValidationPromise) {
|
|
186
|
+
return await AuthMiddleware.licenceValidationPromise;
|
|
187
|
+
}
|
|
188
|
+
AuthMiddleware.licenceValidationPromise = (async () => {
|
|
174
189
|
const response:any = await this.getLicencingDetails(realm);
|
|
175
190
|
if (response.code === HttpStatusCode.InternalServerError) {
|
|
176
191
|
return false
|
|
177
192
|
}
|
|
178
193
|
else{
|
|
179
|
-
const validate
|
|
180
|
-
if (validate.status && validate.ttl) {
|
|
181
|
-
await this.cacheManager.set('client_Licence_token', response.data, validate.ttl);
|
|
182
|
-
}
|
|
183
|
-
|
|
194
|
+
const validate = await this.validateLicence(response.data, publicKey);
|
|
184
195
|
return validate.status;
|
|
185
196
|
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return await
|
|
197
|
+
})();
|
|
198
|
+
try {
|
|
199
|
+
return await AuthMiddleware.licenceValidationPromise;
|
|
200
|
+
} finally {
|
|
201
|
+
AuthMiddleware.licenceValidationPromise = null;
|
|
189
202
|
}
|
|
190
203
|
}
|
|
191
204
|
catch(error:any){
|
|
@@ -228,6 +241,7 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
228
241
|
const licEndMs = this.normalizeEpochMs(token?.lic_end);
|
|
229
242
|
// Reject when licence end (epoch) is missing or already in the past.
|
|
230
243
|
if (!licEndMs) {
|
|
244
|
+
this.markLicenceExpired();
|
|
231
245
|
return{
|
|
232
246
|
status: false
|
|
233
247
|
}
|
|
@@ -238,7 +252,8 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
238
252
|
status: false
|
|
239
253
|
}
|
|
240
254
|
} else {
|
|
241
|
-
|
|
255
|
+
AuthMiddleware.licenceValidatedUntilMs = licEndMs;
|
|
256
|
+
this.scheduleLicenceShutdown(licEndMs);
|
|
242
257
|
return {
|
|
243
258
|
status: true,
|
|
244
259
|
ttl: (licEndMs - Date.now()) > 0 ? (licEndMs - Date.now()) : null
|
|
@@ -247,7 +262,9 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
247
262
|
}
|
|
248
263
|
catch(error:any){
|
|
249
264
|
this.markLicenceExpired();
|
|
250
|
-
return
|
|
265
|
+
return {
|
|
266
|
+
status: false
|
|
267
|
+
};
|
|
251
268
|
}
|
|
252
269
|
}
|
|
253
270
|
|
|
@@ -255,11 +272,43 @@ export class AuthMiddleware implements NestMiddleware {
|
|
|
255
272
|
if (!AuthMiddleware.licenceExpired) {
|
|
256
273
|
AuthMiddleware.licenceExpired = true;
|
|
257
274
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
275
|
+
// this.stopServer();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private scheduleLicenceShutdown(licEndMs: number) {
|
|
279
|
+
if (!licEndMs) {
|
|
280
|
+
return;
|
|
262
281
|
}
|
|
282
|
+
const delay = licEndMs - Date.now();
|
|
283
|
+
if (delay <= 0) {
|
|
284
|
+
this.markLicenceExpired();
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (AuthMiddleware.licenceExpiryTimer) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
AuthMiddleware.licenceExpiryTimer = setTimeout(() => {
|
|
291
|
+
this.markLicenceExpired();
|
|
292
|
+
}, delay);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private stopServer() {
|
|
296
|
+
if (AuthMiddleware.shutdownInitiated) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
AuthMiddleware.shutdownInitiated = true;
|
|
300
|
+
setTimeout(() => {
|
|
301
|
+
try {
|
|
302
|
+
process.kill(process.pid, 'SIGTERM');
|
|
303
|
+
} catch {
|
|
304
|
+
process.exit(1);
|
|
305
|
+
}
|
|
306
|
+
if (!AuthMiddleware.shutdownTimer) {
|
|
307
|
+
AuthMiddleware.shutdownTimer = setTimeout(() => {
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}, 5000);
|
|
310
|
+
}
|
|
311
|
+
}, 0);
|
|
263
312
|
}
|
|
264
313
|
|
|
265
314
|
private normalizeEpochMs(epoch: number): number | null {
|