b23-lib 1.1.1 → 1.2.1

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/index.d.mts CHANGED
@@ -235,22 +235,45 @@ declare const Schema: {
235
235
  };
236
236
  };
237
237
 
238
+ type StringifiedJSONArray = string;
239
+ type AuthUtilityConfig = {
240
+ maxTokenAge?: string;
241
+ userPrivateKeys?: StringifiedJSONArray;
242
+ userPublicKeys?: StringifiedJSONArray;
243
+ anonymousPrivateKeys?: StringifiedJSONArray;
244
+ anonymousPublicKeys?: StringifiedJSONArray;
245
+ systemPrivateKeys?: StringifiedJSONArray;
246
+ systemPublicKeys?: StringifiedJSONArray;
247
+ adminPrivateKeys?: StringifiedJSONArray;
248
+ adminPublicKeys?: StringifiedJSONArray;
249
+ };
250
+ type AuthMiddlewareConfig = {
251
+ allowAnonymous: boolean;
252
+ allowSystem: boolean;
253
+ allowUser: boolean;
254
+ };
238
255
  declare class AuthUtility {
239
- private secretToken;
240
256
  private maxTokenAge;
241
- private anonymousPrivateKey;
242
- private anonymousPublicKey;
243
- constructor({ secret, maxTokenAge, anonymousPrivateKey, anonymousPublicKey }: {
244
- secret?: string;
245
- maxTokenAge?: string;
246
- anonymousPrivateKey?: string;
247
- anonymousPublicKey?: string;
248
- });
257
+ private userPrivateKeys;
258
+ private userPublicKeys;
259
+ private anonymousPrivateKeys;
260
+ private anonymousPublicKeys;
261
+ private systemPrivateKeys;
262
+ private systemPublicKeys;
263
+ private adminPrivateKeys;
264
+ private adminPublicKeys;
265
+ constructor({ maxTokenAge, userPrivateKeys, userPublicKeys, anonymousPrivateKeys, anonymousPublicKeys, systemPrivateKeys, systemPublicKeys, adminPrivateKeys, adminPublicKeys }?: AuthUtilityConfig);
266
+ private createSignedJWT;
267
+ private verifySignedJWT;
249
268
  createAnonymousToken(id: string, additionalData?: object): Promise<string>;
250
269
  verifyAnonymousToken(token: string): Promise<jose.JWTPayload>;
251
- createToken(id: string, additionalData?: object): Promise<string>;
252
- verifyToken(token: string): Promise<jose.JWTPayload>;
253
- AuthMiddleware(allowAnonymous: boolean): (req: any, res: any, next: any) => Promise<void>;
270
+ createUserToken(id: string, additionalData?: object): Promise<string>;
271
+ verifyUserToken(token: string): Promise<jose.JWTPayload>;
272
+ createSystemToken(id: string, additionalData?: object): Promise<string>;
273
+ verifySystemToken(token: string): Promise<jose.JWTPayload>;
274
+ createAdminToken(id: string, additionalData?: object): Promise<string>;
275
+ verifyAdminToken(token: string): Promise<jose.JWTPayload>;
276
+ AuthMiddleware({ allowAnonymous, allowSystem, allowUser }?: AuthMiddlewareConfig): (req: any, res: any, next: any) => Promise<void>;
254
277
  }
255
278
 
256
279
  declare const _default: {
@@ -263,6 +286,21 @@ declare const _default: {
263
286
  };
264
287
  };
265
288
 
289
+ declare const ResponseUtility: {
290
+ handleException: (functionName: string, error: any, res: any) => void;
291
+ generateResponse: (status: number, data?: any, error?: string) => {
292
+ status: number;
293
+ data: any;
294
+ error: string | undefined;
295
+ };
296
+ generateError: (status: number, error: string, knownError?: Boolean, logError?: boolean) => {
297
+ status: number;
298
+ error: string;
299
+ knownError: Boolean;
300
+ logError: boolean;
301
+ };
302
+ };
303
+
266
304
  type SuccessType = {
267
305
  status: number;
268
306
  statusText: string;
@@ -273,8 +311,9 @@ declare const Fetch: (baseURL: string, endpoint: string, method?: "GET" | "POST"
273
311
  declare const Logger: {
274
312
  logException: (functionName: string, error: any) => void;
275
313
  logError: (functionName: string, errorMessage: string) => void;
314
+ logWarning: (functionName: string, message: any) => void;
276
315
  logMessage: (functionName: string, message: any) => void;
277
316
  logInvalidPayload: (functionName: string, errorMessage: string) => void;
278
317
  };
279
318
 
280
- export { AuthUtility as Auth, DynamoDBUtility as DynamoDB, Fetch, Logger, _default as ResponseUtility, Schema, _default as Utils };
319
+ export { AuthUtility as Auth, DynamoDBUtility as DynamoDB, Fetch, Logger, ResponseUtility, Schema, _default as Utils };
package/dist/index.d.ts CHANGED
@@ -235,22 +235,45 @@ declare const Schema: {
235
235
  };
236
236
  };
237
237
 
238
+ type StringifiedJSONArray = string;
239
+ type AuthUtilityConfig = {
240
+ maxTokenAge?: string;
241
+ userPrivateKeys?: StringifiedJSONArray;
242
+ userPublicKeys?: StringifiedJSONArray;
243
+ anonymousPrivateKeys?: StringifiedJSONArray;
244
+ anonymousPublicKeys?: StringifiedJSONArray;
245
+ systemPrivateKeys?: StringifiedJSONArray;
246
+ systemPublicKeys?: StringifiedJSONArray;
247
+ adminPrivateKeys?: StringifiedJSONArray;
248
+ adminPublicKeys?: StringifiedJSONArray;
249
+ };
250
+ type AuthMiddlewareConfig = {
251
+ allowAnonymous: boolean;
252
+ allowSystem: boolean;
253
+ allowUser: boolean;
254
+ };
238
255
  declare class AuthUtility {
239
- private secretToken;
240
256
  private maxTokenAge;
241
- private anonymousPrivateKey;
242
- private anonymousPublicKey;
243
- constructor({ secret, maxTokenAge, anonymousPrivateKey, anonymousPublicKey }: {
244
- secret?: string;
245
- maxTokenAge?: string;
246
- anonymousPrivateKey?: string;
247
- anonymousPublicKey?: string;
248
- });
257
+ private userPrivateKeys;
258
+ private userPublicKeys;
259
+ private anonymousPrivateKeys;
260
+ private anonymousPublicKeys;
261
+ private systemPrivateKeys;
262
+ private systemPublicKeys;
263
+ private adminPrivateKeys;
264
+ private adminPublicKeys;
265
+ constructor({ maxTokenAge, userPrivateKeys, userPublicKeys, anonymousPrivateKeys, anonymousPublicKeys, systemPrivateKeys, systemPublicKeys, adminPrivateKeys, adminPublicKeys }?: AuthUtilityConfig);
266
+ private createSignedJWT;
267
+ private verifySignedJWT;
249
268
  createAnonymousToken(id: string, additionalData?: object): Promise<string>;
250
269
  verifyAnonymousToken(token: string): Promise<jose.JWTPayload>;
251
- createToken(id: string, additionalData?: object): Promise<string>;
252
- verifyToken(token: string): Promise<jose.JWTPayload>;
253
- AuthMiddleware(allowAnonymous: boolean): (req: any, res: any, next: any) => Promise<void>;
270
+ createUserToken(id: string, additionalData?: object): Promise<string>;
271
+ verifyUserToken(token: string): Promise<jose.JWTPayload>;
272
+ createSystemToken(id: string, additionalData?: object): Promise<string>;
273
+ verifySystemToken(token: string): Promise<jose.JWTPayload>;
274
+ createAdminToken(id: string, additionalData?: object): Promise<string>;
275
+ verifyAdminToken(token: string): Promise<jose.JWTPayload>;
276
+ AuthMiddleware({ allowAnonymous, allowSystem, allowUser }?: AuthMiddlewareConfig): (req: any, res: any, next: any) => Promise<void>;
254
277
  }
255
278
 
256
279
  declare const _default: {
@@ -263,6 +286,21 @@ declare const _default: {
263
286
  };
264
287
  };
265
288
 
289
+ declare const ResponseUtility: {
290
+ handleException: (functionName: string, error: any, res: any) => void;
291
+ generateResponse: (status: number, data?: any, error?: string) => {
292
+ status: number;
293
+ data: any;
294
+ error: string | undefined;
295
+ };
296
+ generateError: (status: number, error: string, knownError?: Boolean, logError?: boolean) => {
297
+ status: number;
298
+ error: string;
299
+ knownError: Boolean;
300
+ logError: boolean;
301
+ };
302
+ };
303
+
266
304
  type SuccessType = {
267
305
  status: number;
268
306
  statusText: string;
@@ -273,8 +311,9 @@ declare const Fetch: (baseURL: string, endpoint: string, method?: "GET" | "POST"
273
311
  declare const Logger: {
274
312
  logException: (functionName: string, error: any) => void;
275
313
  logError: (functionName: string, errorMessage: string) => void;
314
+ logWarning: (functionName: string, message: any) => void;
276
315
  logMessage: (functionName: string, message: any) => void;
277
316
  logInvalidPayload: (functionName: string, errorMessage: string) => void;
278
317
  };
279
318
 
280
- export { AuthUtility as Auth, DynamoDBUtility as DynamoDB, Fetch, Logger, _default as ResponseUtility, Schema, _default as Utils };
319
+ export { AuthUtility as Auth, DynamoDBUtility as DynamoDB, Fetch, Logger, ResponseUtility, Schema, _default as Utils };
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ __export(src_exports, {
34
34
  DynamoDB: () => Dynamodb_default,
35
35
  Fetch: () => fetch_default,
36
36
  Logger: () => Logger_default,
37
- ResponseUtility: () => Utils_default,
37
+ ResponseUtility: () => response_default,
38
38
  Schema: () => Schema_default,
39
39
  Utils: () => Utils_default
40
40
  });
@@ -419,7 +419,18 @@ var ErrorTypes_default = Object.freeze({
419
419
  INVALID_TOKEN: "Invalid Token",
420
420
  TOKEN_EXPIRED: "Token Expired",
421
421
  INVALID_AUTH_TYPE: "Invalid Authorization Type",
422
+ USER_PRIVATE_KEY_NOT_FOUND: "User Private Key Not Found",
423
+ USER_PUBLIC_KEY_NOT_FOUND: "User Public Key Not Found",
424
+ ANONYMOUS_PRIVATE_KEY_NOT_FOUND: "Anonymous Private Key Not Found",
425
+ ANONYMOUS_PUBLIC_KEY_NOT_FOUND: "Anonymous Public Key Not Found",
426
+ SYSTEM_PRIVATE_KEY_NOT_FOUND: "System Private Key Not Found",
427
+ SYSTEM_PUBLIC_KEY_NOT_FOUND: "System Public Key Not Found",
428
+ ADMIN_PRIVATE_KEY_NOT_FOUND: "Admin Private Key Not Found",
429
+ ADMIN_PUBLIC_KEY_NOT_FOUND: "Admin Public Key Not Found",
430
+ SECRET_TOKEN_NOT_FOUND: "Secret Token Not Found",
422
431
  ANONYMOUS_SESSION_NOT_ALLOWED: "Anonymous Session Not Allowed",
432
+ USER_SESSION_NOT_ALLOWED: "User Session Not Allowed",
433
+ SYSTEM_SESSION_NOT_ALLOWED: "System Session Not Allowed",
423
434
  INTERNAL_SERVER_ERROR: "Internal Server Error"
424
435
  });
425
436
 
@@ -427,16 +438,19 @@ var ErrorTypes_default = Object.freeze({
427
438
  var import_util = __toESM(require("util"));
428
439
  var Logger = {
429
440
  logException: (functionName, error) => {
430
- console.log(`Exception Occurred in Function: ${functionName}, Error: ${import_util.default.inspect(error)}`);
441
+ console.error(`Exception Occurred in Function: ${functionName}, Error: ${import_util.default.inspect(error)}`);
431
442
  },
432
443
  logError: (functionName, errorMessage) => {
433
- console.log(`Error Occurred in Function: ${functionName}, Error: ${import_util.default.inspect(errorMessage)}`);
444
+ console.error(`Error Occurred in Function: ${functionName}, Error: ${import_util.default.inspect(errorMessage)}`);
445
+ },
446
+ logWarning: (functionName, message) => {
447
+ console.warn(`Warning in Function: ${functionName} - ${import_util.default.inspect(message)}`);
434
448
  },
435
449
  logMessage: (functionName, message) => {
436
- console.log(`Message in Function: ${functionName}, Error: ${import_util.default.inspect(message)}`);
450
+ console.log(`Message in Function: ${functionName} - ${import_util.default.inspect(message)}`);
437
451
  },
438
452
  logInvalidPayload: (functionName, errorMessage) => {
439
- console.log(`Invalid Payload received for Function: ${functionName}, Error: ${errorMessage}`);
453
+ console.error(`Invalid Payload received for Function: ${functionName}, Error: ${errorMessage}`);
440
454
  }
441
455
  };
442
456
  var Logger_default = Logger;
@@ -475,6 +489,12 @@ var ResponseUtility = {
475
489
  status: error.status,
476
490
  error: error.error
477
491
  });
492
+ } else if (error.status && error.error) {
493
+ Logger_default.logException(functionName, error);
494
+ res.status(error.status).json({
495
+ ...error.error,
496
+ status: error.status
497
+ });
478
498
  } else {
479
499
  Logger_default.logException(functionName, error);
480
500
  res.status(500).json({
@@ -503,48 +523,151 @@ var response_default = ResponseUtility;
503
523
 
504
524
  // src/Auth/index.ts
505
525
  var import_assert = __toESM(require("assert"));
526
+ var DefaultAuthUtilityConfig = {
527
+ maxTokenAge: "30 days",
528
+ userPrivateKeys: "[]",
529
+ userPublicKeys: "[]",
530
+ anonymousPrivateKeys: "[]",
531
+ anonymousPublicKeys: "[]",
532
+ systemPrivateKeys: "[]",
533
+ systemPublicKeys: "[]",
534
+ adminPrivateKeys: "[]",
535
+ adminPublicKeys: "[]"
536
+ };
537
+ var DefaultAuthMiddlewareConfig = {
538
+ allowAnonymous: false,
539
+ allowSystem: true,
540
+ allowUser: true
541
+ };
506
542
  var AuthUtility = class {
507
- secretToken;
508
543
  maxTokenAge;
509
- anonymousPrivateKey;
510
- anonymousPublicKey;
511
- constructor({ secret = "", maxTokenAge = "30 days", anonymousPrivateKey = "", anonymousPublicKey = "" }) {
512
- this.secretToken = secret;
544
+ userPrivateKeys;
545
+ userPublicKeys;
546
+ anonymousPrivateKeys;
547
+ anonymousPublicKeys;
548
+ systemPrivateKeys;
549
+ systemPublicKeys;
550
+ adminPrivateKeys;
551
+ adminPublicKeys;
552
+ constructor({ maxTokenAge = "30 days", userPrivateKeys = "[]", userPublicKeys = "[]", anonymousPrivateKeys = "[]", anonymousPublicKeys = "[]", systemPrivateKeys = "[]", systemPublicKeys = "[]", adminPrivateKeys = "[]", adminPublicKeys = "[]" } = DefaultAuthUtilityConfig) {
513
553
  this.maxTokenAge = maxTokenAge;
514
- this.anonymousPrivateKey = anonymousPrivateKey;
515
- this.anonymousPublicKey = anonymousPublicKey;
554
+ this.userPrivateKeys = JSON.parse(userPrivateKeys);
555
+ if (this.userPrivateKeys.length > 3) {
556
+ Logger_default.logWarning("AuthUtility", "More than 1 user private key provided. The last key will be used for signing.");
557
+ }
558
+ this.userPublicKeys = JSON.parse(userPublicKeys);
559
+ if (this.userPublicKeys.length > 3) {
560
+ Logger_default.logWarning("AuthUtility", "More than 3 user public keys provided. This is not recommended.");
561
+ }
562
+ this.anonymousPrivateKeys = JSON.parse(anonymousPrivateKeys);
563
+ if (this.anonymousPrivateKeys.length > 1) {
564
+ Logger_default.logWarning("AuthUtility", "More than 1 anonymous private key provided. The last key will be used for signing.");
565
+ }
566
+ this.anonymousPublicKeys = JSON.parse(anonymousPublicKeys);
567
+ if (this.anonymousPublicKeys.length > 3) {
568
+ Logger_default.logWarning("AuthUtility", "More than 3 anonymous public keys provided. This is not recommended.");
569
+ }
570
+ this.systemPrivateKeys = JSON.parse(systemPrivateKeys);
571
+ if (this.systemPrivateKeys.length > 1) {
572
+ Logger_default.logWarning("AuthUtility", "More than 1 system private key provided. The last key will be used for signing.");
573
+ }
574
+ this.systemPublicKeys = JSON.parse(systemPublicKeys);
575
+ if (this.systemPublicKeys.length > 3) {
576
+ Logger_default.logWarning("AuthUtility", "More than 3 system public keys provided. This is not recommended.");
577
+ }
578
+ this.adminPrivateKeys = JSON.parse(adminPrivateKeys);
579
+ if (this.adminPrivateKeys.length > 1) {
580
+ Logger_default.logWarning("AuthUtility", "More than 1 admin private key provided. The last key will be used for signing.");
581
+ }
582
+ this.adminPublicKeys = JSON.parse(adminPublicKeys);
583
+ if (this.adminPublicKeys.length > 3) {
584
+ Logger_default.logWarning("AuthUtility", "More than 3 admin public keys provided. This is not recommended.");
585
+ }
586
+ }
587
+ async createSignedJWT(payload, privateKeyString, expiration) {
588
+ const privateKey = await (0, import_jose.importPKCS8)(privateKeyString, "RS256");
589
+ const token = await new import_jose.SignJWT(payload).setProtectedHeader({ alg: "RS256" }).setExpirationTime(expiration).setIssuedAt().sign(privateKey);
590
+ return token;
591
+ }
592
+ async verifySignedJWT(token, publicKeyString, expiration) {
593
+ for (let i = publicKeyString.length - 1; i > 0; i--) {
594
+ try {
595
+ const publicKey2 = await (0, import_jose.importSPKI)(publicKeyString[i], "RS256");
596
+ const jwt2 = await (0, import_jose.jwtVerify)(token, publicKey2, { clockTolerance: 30, maxTokenAge: expiration });
597
+ return jwt2.payload;
598
+ } catch (error) {
599
+ continue;
600
+ }
601
+ }
602
+ const publicKey = await (0, import_jose.importSPKI)(publicKeyString[0], "RS256");
603
+ const jwt = await (0, import_jose.jwtVerify)(token, publicKey, { clockTolerance: 30, maxTokenAge: expiration });
604
+ return jwt.payload;
516
605
  }
517
606
  async createAnonymousToken(id, additionalData) {
607
+ (0, import_assert.default)(this.anonymousPrivateKeys.length, ErrorTypes_default.ANONYMOUS_PRIVATE_KEY_NOT_FOUND);
518
608
  (0, import_assert.default)(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
519
609
  const payload = {
520
610
  id,
611
+ type: "Anon",
521
612
  ...additionalData
522
613
  };
523
- const privateKey = await (0, import_jose.importPKCS8)(this.anonymousPrivateKey, "RS256");
524
- const token = await new import_jose.SignJWT(payload).setProtectedHeader({ alg: "RS256" }).setExpirationTime(this.maxTokenAge).setIssuedAt().sign(privateKey);
525
- return token;
614
+ return await this.createSignedJWT(payload, this.anonymousPrivateKeys[this.anonymousPrivateKeys.length - 1], this.maxTokenAge);
526
615
  }
527
616
  async verifyAnonymousToken(token) {
528
- const publicKey = await (0, import_jose.importSPKI)(this.anonymousPublicKey, "RS256");
529
- const jwt = await (0, import_jose.jwtVerify)(token, publicKey, { clockTolerance: 30, maxTokenAge: this.maxTokenAge });
530
- return jwt.payload;
617
+ (0, import_assert.default)(this.anonymousPublicKeys.length, ErrorTypes_default.ANONYMOUS_PUBLIC_KEY_NOT_FOUND);
618
+ const payload = await this.verifySignedJWT(token, this.anonymousPublicKeys, this.maxTokenAge);
619
+ (0, import_assert.default)(payload.type === "Anon", ErrorTypes_default.INVALID_AUTH_TYPE);
620
+ return payload;
531
621
  }
532
- async createToken(id, additionalData) {
622
+ async createUserToken(id, additionalData) {
623
+ (0, import_assert.default)(this.userPrivateKeys.length, ErrorTypes_default.USER_PRIVATE_KEY_NOT_FOUND);
533
624
  (0, import_assert.default)(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
534
625
  const payload = {
535
626
  id,
627
+ type: "User",
536
628
  ...additionalData
537
629
  };
538
- const secretKey = Buffer.from(this.secretToken, "hex");
539
- const token = await new import_jose.EncryptJWT(payload).setExpirationTime(this.maxTokenAge).setIssuedAt().setProtectedHeader({ alg: "dir", enc: "A256CBC-HS512" }).encrypt(secretKey);
540
- return token;
630
+ return await this.createSignedJWT(payload, this.userPrivateKeys[this.userPrivateKeys.length - 1], this.maxTokenAge);
541
631
  }
542
- async verifyToken(token) {
543
- const secretKey = Buffer.from(this.secretToken, "hex");
544
- const jwt = await (0, import_jose.jwtDecrypt)(token, secretKey, { clockTolerance: 30, maxTokenAge: this.maxTokenAge });
545
- return jwt.payload;
632
+ async verifyUserToken(token) {
633
+ (0, import_assert.default)(this.userPublicKeys.length, ErrorTypes_default.USER_PUBLIC_KEY_NOT_FOUND);
634
+ const payload = await this.verifySignedJWT(token, this.userPublicKeys, this.maxTokenAge);
635
+ (0, import_assert.default)(payload.type === "User", ErrorTypes_default.INVALID_AUTH_TYPE);
636
+ return payload;
637
+ }
638
+ async createSystemToken(id, additionalData) {
639
+ (0, import_assert.default)(this.userPrivateKeys.length, ErrorTypes_default.USER_PRIVATE_KEY_NOT_FOUND);
640
+ (0, import_assert.default)(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
641
+ const payload = {
642
+ id,
643
+ type: "System",
644
+ ...additionalData
645
+ };
646
+ return await this.createSignedJWT(payload, this.systemPrivateKeys[this.systemPrivateKeys.length - 1], "5 min");
647
+ }
648
+ async verifySystemToken(token) {
649
+ (0, import_assert.default)(this.systemPublicKeys.length, ErrorTypes_default.USER_PUBLIC_KEY_NOT_FOUND);
650
+ const payload = await this.verifySignedJWT(token, this.systemPublicKeys, "5 min");
651
+ (0, import_assert.default)(payload.type === "System", ErrorTypes_default.INVALID_AUTH_TYPE);
652
+ return payload;
546
653
  }
547
- AuthMiddleware(allowAnonymous) {
654
+ async createAdminToken(id, additionalData) {
655
+ (0, import_assert.default)(this.adminPrivateKeys.length, ErrorTypes_default.ADMIN_PRIVATE_KEY_NOT_FOUND);
656
+ (0, import_assert.default)(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
657
+ const payload = {
658
+ id,
659
+ type: "Admin",
660
+ ...additionalData
661
+ };
662
+ return await this.createSignedJWT(payload, this.adminPrivateKeys[this.adminPrivateKeys.length - 1], this.maxTokenAge);
663
+ }
664
+ async verifyAdminToken(token) {
665
+ (0, import_assert.default)(this.adminPublicKeys.length, ErrorTypes_default.ADMIN_PUBLIC_KEY_NOT_FOUND);
666
+ const payload = await this.verifySignedJWT(token, this.adminPublicKeys, this.maxTokenAge);
667
+ (0, import_assert.default)(payload.type === "Admin", ErrorTypes_default.INVALID_AUTH_TYPE);
668
+ return payload;
669
+ }
670
+ AuthMiddleware({ allowAnonymous, allowSystem, allowUser } = DefaultAuthMiddlewareConfig) {
548
671
  return async (req, res, next) => {
549
672
  try {
550
673
  const [authType, token] = req.get("Authorization")?.split(" ");
@@ -555,17 +678,27 @@ var AuthUtility = class {
555
678
  switch (authType) {
556
679
  case "Anon":
557
680
  if (!allowAnonymous) {
558
- throw response_default.generateError(403, ErrorTypes_default.ANONYMOUS_SESSION_NOT_ALLOWED, true, true);
681
+ throw response_default.generateError(403, ErrorTypes_default.ANONYMOUS_SESSION_NOT_ALLOWED);
559
682
  }
560
683
  payload = await this.verifyAnonymousToken(token);
561
684
  break;
562
685
  case "User":
563
- payload = await this.verifyToken(token);
686
+ if (!allowUser) {
687
+ throw response_default.generateError(403, ErrorTypes_default.USER_SESSION_NOT_ALLOWED);
688
+ }
689
+ payload = await this.verifyUserToken(token);
564
690
  break;
565
691
  case "System":
692
+ if (!allowSystem) {
693
+ throw response_default.generateError(403, ErrorTypes_default.SYSTEM_SESSION_NOT_ALLOWED);
694
+ }
695
+ payload = await this.verifySystemToken(token);
696
+ break;
697
+ case "Admin":
698
+ payload = await this.verifyAdminToken(token);
566
699
  break;
567
700
  default:
568
- throw response_default.generateError(403, ErrorTypes_default.INVALID_AUTH_TYPE, true, true);
701
+ throw response_default.generateError(403, ErrorTypes_default.INVALID_AUTH_TYPE);
569
702
  }
570
703
  res.locals.auth = {
571
704
  authType,
@@ -575,7 +708,7 @@ var AuthUtility = class {
575
708
  next();
576
709
  } catch (error) {
577
710
  Logger_default.logError("AuthMiddleware", import_util2.default.inspect(error));
578
- response_default.handleException("AuthMiddleware", response_default.generateError(401, ErrorTypes_default.TOKEN_EXPIRED), res);
711
+ response_default.handleException("AuthMiddleware", response_default.generateError(401, error.error ? error.error : ErrorTypes_default.TOKEN_EXPIRED, true), res);
579
712
  }
580
713
  };
581
714
  }
package/dist/index.mjs CHANGED
@@ -383,7 +383,7 @@ var Schema = {
383
383
  var Schema_default = Schema;
384
384
 
385
385
  // src/Auth/index.ts
386
- import { EncryptJWT, importPKCS8, importSPKI, jwtDecrypt, jwtVerify, SignJWT } from "jose";
386
+ import { importPKCS8, importSPKI, jwtVerify, SignJWT } from "jose";
387
387
  import util2 from "util";
388
388
 
389
389
  // src/enums/ErrorTypes.ts
@@ -392,7 +392,18 @@ var ErrorTypes_default = Object.freeze({
392
392
  INVALID_TOKEN: "Invalid Token",
393
393
  TOKEN_EXPIRED: "Token Expired",
394
394
  INVALID_AUTH_TYPE: "Invalid Authorization Type",
395
+ USER_PRIVATE_KEY_NOT_FOUND: "User Private Key Not Found",
396
+ USER_PUBLIC_KEY_NOT_FOUND: "User Public Key Not Found",
397
+ ANONYMOUS_PRIVATE_KEY_NOT_FOUND: "Anonymous Private Key Not Found",
398
+ ANONYMOUS_PUBLIC_KEY_NOT_FOUND: "Anonymous Public Key Not Found",
399
+ SYSTEM_PRIVATE_KEY_NOT_FOUND: "System Private Key Not Found",
400
+ SYSTEM_PUBLIC_KEY_NOT_FOUND: "System Public Key Not Found",
401
+ ADMIN_PRIVATE_KEY_NOT_FOUND: "Admin Private Key Not Found",
402
+ ADMIN_PUBLIC_KEY_NOT_FOUND: "Admin Public Key Not Found",
403
+ SECRET_TOKEN_NOT_FOUND: "Secret Token Not Found",
395
404
  ANONYMOUS_SESSION_NOT_ALLOWED: "Anonymous Session Not Allowed",
405
+ USER_SESSION_NOT_ALLOWED: "User Session Not Allowed",
406
+ SYSTEM_SESSION_NOT_ALLOWED: "System Session Not Allowed",
396
407
  INTERNAL_SERVER_ERROR: "Internal Server Error"
397
408
  });
398
409
 
@@ -400,16 +411,19 @@ var ErrorTypes_default = Object.freeze({
400
411
  import util from "util";
401
412
  var Logger = {
402
413
  logException: (functionName, error) => {
403
- console.log(`Exception Occurred in Function: ${functionName}, Error: ${util.inspect(error)}`);
414
+ console.error(`Exception Occurred in Function: ${functionName}, Error: ${util.inspect(error)}`);
404
415
  },
405
416
  logError: (functionName, errorMessage) => {
406
- console.log(`Error Occurred in Function: ${functionName}, Error: ${util.inspect(errorMessage)}`);
417
+ console.error(`Error Occurred in Function: ${functionName}, Error: ${util.inspect(errorMessage)}`);
418
+ },
419
+ logWarning: (functionName, message) => {
420
+ console.warn(`Warning in Function: ${functionName} - ${util.inspect(message)}`);
407
421
  },
408
422
  logMessage: (functionName, message) => {
409
- console.log(`Message in Function: ${functionName}, Error: ${util.inspect(message)}`);
423
+ console.log(`Message in Function: ${functionName} - ${util.inspect(message)}`);
410
424
  },
411
425
  logInvalidPayload: (functionName, errorMessage) => {
412
- console.log(`Invalid Payload received for Function: ${functionName}, Error: ${errorMessage}`);
426
+ console.error(`Invalid Payload received for Function: ${functionName}, Error: ${errorMessage}`);
413
427
  }
414
428
  };
415
429
  var Logger_default = Logger;
@@ -448,6 +462,12 @@ var ResponseUtility = {
448
462
  status: error.status,
449
463
  error: error.error
450
464
  });
465
+ } else if (error.status && error.error) {
466
+ Logger_default.logException(functionName, error);
467
+ res.status(error.status).json({
468
+ ...error.error,
469
+ status: error.status
470
+ });
451
471
  } else {
452
472
  Logger_default.logException(functionName, error);
453
473
  res.status(500).json({
@@ -476,48 +496,151 @@ var response_default = ResponseUtility;
476
496
 
477
497
  // src/Auth/index.ts
478
498
  import assert from "assert";
499
+ var DefaultAuthUtilityConfig = {
500
+ maxTokenAge: "30 days",
501
+ userPrivateKeys: "[]",
502
+ userPublicKeys: "[]",
503
+ anonymousPrivateKeys: "[]",
504
+ anonymousPublicKeys: "[]",
505
+ systemPrivateKeys: "[]",
506
+ systemPublicKeys: "[]",
507
+ adminPrivateKeys: "[]",
508
+ adminPublicKeys: "[]"
509
+ };
510
+ var DefaultAuthMiddlewareConfig = {
511
+ allowAnonymous: false,
512
+ allowSystem: true,
513
+ allowUser: true
514
+ };
479
515
  var AuthUtility = class {
480
- secretToken;
481
516
  maxTokenAge;
482
- anonymousPrivateKey;
483
- anonymousPublicKey;
484
- constructor({ secret = "", maxTokenAge = "30 days", anonymousPrivateKey = "", anonymousPublicKey = "" }) {
485
- this.secretToken = secret;
517
+ userPrivateKeys;
518
+ userPublicKeys;
519
+ anonymousPrivateKeys;
520
+ anonymousPublicKeys;
521
+ systemPrivateKeys;
522
+ systemPublicKeys;
523
+ adminPrivateKeys;
524
+ adminPublicKeys;
525
+ constructor({ maxTokenAge = "30 days", userPrivateKeys = "[]", userPublicKeys = "[]", anonymousPrivateKeys = "[]", anonymousPublicKeys = "[]", systemPrivateKeys = "[]", systemPublicKeys = "[]", adminPrivateKeys = "[]", adminPublicKeys = "[]" } = DefaultAuthUtilityConfig) {
486
526
  this.maxTokenAge = maxTokenAge;
487
- this.anonymousPrivateKey = anonymousPrivateKey;
488
- this.anonymousPublicKey = anonymousPublicKey;
527
+ this.userPrivateKeys = JSON.parse(userPrivateKeys);
528
+ if (this.userPrivateKeys.length > 3) {
529
+ Logger_default.logWarning("AuthUtility", "More than 1 user private key provided. The last key will be used for signing.");
530
+ }
531
+ this.userPublicKeys = JSON.parse(userPublicKeys);
532
+ if (this.userPublicKeys.length > 3) {
533
+ Logger_default.logWarning("AuthUtility", "More than 3 user public keys provided. This is not recommended.");
534
+ }
535
+ this.anonymousPrivateKeys = JSON.parse(anonymousPrivateKeys);
536
+ if (this.anonymousPrivateKeys.length > 1) {
537
+ Logger_default.logWarning("AuthUtility", "More than 1 anonymous private key provided. The last key will be used for signing.");
538
+ }
539
+ this.anonymousPublicKeys = JSON.parse(anonymousPublicKeys);
540
+ if (this.anonymousPublicKeys.length > 3) {
541
+ Logger_default.logWarning("AuthUtility", "More than 3 anonymous public keys provided. This is not recommended.");
542
+ }
543
+ this.systemPrivateKeys = JSON.parse(systemPrivateKeys);
544
+ if (this.systemPrivateKeys.length > 1) {
545
+ Logger_default.logWarning("AuthUtility", "More than 1 system private key provided. The last key will be used for signing.");
546
+ }
547
+ this.systemPublicKeys = JSON.parse(systemPublicKeys);
548
+ if (this.systemPublicKeys.length > 3) {
549
+ Logger_default.logWarning("AuthUtility", "More than 3 system public keys provided. This is not recommended.");
550
+ }
551
+ this.adminPrivateKeys = JSON.parse(adminPrivateKeys);
552
+ if (this.adminPrivateKeys.length > 1) {
553
+ Logger_default.logWarning("AuthUtility", "More than 1 admin private key provided. The last key will be used for signing.");
554
+ }
555
+ this.adminPublicKeys = JSON.parse(adminPublicKeys);
556
+ if (this.adminPublicKeys.length > 3) {
557
+ Logger_default.logWarning("AuthUtility", "More than 3 admin public keys provided. This is not recommended.");
558
+ }
559
+ }
560
+ async createSignedJWT(payload, privateKeyString, expiration) {
561
+ const privateKey = await importPKCS8(privateKeyString, "RS256");
562
+ const token = await new SignJWT(payload).setProtectedHeader({ alg: "RS256" }).setExpirationTime(expiration).setIssuedAt().sign(privateKey);
563
+ return token;
564
+ }
565
+ async verifySignedJWT(token, publicKeyString, expiration) {
566
+ for (let i = publicKeyString.length - 1; i > 0; i--) {
567
+ try {
568
+ const publicKey2 = await importSPKI(publicKeyString[i], "RS256");
569
+ const jwt2 = await jwtVerify(token, publicKey2, { clockTolerance: 30, maxTokenAge: expiration });
570
+ return jwt2.payload;
571
+ } catch (error) {
572
+ continue;
573
+ }
574
+ }
575
+ const publicKey = await importSPKI(publicKeyString[0], "RS256");
576
+ const jwt = await jwtVerify(token, publicKey, { clockTolerance: 30, maxTokenAge: expiration });
577
+ return jwt.payload;
489
578
  }
490
579
  async createAnonymousToken(id, additionalData) {
580
+ assert(this.anonymousPrivateKeys.length, ErrorTypes_default.ANONYMOUS_PRIVATE_KEY_NOT_FOUND);
491
581
  assert(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
492
582
  const payload = {
493
583
  id,
584
+ type: "Anon",
494
585
  ...additionalData
495
586
  };
496
- const privateKey = await importPKCS8(this.anonymousPrivateKey, "RS256");
497
- const token = await new SignJWT(payload).setProtectedHeader({ alg: "RS256" }).setExpirationTime(this.maxTokenAge).setIssuedAt().sign(privateKey);
498
- return token;
587
+ return await this.createSignedJWT(payload, this.anonymousPrivateKeys[this.anonymousPrivateKeys.length - 1], this.maxTokenAge);
499
588
  }
500
589
  async verifyAnonymousToken(token) {
501
- const publicKey = await importSPKI(this.anonymousPublicKey, "RS256");
502
- const jwt = await jwtVerify(token, publicKey, { clockTolerance: 30, maxTokenAge: this.maxTokenAge });
503
- return jwt.payload;
590
+ assert(this.anonymousPublicKeys.length, ErrorTypes_default.ANONYMOUS_PUBLIC_KEY_NOT_FOUND);
591
+ const payload = await this.verifySignedJWT(token, this.anonymousPublicKeys, this.maxTokenAge);
592
+ assert(payload.type === "Anon", ErrorTypes_default.INVALID_AUTH_TYPE);
593
+ return payload;
504
594
  }
505
- async createToken(id, additionalData) {
595
+ async createUserToken(id, additionalData) {
596
+ assert(this.userPrivateKeys.length, ErrorTypes_default.USER_PRIVATE_KEY_NOT_FOUND);
506
597
  assert(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
507
598
  const payload = {
508
599
  id,
600
+ type: "User",
509
601
  ...additionalData
510
602
  };
511
- const secretKey = Buffer.from(this.secretToken, "hex");
512
- const token = await new EncryptJWT(payload).setExpirationTime(this.maxTokenAge).setIssuedAt().setProtectedHeader({ alg: "dir", enc: "A256CBC-HS512" }).encrypt(secretKey);
513
- return token;
603
+ return await this.createSignedJWT(payload, this.userPrivateKeys[this.userPrivateKeys.length - 1], this.maxTokenAge);
514
604
  }
515
- async verifyToken(token) {
516
- const secretKey = Buffer.from(this.secretToken, "hex");
517
- const jwt = await jwtDecrypt(token, secretKey, { clockTolerance: 30, maxTokenAge: this.maxTokenAge });
518
- return jwt.payload;
605
+ async verifyUserToken(token) {
606
+ assert(this.userPublicKeys.length, ErrorTypes_default.USER_PUBLIC_KEY_NOT_FOUND);
607
+ const payload = await this.verifySignedJWT(token, this.userPublicKeys, this.maxTokenAge);
608
+ assert(payload.type === "User", ErrorTypes_default.INVALID_AUTH_TYPE);
609
+ return payload;
610
+ }
611
+ async createSystemToken(id, additionalData) {
612
+ assert(this.userPrivateKeys.length, ErrorTypes_default.USER_PRIVATE_KEY_NOT_FOUND);
613
+ assert(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
614
+ const payload = {
615
+ id,
616
+ type: "System",
617
+ ...additionalData
618
+ };
619
+ return await this.createSignedJWT(payload, this.systemPrivateKeys[this.systemPrivateKeys.length - 1], "5 min");
620
+ }
621
+ async verifySystemToken(token) {
622
+ assert(this.systemPublicKeys.length, ErrorTypes_default.USER_PUBLIC_KEY_NOT_FOUND);
623
+ const payload = await this.verifySignedJWT(token, this.systemPublicKeys, "5 min");
624
+ assert(payload.type === "System", ErrorTypes_default.INVALID_AUTH_TYPE);
625
+ return payload;
519
626
  }
520
- AuthMiddleware(allowAnonymous) {
627
+ async createAdminToken(id, additionalData) {
628
+ assert(this.adminPrivateKeys.length, ErrorTypes_default.ADMIN_PRIVATE_KEY_NOT_FOUND);
629
+ assert(Utils_default.isUUID(id), ErrorTypes_default.INVALID_UUID);
630
+ const payload = {
631
+ id,
632
+ type: "Admin",
633
+ ...additionalData
634
+ };
635
+ return await this.createSignedJWT(payload, this.adminPrivateKeys[this.adminPrivateKeys.length - 1], this.maxTokenAge);
636
+ }
637
+ async verifyAdminToken(token) {
638
+ assert(this.adminPublicKeys.length, ErrorTypes_default.ADMIN_PUBLIC_KEY_NOT_FOUND);
639
+ const payload = await this.verifySignedJWT(token, this.adminPublicKeys, this.maxTokenAge);
640
+ assert(payload.type === "Admin", ErrorTypes_default.INVALID_AUTH_TYPE);
641
+ return payload;
642
+ }
643
+ AuthMiddleware({ allowAnonymous, allowSystem, allowUser } = DefaultAuthMiddlewareConfig) {
521
644
  return async (req, res, next) => {
522
645
  try {
523
646
  const [authType, token] = req.get("Authorization")?.split(" ");
@@ -528,17 +651,27 @@ var AuthUtility = class {
528
651
  switch (authType) {
529
652
  case "Anon":
530
653
  if (!allowAnonymous) {
531
- throw response_default.generateError(403, ErrorTypes_default.ANONYMOUS_SESSION_NOT_ALLOWED, true, true);
654
+ throw response_default.generateError(403, ErrorTypes_default.ANONYMOUS_SESSION_NOT_ALLOWED);
532
655
  }
533
656
  payload = await this.verifyAnonymousToken(token);
534
657
  break;
535
658
  case "User":
536
- payload = await this.verifyToken(token);
659
+ if (!allowUser) {
660
+ throw response_default.generateError(403, ErrorTypes_default.USER_SESSION_NOT_ALLOWED);
661
+ }
662
+ payload = await this.verifyUserToken(token);
537
663
  break;
538
664
  case "System":
665
+ if (!allowSystem) {
666
+ throw response_default.generateError(403, ErrorTypes_default.SYSTEM_SESSION_NOT_ALLOWED);
667
+ }
668
+ payload = await this.verifySystemToken(token);
669
+ break;
670
+ case "Admin":
671
+ payload = await this.verifyAdminToken(token);
539
672
  break;
540
673
  default:
541
- throw response_default.generateError(403, ErrorTypes_default.INVALID_AUTH_TYPE, true, true);
674
+ throw response_default.generateError(403, ErrorTypes_default.INVALID_AUTH_TYPE);
542
675
  }
543
676
  res.locals.auth = {
544
677
  authType,
@@ -548,7 +681,7 @@ var AuthUtility = class {
548
681
  next();
549
682
  } catch (error) {
550
683
  Logger_default.logError("AuthMiddleware", util2.inspect(error));
551
- response_default.handleException("AuthMiddleware", response_default.generateError(401, ErrorTypes_default.TOKEN_EXPIRED), res);
684
+ response_default.handleException("AuthMiddleware", response_default.generateError(401, error.error ? error.error : ErrorTypes_default.TOKEN_EXPIRED, true), res);
552
685
  }
553
686
  };
554
687
  }
@@ -605,7 +738,7 @@ export {
605
738
  Dynamodb_default as DynamoDB,
606
739
  fetch_default as Fetch,
607
740
  Logger_default as Logger,
608
- Utils_default as ResponseUtility,
741
+ response_default as ResponseUtility,
609
742
  Schema_default as Schema,
610
743
  Utils_default as Utils
611
744
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "b23-lib",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "description": "This repo hold common classes, type and util functiona",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",