@konplit-services/common 1.9.0 → 1.10.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.
@@ -4,3 +4,5 @@ export * from "./permission-created.interface";
4
4
  export * from "./permission-removed.interface";
5
5
  export * from "./user-created.interface";
6
6
  export * from "./user-updated.interface";
7
+ export * from "./twofa-created.interface";
8
+ export * from "./twofa-updated.interface";
@@ -20,3 +20,5 @@ __exportStar(require("./permission-created.interface"), exports);
20
20
  __exportStar(require("./permission-removed.interface"), exports);
21
21
  __exportStar(require("./user-created.interface"), exports);
22
22
  __exportStar(require("./user-updated.interface"), exports);
23
+ __exportStar(require("./twofa-created.interface"), exports);
24
+ __exportStar(require("./twofa-updated.interface"), exports);
@@ -0,0 +1,16 @@
1
+ import { TwoFAType } from "../../../helper";
2
+ import { StreamEvent, StreamName, Subjects } from "../../subjects";
3
+ export interface TWOFACreatedEvent {
4
+ subject: Subjects.TwoFACreated;
5
+ streamName: StreamName.name;
6
+ streamEvents: StreamEvent.Event;
7
+ data: {
8
+ id: string;
9
+ accountId?: string;
10
+ userId: string;
11
+ isTwoFactor?: boolean;
12
+ twoFactorType?: TwoFAType;
13
+ twoFactorSecret?: string;
14
+ version?: number;
15
+ };
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,16 @@
1
+ import { TwoFAType } from "../../../helper";
2
+ import { StreamEvent, StreamName, Subjects } from "../../subjects";
3
+ export interface TWOFAUpdatedEvent {
4
+ subject: Subjects.TwoFAUpdated;
5
+ streamName: StreamName.name;
6
+ streamEvents: StreamEvent.Event;
7
+ data: {
8
+ id: string;
9
+ accountId?: string;
10
+ userId: string;
11
+ isTwoFactor?: boolean;
12
+ twoFactorType?: TwoFAType;
13
+ twoFactorSecret?: string;
14
+ version?: number;
15
+ };
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,6 +7,8 @@ export declare enum StreamName {
7
7
  export declare enum Subjects {
8
8
  AccountCreated = "events.account.created",
9
9
  AccountUpdated = "events.account.updated",
10
+ TwoFACreated = "events.two.fa.created",
11
+ TwoFAUpdated = "events.two.fa.updated",
10
12
  UserCreated = "events.user.created",
11
13
  UserUpdated = "events.user.updated",
12
14
  MerchantCreated = "events.merchant.created",
@@ -14,6 +14,8 @@ var Subjects;
14
14
  // Accounts Subjects
15
15
  Subjects["AccountCreated"] = "events.account.created";
16
16
  Subjects["AccountUpdated"] = "events.account.updated";
17
+ Subjects["TwoFACreated"] = "events.two.fa.created";
18
+ Subjects["TwoFAUpdated"] = "events.two.fa.updated";
17
19
  //users
18
20
  Subjects["UserCreated"] = "events.user.created";
19
21
  Subjects["UserUpdated"] = "events.user.updated";
@@ -53,3 +53,4 @@ export * from "./subaccount";
53
53
  export * from "./remove-query-properties";
54
54
  export * from "./ussd";
55
55
  export * from "./phone-validator";
56
+ export * from "./token-validation";
@@ -71,3 +71,4 @@ __exportStar(require("./remove-query-properties"), exports);
71
71
  __exportStar(require("./ussd"), exports);
72
72
  //validation
73
73
  __exportStar(require("./phone-validator"), exports);
74
+ __exportStar(require("./token-validation"), exports);
@@ -42,10 +42,5 @@ export declare const subtractMoney: (a: ReturnType<typeof dinero>, b: ReturnType
42
42
  */
43
43
  export declare const multiplyMoney: (a: ReturnType<typeof dinero>, factor: number) => import("dinero.js").Dinero<number>;
44
44
  export declare const divideMoney: (money: ReturnType<typeof dinero>, divisor: number) => import("dinero.js").Dinero<number>;
45
- /**
46
- * Convert a decimal string or number (₦) to minor units (kobo).
47
- * Example: "4543.367487363" → 454337n (₦4543.37)
48
- * Example: 4543.37 → 454337n
49
- */
50
- export declare const toSmalletUnit: (value: string | number, exponent?: number) => bigint;
45
+ export declare const toSmalletUnit: (naira: number | string) => number;
51
46
  export {};
@@ -87,17 +87,10 @@ const divideMoney = (money, divisor) => {
87
87
  return (0, exports.createMoney)(result);
88
88
  };
89
89
  exports.divideMoney = divideMoney;
90
- /**
91
- * Convert a decimal string or number (₦) to minor units (kobo).
92
- * Example: "4543.367487363" → 454337n (₦4543.37)
93
- * Example: 4543.37 → 454337n
94
- */
95
- const toSmalletUnit = (value, exponent = 2) => {
96
- const strValue = value.toString();
97
- const [integer, fraction = ""] = strValue.split(".");
98
- const paddedFraction = (fraction + "0".repeat(exponent)).slice(0, exponent);
99
- const minorStr = integer + paddedFraction;
100
- return BigInt(minorStr);
90
+ const toSmalletUnit = (naira) => {
91
+ if (typeof naira === "string") {
92
+ naira = parseFloat(naira);
93
+ }
94
+ return Math.round(naira * 100);
101
95
  };
102
96
  exports.toSmalletUnit = toSmalletUnit;
103
- const value = Number((0, exports.toSmalletUnit)("4543.367487363")); // 454337n
@@ -0,0 +1,5 @@
1
+ export declare enum TokenValidationType {
2
+ settlement = "settlement",
3
+ transafer = "transafer",
4
+ login = "login"
5
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TokenValidationType = void 0;
4
+ var TokenValidationType;
5
+ (function (TokenValidationType) {
6
+ TokenValidationType["settlement"] = "settlement";
7
+ TokenValidationType["transafer"] = "transafer";
8
+ TokenValidationType["login"] = "login";
9
+ })(TokenValidationType || (exports.TokenValidationType = TokenValidationType = {}));
@@ -25,20 +25,21 @@ const currentUser = (req, res, next) => __awaiter(void 0, void 0, void 0, functi
25
25
  const token = req.headers["authorization"].split(" ")[1];
26
26
  const payload = yield Jwt_1.JWT.verifyToken(token);
27
27
  // Add this debug logic:
28
- const now = Math.floor(Date.now() / 1000); // Current time in seconds
29
- const timeElapsed = (now - payload.iat);
30
- const timeRemaining = payload.exp - now;
31
- const tokenLifetime = payload.exp - payload.iat;
32
- console.log({
33
- issuedAt: new Date(payload.iat * 1000).toISOString(),
34
- expiresAt: new Date(payload.exp * 1000).toISOString(),
35
- timeElapsed,
36
- timeRemaining,
37
- tokenLifetime,
38
- });
28
+ // const now = Math.floor(Date.now() / 1000); // Current time in seconds
29
+ //const timeElapsed = (now - payload.iat!) as number;
30
+ // const timeRemaining = payload.exp! - now;
31
+ // const tokenLifetime = payload.exp! - payload.iat!;
32
+ // console.log({
33
+ // issuedAt: new Date(payload.iat! * 1000).toISOString(),
34
+ // expiresAt: new Date(payload.exp! * 1000).toISOString(),
35
+ // timeElapsed,
36
+ // timeRemaining,
37
+ // tokenLifetime,
38
+ // });
39
39
  if (payload.type !== Jwt_1.JWTType.ACCESS) {
40
40
  throw new notAuthorized_1.NotAuthorizedError(language_1.lang.not_authorized, error_codes_1.error_codes.INVALID_AUTHORIZATION);
41
41
  }
42
+ // Check if token found in redis the token is revoked
42
43
  const isValidToken = yield base_1.redisWrapper.isTokenRevoked((0, constants_1.checkRevokedToken)(payload.id, token));
43
44
  if (isValidToken) {
44
45
  throw new notAuthorized_1.NotAuthorizedError(language_1.lang.not_authorized, error_codes_1.error_codes.INVALID_AUTHORIZATION);
@@ -9,3 +9,4 @@ export * from "./mono-webhook";
9
9
  export * from "./request-log";
10
10
  export * from "./rate-limit";
11
11
  export * from "./transaction-session";
12
+ export * from "./token-validation-session";
@@ -25,3 +25,4 @@ __exportStar(require("./mono-webhook"), exports);
25
25
  __exportStar(require("./request-log"), exports);
26
26
  __exportStar(require("./rate-limit"), exports);
27
27
  __exportStar(require("./transaction-session"), exports);
28
+ __exportStar(require("./token-validation-session"), exports);
@@ -0,0 +1,10 @@
1
+ import { NextFunction, Request, Response } from "express";
2
+ import { TOKEN_VALIDATION_JWT_DATA } from "../services/Jwt";
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ twoFaData: TOKEN_VALIDATION_JWT_DATA;
7
+ }
8
+ }
9
+ }
10
+ export declare const TwoFactorSessionValidation: (req: Request, res: Response, next: NextFunction) => Promise<void>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TwoFactorSessionValidation = void 0;
13
+ const Jwt_1 = require("../services/Jwt");
14
+ const notAuthorized_1 = require("../errors/notAuthorized");
15
+ const error_codes_1 = require("../helper/errorCodes/error-codes");
16
+ const app_configs_1 = require("../app.configs");
17
+ const helper_1 = require("../helper");
18
+ const redis_1 = require("../redis");
19
+ const TwoFactorSessionValidation = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
20
+ if (!req.headers["k-2fa-session"]) {
21
+ throw new notAuthorized_1.NotAuthorizedError("k-2fa-session token not provided", error_codes_1.error_codes.INVALID_AUTHORIZATION);
22
+ }
23
+ try {
24
+ if (req.headers["k-2fa-session"]) {
25
+ const token = req.headers["k-2fa-session"];
26
+ const payload = yield Jwt_1.JWT.verify2FAToken(token);
27
+ // Check if token found in redis the token is revoked
28
+ const isValidToken = yield redis_1.redisWrapper.isTokenRevoked((0, redis_1.checkRevokedToken)(payload.userId, token));
29
+ if (isValidToken) {
30
+ throw new notAuthorized_1.NotAuthorizedError(helper_1.lang.not_authorized, error_codes_1.error_codes.INVALID_AUTHORIZATION);
31
+ }
32
+ yield redis_1.redisWrapper.isTokenRevoked((0, redis_1.setsetRevokedToken)(payload.userId, token));
33
+ req.twoFaData = payload;
34
+ }
35
+ return next();
36
+ }
37
+ catch (error) {
38
+ if (app_configs_1.appConfigs.getNODE_ENV() !== "production") {
39
+ console.log("failed to process 2fa token");
40
+ }
41
+ throw new notAuthorized_1.NotAuthorizedError("Invalid twofa session please restart the process again", error_codes_1.error_codes.INVALID_AUTHORIZATION);
42
+ }
43
+ });
44
+ exports.TwoFactorSessionValidation = TwoFactorSessionValidation;
@@ -1,6 +1,8 @@
1
1
  export declare const REDIS_REPOSITORY = "RedisRepository";
2
2
  export declare const setVerificationCode: (email: string) => string;
3
3
  export declare const getVerificationCode: (email: string) => string;
4
+ export declare const setSettlementAuthCode: (email: string) => string;
5
+ export declare const getSettlementAuthCode: (email: string) => string;
4
6
  export declare const setTransferCode: (id: string, code: string) => string;
5
7
  export declare const getTransferCode: (id: string, code: string) => string;
6
8
  export declare const getPermissions: (id: string) => string;
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setTransferToken = exports.checkTransferToken = exports.setsetRevokedToken = exports.checkRevokedToken = exports.setPermissions = exports.getPermissions = exports.getTransferCode = exports.setTransferCode = exports.getVerificationCode = exports.setVerificationCode = exports.REDIS_REPOSITORY = void 0;
3
+ exports.setTransferToken = exports.checkTransferToken = exports.setsetRevokedToken = exports.checkRevokedToken = exports.setPermissions = exports.getPermissions = exports.getTransferCode = exports.setTransferCode = exports.getSettlementAuthCode = exports.setSettlementAuthCode = exports.getVerificationCode = exports.setVerificationCode = exports.REDIS_REPOSITORY = void 0;
4
4
  exports.REDIS_REPOSITORY = "RedisRepository";
5
5
  const setVerificationCode = (email) => `${email}-verification`;
6
6
  exports.setVerificationCode = setVerificationCode;
7
7
  const getVerificationCode = (email) => `${email}-verification`;
8
8
  exports.getVerificationCode = getVerificationCode;
9
+ const setSettlementAuthCode = (email) => `${email}-settlement-auth`;
10
+ exports.setSettlementAuthCode = setSettlementAuthCode;
11
+ const getSettlementAuthCode = (email) => `${email}-settlement-auth`;
12
+ exports.getSettlementAuthCode = getSettlementAuthCode;
9
13
  const setTransferCode = (id, code) => `${id}-${code}-transfer`;
10
14
  exports.setTransferCode = setTransferCode;
11
15
  const getTransferCode = (id, code) => `${id}-${code}-transfer`;
@@ -1,5 +1,5 @@
1
1
  import { SignOptions } from "jsonwebtoken";
2
- import { Usage, USER_TYPES } from "../helper";
2
+ import { TokenValidationType, Usage, USER_TYPES } from "../helper";
3
3
  export declare enum JWTType {
4
4
  REFRESH = "REFRESH",
5
5
  ACCESS = "ACCESS"
@@ -12,6 +12,7 @@ export interface JWT_Data {
12
12
  userType: USER_TYPES;
13
13
  accountId?: string;
14
14
  adminId?: string;
15
+ fullName?: string;
15
16
  iat?: number;
16
17
  exp?: number;
17
18
  }
@@ -34,6 +35,12 @@ export interface SUBSCRIPTION_JWT_DATA {
34
35
  iat?: string;
35
36
  exp?: number;
36
37
  }
38
+ export interface TOKEN_VALIDATION_JWT_DATA {
39
+ userId: string;
40
+ type: TokenValidationType;
41
+ iat?: string;
42
+ exp?: number;
43
+ }
37
44
  export declare class JWT {
38
45
  static getToken(data: JWT_Data, options?: SignOptions): Promise<string>;
39
46
  static verifyToken(token: string): Promise<JWT_Data>;
@@ -41,4 +48,6 @@ export declare class JWT {
41
48
  static verifyTransactionToken(token: string): Promise<TRANSACTION_JWT_DATA>;
42
49
  static getSubscriptionToken(data: SUBSCRIPTION_JWT_DATA, options?: SignOptions): Promise<string>;
43
50
  static verifySubscriptionToken(token: string): Promise<SUBSCRIPTION_JWT_DATA>;
51
+ static get2FAToken(data: TOKEN_VALIDATION_JWT_DATA, options?: SignOptions): Promise<string>;
52
+ static verify2FAToken(token: string): Promise<TOKEN_VALIDATION_JWT_DATA>;
44
53
  }
@@ -24,6 +24,7 @@ var JWTType;
24
24
  const secret = process.env.JWT_KEY;
25
25
  const transactionSecret = process.env.TRANSACTION_JWT_KEY;
26
26
  const subscriptionSecret = process.env.SUBSCRIPTION_JWT_KEY;
27
+ const twoFactorSecret = process.env.SUBSCRIPTION_JWT_KEY;
27
28
  class JWT {
28
29
  static getToken(data_1) {
29
30
  return __awaiter(this, arguments, void 0, function* (data, options = {}) {
@@ -73,5 +74,21 @@ class JWT {
73
74
  });
74
75
  });
75
76
  }
77
+ static get2FAToken(data_1) {
78
+ return __awaiter(this, arguments, void 0, function* (data, options = {}) {
79
+ return signAsync(data, twoFactorSecret, options);
80
+ });
81
+ }
82
+ static verify2FAToken(token) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ return new Promise((resolve, reject) => {
85
+ jsonwebtoken_1.default.verify(token, twoFactorSecret, function (err, decoded) {
86
+ if (err)
87
+ reject(err);
88
+ resolve(decoded);
89
+ });
90
+ });
91
+ });
92
+ }
76
93
  }
77
94
  exports.JWT = JWT;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konplit-services/common",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",