@traxionpay/cbsmiddleware 0.0.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.
Files changed (203) hide show
  1. package/.prettierrc +4 -0
  2. package/Dockerfile +26 -0
  3. package/README.md +109 -0
  4. package/dist/app.module.d.ts +3 -0
  5. package/dist/app.module.d.ts.map +1 -0
  6. package/dist/app.module.js +44 -0
  7. package/dist/app.module.js.map +1 -0
  8. package/dist/auth/apikey.guard.d.ts +9 -0
  9. package/dist/auth/apikey.guard.d.ts.map +1 -0
  10. package/dist/auth/apikey.guard.js +86 -0
  11. package/dist/auth/apikey.guard.js.map +1 -0
  12. package/dist/auth/auth.controller.d.ts +10 -0
  13. package/dist/auth/auth.controller.d.ts.map +1 -0
  14. package/dist/auth/auth.controller.js +65 -0
  15. package/dist/auth/auth.controller.js.map +1 -0
  16. package/dist/auth/auth.interface.d.ts +8 -0
  17. package/dist/auth/auth.interface.d.ts.map +1 -0
  18. package/dist/auth/auth.interface.js +3 -0
  19. package/dist/auth/auth.interface.js.map +1 -0
  20. package/dist/auth/auth.module.d.ts +6 -0
  21. package/dist/auth/auth.module.d.ts.map +1 -0
  22. package/dist/auth/auth.module.js +81 -0
  23. package/dist/auth/auth.module.js.map +1 -0
  24. package/dist/auth/constant.d.ts +2 -0
  25. package/dist/auth/constant.d.ts.map +1 -0
  26. package/dist/auth/constant.js +5 -0
  27. package/dist/auth/constant.js.map +1 -0
  28. package/dist/auth/jwt-constant.d.ts +8 -0
  29. package/dist/auth/jwt-constant.d.ts.map +1 -0
  30. package/dist/auth/jwt-constant.js +60 -0
  31. package/dist/auth/jwt-constant.js.map +1 -0
  32. package/dist/auth/jwt-guard.d.ts +5 -0
  33. package/dist/auth/jwt-guard.d.ts.map +1 -0
  34. package/dist/auth/jwt-guard.js +18 -0
  35. package/dist/auth/jwt-guard.js.map +1 -0
  36. package/dist/auth/jwt-strategy.d.ts +16 -0
  37. package/dist/auth/jwt-strategy.d.ts.map +1 -0
  38. package/dist/auth/jwt-strategy.js +59 -0
  39. package/dist/auth/jwt-strategy.js.map +1 -0
  40. package/dist/auth/services/auth.service.d.ts +14 -0
  41. package/dist/auth/services/auth.service.d.ts.map +1 -0
  42. package/dist/auth/services/auth.service.js +56 -0
  43. package/dist/auth/services/auth.service.js.map +1 -0
  44. package/dist/auth/services/encryption.service.d.ts +11 -0
  45. package/dist/auth/services/encryption.service.d.ts.map +1 -0
  46. package/dist/auth/services/encryption.service.js +49 -0
  47. package/dist/auth/services/encryption.service.js.map +1 -0
  48. package/dist/auth.config.d.ts +29 -0
  49. package/dist/auth.config.d.ts.map +1 -0
  50. package/dist/auth.config.js +71 -0
  51. package/dist/auth.config.js.map +1 -0
  52. package/dist/banking/banking.controller.d.ts +18 -0
  53. package/dist/banking/banking.controller.d.ts.map +1 -0
  54. package/dist/banking/banking.controller.js +146 -0
  55. package/dist/banking/banking.controller.js.map +1 -0
  56. package/dist/banking/banking.module.d.ts +6 -0
  57. package/dist/banking/banking.module.d.ts.map +1 -0
  58. package/dist/banking/banking.module.js +90 -0
  59. package/dist/banking/banking.module.js.map +1 -0
  60. package/dist/banking/dto/account-transfer.dto.d.ts +17 -0
  61. package/dist/banking/dto/account-transfer.dto.d.ts.map +1 -0
  62. package/dist/banking/dto/account-transfer.dto.js +101 -0
  63. package/dist/banking/dto/account-transfer.dto.js.map +1 -0
  64. package/dist/banking/dto/account.dto.d.ts +19 -0
  65. package/dist/banking/dto/account.dto.d.ts.map +1 -0
  66. package/dist/banking/dto/account.dto.js +104 -0
  67. package/dist/banking/dto/account.dto.js.map +1 -0
  68. package/dist/banking/dto/fetch-bank-balance.dto.d.ts +12 -0
  69. package/dist/banking/dto/fetch-bank-balance.dto.d.ts.map +1 -0
  70. package/dist/banking/dto/fetch-bank-balance.dto.js +71 -0
  71. package/dist/banking/dto/fetch-bank-balance.dto.js.map +1 -0
  72. package/dist/banking/dto/transaction-history.dto.d.ts +15 -0
  73. package/dist/banking/dto/transaction-history.dto.d.ts.map +1 -0
  74. package/dist/banking/dto/transaction-history.dto.js +89 -0
  75. package/dist/banking/dto/transaction-history.dto.js.map +1 -0
  76. package/dist/banking/factory/bank-strategy.factory.d.ts +9 -0
  77. package/dist/banking/factory/bank-strategy.factory.d.ts.map +1 -0
  78. package/dist/banking/factory/bank-strategy.factory.js +48 -0
  79. package/dist/banking/factory/bank-strategy.factory.js.map +1 -0
  80. package/dist/banking/interfaces/bank-config.interface.d.ts +22 -0
  81. package/dist/banking/interfaces/bank-config.interface.d.ts.map +1 -0
  82. package/dist/banking/interfaces/bank-config.interface.js +3 -0
  83. package/dist/banking/interfaces/bank-config.interface.js.map +1 -0
  84. package/dist/banking/interfaces/bank-service.interface.d.ts +19 -0
  85. package/dist/banking/interfaces/bank-service.interface.d.ts.map +1 -0
  86. package/dist/banking/interfaces/bank-service.interface.js +3 -0
  87. package/dist/banking/interfaces/bank-service.interface.js.map +1 -0
  88. package/dist/banking/services/ASPAC.service.d.ts +25 -0
  89. package/dist/banking/services/ASPAC.service.d.ts.map +1 -0
  90. package/dist/banking/services/ASPAC.service.js +498 -0
  91. package/dist/banking/services/ASPAC.service.js.map +1 -0
  92. package/dist/banking/services/BankGateway.service.d.ts +18 -0
  93. package/dist/banking/services/BankGateway.service.d.ts.map +1 -0
  94. package/dist/banking/services/BankGateway.service.js +71 -0
  95. package/dist/banking/services/BankGateway.service.js.map +1 -0
  96. package/dist/banking/services/MBWIN.service.d.ts +25 -0
  97. package/dist/banking/services/MBWIN.service.d.ts.map +1 -0
  98. package/dist/banking/services/MBWIN.service.js +655 -0
  99. package/dist/banking/services/MBWIN.service.js.map +1 -0
  100. package/dist/banking/services/WelcomeBank.service.d.ts +29 -0
  101. package/dist/banking/services/WelcomeBank.service.d.ts.map +1 -0
  102. package/dist/banking/services/WelcomeBank.service.js +840 -0
  103. package/dist/banking/services/WelcomeBank.service.js.map +1 -0
  104. package/dist/banking/services/sms.service.d.ts +10 -0
  105. package/dist/banking/services/sms.service.d.ts.map +1 -0
  106. package/dist/banking/services/sms.service.js +97 -0
  107. package/dist/banking/services/sms.service.js.map +1 -0
  108. package/dist/banking/tokens/bank-service.tokens.d.ts +5 -0
  109. package/dist/banking/tokens/bank-service.tokens.d.ts.map +1 -0
  110. package/dist/banking/tokens/bank-service.tokens.js +8 -0
  111. package/dist/banking/tokens/bank-service.tokens.js.map +1 -0
  112. package/dist/banking/types.d.ts +10 -0
  113. package/dist/banking/types.d.ts.map +1 -0
  114. package/dist/banking/types.js +3 -0
  115. package/dist/banking/types.js.map +1 -0
  116. package/dist/decorators/response_message.decorator.d.ts +2 -0
  117. package/dist/decorators/response_message.decorator.d.ts.map +1 -0
  118. package/dist/decorators/response_message.decorator.js +7 -0
  119. package/dist/decorators/response_message.decorator.js.map +1 -0
  120. package/dist/helpers/axios-error.helper.d.ts +6 -0
  121. package/dist/helpers/axios-error.helper.d.ts.map +1 -0
  122. package/dist/helpers/axios-error.helper.js +78 -0
  123. package/dist/helpers/axios-error.helper.js.map +1 -0
  124. package/dist/helpers/response-format.helper.d.ts +4 -0
  125. package/dist/helpers/response-format.helper.d.ts.map +1 -0
  126. package/dist/helpers/response-format.helper.js +15 -0
  127. package/dist/helpers/response-format.helper.js.map +1 -0
  128. package/dist/index.d.ts +10 -0
  129. package/dist/index.d.ts.map +1 -0
  130. package/dist/index.js +26 -0
  131. package/dist/index.js.map +1 -0
  132. package/dist/interceptors/response.interceptor.d.ts +16 -0
  133. package/dist/interceptors/response.interceptor.d.ts.map +1 -0
  134. package/dist/interceptors/response.interceptor.js +80 -0
  135. package/dist/interceptors/response.interceptor.js.map +1 -0
  136. package/dist/logger/logger-interceptor.d.ts +14 -0
  137. package/dist/logger/logger-interceptor.d.ts.map +1 -0
  138. package/dist/logger/logger-interceptor.js +60 -0
  139. package/dist/logger/logger-interceptor.js.map +1 -0
  140. package/dist/logger/logger-option.d.ts +6 -0
  141. package/dist/logger/logger-option.d.ts.map +1 -0
  142. package/dist/logger/logger-option.js +103 -0
  143. package/dist/logger/logger-option.js.map +1 -0
  144. package/dist/logger/logger.config.d.ts +3 -0
  145. package/dist/logger/logger.config.d.ts.map +1 -0
  146. package/dist/logger/logger.config.js +31 -0
  147. package/dist/logger/logger.config.js.map +1 -0
  148. package/dist/logger/logger.module.d.ts +3 -0
  149. package/dist/logger/logger.module.d.ts.map +1 -0
  150. package/dist/logger/logger.module.js +76 -0
  151. package/dist/logger/logger.module.js.map +1 -0
  152. package/dist/main.d.ts +2 -0
  153. package/dist/main.d.ts.map +1 -0
  154. package/dist/main.js +13 -0
  155. package/dist/main.js.map +1 -0
  156. package/dist/tsconfig.build.tsbuildinfo +1 -0
  157. package/docker-compose.yml +14 -0
  158. package/ecosystem.config.js +35 -0
  159. package/eslint.config.mjs +34 -0
  160. package/nest-cli.json +8 -0
  161. package/package.json +102 -0
  162. package/src/app.module.ts +33 -0
  163. package/src/auth/apikey.guard.ts +42 -0
  164. package/src/auth/auth.controller.ts +41 -0
  165. package/src/auth/auth.interface.ts +7 -0
  166. package/src/auth/auth.module.ts +125 -0
  167. package/src/auth/constant.ts +1 -0
  168. package/src/auth/jwt-constant.ts +31 -0
  169. package/src/auth/jwt-guard.ts +5 -0
  170. package/src/auth/jwt-strategy.ts +43 -0
  171. package/src/auth/services/auth.service.ts +33 -0
  172. package/src/auth/services/encryption.service.ts +35 -0
  173. package/src/auth.config.ts +42 -0
  174. package/src/banking/banking.controller.ts +142 -0
  175. package/src/banking/banking.module.ts +142 -0
  176. package/src/banking/dto/account-transfer.dto.ts +66 -0
  177. package/src/banking/dto/account.dto.ts +70 -0
  178. package/src/banking/dto/fetch-bank-balance.dto.ts +46 -0
  179. package/src/banking/dto/transaction-history.dto.ts +58 -0
  180. package/src/banking/factory/bank-strategy.factory.ts +25 -0
  181. package/src/banking/interfaces/bank-config.interface.ts +25 -0
  182. package/src/banking/interfaces/bank-service.interface.ts +164 -0
  183. package/src/banking/services/ASPAC.service.ts +574 -0
  184. package/src/banking/services/BankGateway.service.ts +64 -0
  185. package/src/banking/services/MBWIN.service.ts +779 -0
  186. package/src/banking/services/WelcomeBank.service.ts +990 -0
  187. package/src/banking/services/sms.service.ts +50 -0
  188. package/src/banking/tokens/bank-service.tokens.ts +4 -0
  189. package/src/banking/types.ts +10 -0
  190. package/src/decorators/response_message.decorator.ts +4 -0
  191. package/src/helpers/axios-error.helper.ts +63 -0
  192. package/src/helpers/response-format.helper.ts +15 -0
  193. package/src/index.ts +15 -0
  194. package/src/interceptors/response.interceptor.ts +53 -0
  195. package/src/logger/logger-interceptor.ts +55 -0
  196. package/src/logger/logger-option.ts +119 -0
  197. package/src/logger/logger.config.ts +31 -0
  198. package/src/logger/logger.module.ts +31 -0
  199. package/src/main.ts +10 -0
  200. package/src/types/pino-daily-rotate-file.d.ts +31 -0
  201. package/tsconfig.build.json +11 -0
  202. package/tsconfig.build.tsbuildinfo +1 -0
  203. package/tsconfig.json +22 -0
@@ -0,0 +1,14 @@
1
+ services:
2
+ service:
3
+ build: .
4
+ container_name: cbs-middleware
5
+ env_file:
6
+ - ./.env
7
+ environment:
8
+ - NODE_ENV=production
9
+ ports:
10
+ - "5011:5000"
11
+ volumes:
12
+ - ./logs:/usr/src/app/logs
13
+ - ./certs:/usr/src/app/certs:ro
14
+ restart: always
@@ -0,0 +1,35 @@
1
+ /*
2
+ * Copyright 2024.
3
+ * Company: Traxion Tech Inc.
4
+ * Author: Patrick Doldolea
5
+ * Created: 12/18/24, 7:44 PM
6
+ * Modified: 12/18/24, 7:44 PM
7
+ * Last User: pdoldolea
8
+ */
9
+
10
+ /*
11
+ NOTE: clustering is disabled
12
+ */
13
+
14
+ const os = require('os');
15
+
16
+ const cpuCount = os.cpus().length;
17
+ const instances = Math.floor(cpuCount / 2) || 1;
18
+ const singleNodeInstance = process.env.FORCED_SINGLE_INSTANCE === 'true';
19
+
20
+ module.exports = {
21
+ apps: [
22
+ {
23
+ name: 'CBS MiddleWare',
24
+ namespace: 'service',
25
+ script: 'dist/main.js', // Entry point of your NestJS application
26
+ instances: 2,
27
+ exec_mode: 'cluster', // cluster only on multiple instance requirements
28
+ watch: false, // Set to true if you want PM2 to watch for file changes (not recommended for production)
29
+ env: {
30
+ NODE_ENV: 'production', // Sets the environment variable
31
+ PORT: 5000
32
+ },
33
+ },
34
+ ],
35
+ };
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+ import eslint from '@eslint/js';
3
+ import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
4
+ import globals from 'globals';
5
+ import tseslint from 'typescript-eslint';
6
+
7
+ export default tseslint.config(
8
+ {
9
+ ignores: ['eslint.config.mjs'],
10
+ },
11
+ eslint.configs.recommended,
12
+ ...tseslint.configs.recommendedTypeChecked,
13
+ eslintPluginPrettierRecommended,
14
+ {
15
+ languageOptions: {
16
+ globals: {
17
+ ...globals.node,
18
+ ...globals.jest,
19
+ },
20
+ sourceType: 'commonjs',
21
+ parserOptions: {
22
+ projectService: true,
23
+ tsconfigRootDir: import.meta.dirname,
24
+ },
25
+ },
26
+ },
27
+ {
28
+ rules: {
29
+ '@typescript-eslint/no-explicit-any': 'off',
30
+ '@typescript-eslint/no-floating-promises': 'warn',
31
+ '@typescript-eslint/no-unsafe-argument': 'warn'
32
+ },
33
+ },
34
+ );
package/nest-cli.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/nest-cli",
3
+ "collection": "@nestjs/schematics",
4
+ "sourceRoot": "src",
5
+ "compilerOptions": {
6
+ "deleteOutDir": true
7
+ }
8
+ }
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "@traxionpay/cbsmiddleware",
3
+ "version": "0.0.1",
4
+ "description": "This is a cbs middlware for RB Banks",
5
+ "author": "Archer",
6
+ "private": false,
7
+ "license": "UNLICENSED",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "scripts": {
11
+ "build": "tsc -p tsconfig.build.json",
12
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
13
+ "start": "nest start",
14
+ "start:dev": "nest start --watch",
15
+ "start:debug": "nest start --debug --watch",
16
+ "start:prod": "node dist/main",
17
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
18
+ "test": "jest",
19
+ "test:watch": "jest --watch",
20
+ "test:cov": "jest --coverage",
21
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
22
+ "test:e2e": "jest --config ./test/jest-e2e.json"
23
+ },
24
+ "dependencies": {
25
+ "@nestjs/common": "^11.0.1",
26
+ "@nestjs/config": "^4.0.2",
27
+ "@nestjs/core": "^11.0.1",
28
+ "@nestjs/jwt": "^11.0.0",
29
+ "@nestjs/mapped-types": "*",
30
+ "@nestjs/passport": "^11.0.5",
31
+ "@nestjs/platform-express": "^11.0.1",
32
+ "axios": "^1.10.0",
33
+ "bcryptjs": "^3.0.2",
34
+ "class-validator": "^0.14.2",
35
+ "crypto-js": "^4.2.0",
36
+ "date-fns-tz": "^3.2.0",
37
+ "moment-timezone": "^0.6.0",
38
+ "nestjs-pino": "^4.4.0",
39
+ "passport": "^0.7.0",
40
+ "passport-jwt": "^4.0.1",
41
+ "pino-daily-rotate-file": "^0.0.1",
42
+ "pino-http": "^10.5.0",
43
+ "pino-pretty": "^13.0.0",
44
+ "reflect-metadata": "^0.2.2",
45
+ "rxjs": "^7.8.1",
46
+ "speakeasy": "^2.0.0",
47
+ "totp-generator": "^2.0.0",
48
+ "uuid": "^11.1.0"
49
+ },
50
+ "devDependencies": {
51
+ "@eslint/eslintrc": "^3.2.0",
52
+ "@eslint/js": "^9.18.0",
53
+ "@nestjs/cli": "^11.0.0",
54
+ "@nestjs/schematics": "^11.0.0",
55
+ "@nestjs/testing": "^11.0.1",
56
+ "@swc/cli": "^0.6.0",
57
+ "@swc/core": "^1.10.7",
58
+ "@types/express": "^5.0.0",
59
+ "@types/jest": "^29.5.14",
60
+ "@types/node": "^22.10.7",
61
+ "@types/supertest": "^6.0.2",
62
+ "eslint": "^9.18.0",
63
+ "eslint-config-prettier": "^10.0.1",
64
+ "eslint-plugin-prettier": "^5.2.2",
65
+ "globals": "^16.0.0",
66
+ "jest": "^29.7.0",
67
+ "prettier": "^3.4.2",
68
+ "source-map-support": "^0.5.21",
69
+ "supertest": "^7.0.0",
70
+ "ts-jest": "^29.2.5",
71
+ "ts-loader": "^9.5.2",
72
+ "ts-node": "^10.9.2",
73
+ "tsconfig-paths": "^4.2.0",
74
+ "typescript": "^5.7.3",
75
+ "typescript-eslint": "^8.20.0"
76
+ },
77
+ "jest": {
78
+ "moduleFileExtensions": [
79
+ "js",
80
+ "json",
81
+ "ts"
82
+ ],
83
+ "rootDir": "src",
84
+ "testRegex": ".*\\.spec\\.ts$",
85
+ "transform": {
86
+ "^.+\\.(t|j)s$": "ts-jest"
87
+ },
88
+ "collectCoverageFrom": [
89
+ "**/*.(t|j)s"
90
+ ],
91
+ "coverageDirectory": "../coverage",
92
+ "testEnvironment": "node"
93
+ },
94
+ "repository": {
95
+ "type": "git",
96
+ "url": "git+https://bitbucket.org/traxiondev/cbs-middleware-package.git"
97
+ },
98
+ "bugs": {
99
+ "url": "https://bitbucket.org/traxiondev/cbs-middleware-package/issues"
100
+ },
101
+ "homepage": "https://bitbucket.org/traxiondev/cbs-middleware-package#readme"
102
+ }
@@ -0,0 +1,33 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { BankingModule } from './banking/banking.module';
3
+ //alias module if you have authmodule in your own repo
4
+ import { AuthModule as MiddleWareAuthModule } from './auth/auth.module';
5
+ import { TransformInterceptor } from './interceptors/response.interceptor';
6
+ import { LoggerInterceptor } from './logger/logger-interceptor';
7
+ import { APP_INTERCEPTOR } from '@nestjs/core';
8
+ import { ConfigModule } from '@nestjs/config';
9
+ import { authConfig, bankConfig } from './auth.config';
10
+
11
+ @Module({
12
+ imports: [
13
+ ConfigModule.forRoot({
14
+ isGlobal: true,
15
+ }),
16
+ BankingModule.register({
17
+ config: bankConfig
18
+ //options: optional
19
+ }),
20
+ MiddleWareAuthModule.forRoot(authConfig),
21
+ ],
22
+ providers: [
23
+ {
24
+ provide: APP_INTERCEPTOR,
25
+ useClass: LoggerInterceptor, //optional
26
+ },
27
+ {
28
+ provide: APP_INTERCEPTOR,
29
+ useClass: TransformInterceptor, //optional if want to Transform your responses
30
+ },
31
+ ],
32
+ })
33
+ export class AppModule {}
@@ -0,0 +1,42 @@
1
+
2
+ import { CanActivate, ExecutionContext, HttpStatus, Injectable, Inject } from '@nestjs/common';
3
+ import * as moment from 'moment-timezone';
4
+ import { AUTH_MODULE_OPTIONS } from './constant';
5
+ import { AuthModuleOptions } from './auth.interface';
6
+
7
+ @Injectable()
8
+ export class ApiKeyGuard implements CanActivate {
9
+ private readonly validApiKeys: string;
10
+
11
+ constructor(
12
+ @Inject(AUTH_MODULE_OPTIONS)
13
+ private readonly options: AuthModuleOptions,
14
+ ) {
15
+ this.validApiKeys = options.apiKey || 'Hi';
16
+ }
17
+
18
+ canActivate(context: ExecutionContext): any {
19
+
20
+ const request = context.switchToHttp();
21
+ const response = request.getResponse();
22
+ const apiKey = request.getRequest().headers['x-api-key'] as string | undefined;
23
+ const errorResponse = {
24
+ statusCode: HttpStatus.UNAUTHORIZED,
25
+ timeStamp: moment.tz('Asia/Manila').format('YYYY-MM-DD HH:mm:ss'),
26
+ message: 'Invalid API Key provided.',
27
+ error: 'Unauthorized',
28
+ };
29
+
30
+ if (!apiKey) {
31
+ response.status(HttpStatus.UNAUTHORIZED).send(errorResponse);
32
+ }
33
+
34
+ if(this.validApiKeys == apiKey) {
35
+ return true;
36
+ } else {
37
+ // return false;
38
+ response.status(HttpStatus.UNAUTHORIZED).send(errorResponse);
39
+ }
40
+
41
+ }
42
+ }
@@ -0,0 +1,41 @@
1
+ import { Controller, Post, UseGuards, Inject } from '@nestjs/common';
2
+ import { AuthService } from './services/auth.service';
3
+ import { ApiKeyGuard } from './apikey.guard';
4
+ import { AUTH_MODULE_OPTIONS } from './constant';
5
+ import { AuthModuleOptions } from './auth.interface';
6
+ import { ResponseMessage } from '../decorators/response_message.decorator';
7
+ @Controller('auth')
8
+ export class AuthController {
9
+ private readonly secretKey: string;
10
+ constructor(private readonly authService: AuthService,
11
+ @Inject(AUTH_MODULE_OPTIONS)
12
+ private readonly options: AuthModuleOptions,
13
+
14
+ ) {
15
+ this.secretKey = options.jwtSecret || '';
16
+ }
17
+
18
+ @Post('token')
19
+ @UseGuards(ApiKeyGuard)
20
+ @ResponseMessage("Generate Token")
21
+ async generateToken() {
22
+ const payload = {
23
+ service: 'banking-service',
24
+ issuedAt: Date.now(),
25
+ secret_key: this.secretKey
26
+ };
27
+
28
+ const token = await this.authService.generateToken(payload);
29
+ if (token) {
30
+ return {
31
+ success: true,
32
+ ...token,
33
+ }
34
+ }else {
35
+ return {
36
+ success: false,
37
+ message: 'Error Token Generation',
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,7 @@
1
+ export interface AuthModuleOptions {
2
+ jwtSecret?: string;
3
+ expiresIn?: string | undefined;
4
+ publicKey?: string;
5
+ privateKey?: string;
6
+ apiKey?: string;
7
+ }
@@ -0,0 +1,125 @@
1
+ import { Module, DynamicModule } from '@nestjs/common';
2
+ import { JwtModule } from '@nestjs/jwt';
3
+ import { PassportModule } from '@nestjs/passport';
4
+ import { AuthService } from './services/auth.service';
5
+ import { JwtStrategy } from './jwt-strategy';
6
+ import { JwtAuthGuard } from './jwt-guard';
7
+ import { AUTH_MODULE_OPTIONS } from './constant';
8
+ import { AuthModuleOptions } from './auth.interface';
9
+ import { AuthController } from './auth.controller';
10
+ import { AppLoggerModule } from '../logger/logger.module';
11
+ import { EncryptionService } from './services/encryption.service';
12
+
13
+ /**
14
+ * The `AuthModule` provides a dynamic authentication module with JWT-based authentication.
15
+ *
16
+ * It supports both symmetric (`jwtSecret`) and asymmetric (`privateKey`/`publicKey`) signing strategies,
17
+ * and it integrates with Passport.js and NestJS guards for secure route access.
18
+ *
19
+ * You can configure this module at runtime using the `forRoot()` static method.
20
+ *
21
+ * @export
22
+ * @class AuthModule
23
+ * @typedef {AuthModule}
24
+ *
25
+ * @example
26
+ * // Register the module using a symmetric secret
27
+ * AuthModule.forRoot({
28
+ * jwtSecret: process.env.JWT_SECRET,
29
+ * expiresIn: '1h',
30
+ * apiKey: process.env.API_KEY,
31
+ * });
32
+ *
33
+ * @example
34
+ * // Register using asymmetric RSA keys
35
+ * AuthModule.forRoot({
36
+ * privateKey: fs.readFileSync('private.pem', 'utf-8'),
37
+ * publicKey: fs.readFileSync('public.pem', 'utf-8'),
38
+ * expiresIn: '3600s',
39
+ * });
40
+ */
41
+ @Module({})
42
+ export class AuthModule {
43
+ /**
44
+ * Dynamically registers and configures the `AuthModule` with optional JWT and API key settings.
45
+ *
46
+ * - Supports both symmetric (`jwtSecret`) and asymmetric (`privateKey`/`publicKey`) JWT configurations.
47
+ * - Throws an error if neither a `jwtSecret` nor `privateKey` is provided.
48
+ *
49
+ * @static
50
+ * @param {Partial<AuthModuleOptions>} [options={}] - Optional configuration for JWT and API key support.
51
+ * @returns {DynamicModule} A fully configured NestJS dynamic module.
52
+ *
53
+ * @example
54
+ * import { AuthModule } from './auth/auth.module';
55
+ *
56
+ * `@`Module({
57
+ * imports: [
58
+ * AuthModule.forRoot({
59
+ * jwtSecret: 'your-secret',
60
+ * expiresIn: '3600s',
61
+ * apiKey: 'my-api-key',
62
+ * }),
63
+ * ],
64
+ * })
65
+ * export class AppModule {}
66
+ */
67
+ static forRoot(options: Partial<AuthModuleOptions> = {}): DynamicModule {
68
+ const jwtSecret = options.jwtSecret;
69
+ const expiresIn = options.expiresIn?.toString(); // ensure it's a string
70
+ const publicKey = options.publicKey;
71
+ const privateKey = options.privateKey;
72
+ const apiKey = options.apiKey;
73
+
74
+ if (!jwtSecret && !privateKey) {
75
+ throw new Error(
76
+ 'AuthModule Error: jwtSecret or privateKey is required via options or .env or constants',
77
+ );
78
+ }
79
+
80
+ const finalOptions: AuthModuleOptions = {
81
+ jwtSecret,
82
+ expiresIn,
83
+ publicKey,
84
+ privateKey,
85
+ apiKey,
86
+ };
87
+
88
+ return {
89
+ module: AuthModule,
90
+ imports: [
91
+ PassportModule, // Provides support for Passport strategies
92
+ AppLoggerModule, // Custom logging module
93
+ JwtModule.registerAsync({
94
+ global: true,
95
+ useFactory: async () => {
96
+ if (privateKey && publicKey) {
97
+ return {
98
+ privateKey,
99
+ publicKey,
100
+ signOptions: { algorithm: 'RS256', expiresIn },
101
+ };
102
+ } else {
103
+ return {
104
+ secret: jwtSecret,
105
+ signOptions: { expiresIn },
106
+ };
107
+ }
108
+ },
109
+ }),
110
+ ],
111
+ controllers: [AuthController],
112
+ providers: [
113
+ AuthService,
114
+ JwtStrategy, // Strategy for validating JWTs
115
+ JwtAuthGuard, // Guard to protect routes using JWTs
116
+ EncryptionService, // Optional encryption utility
117
+ {
118
+ provide: AUTH_MODULE_OPTIONS,
119
+ useValue: finalOptions,
120
+ },
121
+ ],
122
+ exports: [AuthService, JwtAuthGuard], // Export AuthService and Guard for use in other modules
123
+ };
124
+ }
125
+ }
@@ -0,0 +1 @@
1
+ export const AUTH_MODULE_OPTIONS = 'AUTH_MODULE_OPTIONS';
@@ -0,0 +1,31 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as process from 'process';
4
+ import { SignOptions } from 'jsonwebtoken';
5
+
6
+ const defaultCertPath = path.resolve(process.cwd(), 'certs'); // From the consumer's project root
7
+
8
+ const privateKeyPath = path.join(defaultCertPath, 'private.key');
9
+ const publicKeyPath = path.join(defaultCertPath, 'public.key');
10
+
11
+ let privateKey: string | undefined;
12
+ let publicKey: string | undefined;
13
+
14
+ // Safely try to read certs from consumer's file system
15
+ if (fs.existsSync(privateKeyPath)) {
16
+ privateKey = fs.readFileSync(privateKeyPath, 'utf8');
17
+ }
18
+
19
+ if (fs.existsSync(publicKeyPath)) {
20
+ publicKey = fs.readFileSync(publicKeyPath, 'utf8');
21
+ }
22
+
23
+ export const JWT_CONSTANTS = {
24
+ jwtSecret: process.env.JWT_SECRET,
25
+ privateKey,
26
+ publicKey,
27
+ signOptions: {
28
+ algorithm: privateKey && publicKey ? 'RS256' : 'HS256',
29
+ expiresIn: process.env.JWT_EXPIRES_IN || '1m',
30
+ } as SignOptions,
31
+ };
@@ -0,0 +1,5 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { AuthGuard } from '@nestjs/passport';
3
+
4
+ @Injectable()
5
+ export class JwtAuthGuard extends AuthGuard('jwt') {}
@@ -0,0 +1,43 @@
1
+ import { PassportStrategy } from '@nestjs/passport';
2
+ import { ExtractJwt, Strategy } from 'passport-jwt';
3
+ import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
4
+ import { AUTH_MODULE_OPTIONS } from './constant';
5
+ import { AuthModuleOptions } from './auth.interface';
6
+ import { Logger } from 'nestjs-pino';
7
+ import { EncryptionService } from './services/encryption.service';
8
+
9
+ @Injectable()
10
+ export class JwtStrategy extends PassportStrategy(Strategy) {
11
+ private readonly secretKey: string;
12
+ constructor(
13
+ @Inject(AUTH_MODULE_OPTIONS)
14
+ private readonly options: AuthModuleOptions,
15
+ private readonly logger: Logger,
16
+ private readonly encryptionService: EncryptionService,
17
+ ) {
18
+ super({
19
+ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
20
+ ignoreExpiration: false,
21
+ secretOrKey: options.publicKey,
22
+ });
23
+ this.secretKey = options.jwtSecret || '';
24
+ }
25
+
26
+ async validate(payload: any) {
27
+ const decryptedPayload = JSON.parse(this.encryptionService.decrypt(payload.encrypted));
28
+ if (this.secretKey !== decryptedPayload.secret_key) {
29
+ this.logger.error('Invalid token payload');
30
+ throw new UnauthorizedException('Invalid token payload');
31
+ }
32
+
33
+ const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
34
+ if (payload.exp < currentTime) {
35
+ this.logger.error('Invalid token payload');
36
+ throw new UnauthorizedException('Token is expired');
37
+ }
38
+
39
+ return { secret_key: decryptedPayload.secret_key };
40
+
41
+ }
42
+ }
43
+
@@ -0,0 +1,33 @@
1
+ import { Injectable, Inject } from '@nestjs/common';
2
+ import { JwtService } from '@nestjs/jwt';
3
+ import { AuthModuleOptions } from '../auth.interface';
4
+ import { AUTH_MODULE_OPTIONS } from '../constant';
5
+ import { Logger } from 'nestjs-pino';
6
+ import { EncryptionService } from './encryption.service';
7
+
8
+ @Injectable()
9
+ export class AuthService {
10
+ constructor(
11
+ private readonly jwtService: JwtService,
12
+ private readonly logger: Logger,
13
+ private readonly encryptionService: EncryptionService,
14
+ @Inject(AUTH_MODULE_OPTIONS)
15
+ private readonly options: AuthModuleOptions,
16
+ ) {}
17
+
18
+ async generateToken(payload: any): Promise<any> {
19
+ try {
20
+ const encryptedPayload = this.encryptionService.encrypt(JSON.stringify(payload));
21
+ return {
22
+ token: this.jwtService.sign({ encrypted: encryptedPayload }),
23
+ };
24
+ } catch (error) {
25
+ this.logger.error(error);
26
+ throw error;
27
+ }
28
+ }
29
+
30
+ verifyToken(token: string): any {
31
+ return this.jwtService.verify(token);
32
+ }
33
+ }
@@ -0,0 +1,35 @@
1
+ import { createCipheriv, createDecipheriv, scryptSync } from 'crypto';
2
+ import { Injectable, Inject } from '@nestjs/common';
3
+ import { AUTH_MODULE_OPTIONS } from '../constant';
4
+ import { AuthModuleOptions } from '../auth.interface';
5
+
6
+ @Injectable()
7
+ export class EncryptionService {
8
+ private algorithm = 'aes-256-cbc';
9
+ // JWT_SECRET is required in .env file. Please generate strong JWT_SECRET
10
+ private readonly secretKey: string;
11
+ private iv = Buffer.alloc(16, 0); // Initialization vector
12
+
13
+ constructor(
14
+ @Inject(AUTH_MODULE_OPTIONS)
15
+ private readonly options: AuthModuleOptions,
16
+ ) {
17
+ this.secretKey = options.jwtSecret || '';
18
+ }
19
+ // Encypt Token
20
+ encrypt(text: string): string {
21
+ const key = scryptSync(this.secretKey, 'salt', 32);
22
+ const cipher = createCipheriv(this.algorithm, key, this.iv);
23
+ let encrypted = cipher.update(text, 'utf8', 'hex');
24
+ encrypted += cipher.final('hex');
25
+ return encrypted;
26
+ }
27
+
28
+ decrypt(encrypted: string): string {
29
+ const key = scryptSync(this.secretKey, 'salt', 32);
30
+ const decipher = createDecipheriv(this.algorithm, key, this.iv);
31
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
32
+ decrypted += decipher.final('utf8');
33
+ return decrypted;
34
+ }
35
+ }
@@ -0,0 +1,42 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as dotenv from 'dotenv';
4
+ dotenv.config();
5
+
6
+ const privateKeyPath = path.resolve(process.cwd(), 'certs', 'private.key');
7
+ const publicKeyPath = path.resolve(process.cwd(), 'certs', 'public.key');
8
+
9
+ export const authConfig = {
10
+ //Based on current AuthModule Configuration
11
+ jwtSecret: process.env.JWT_SECRET,
12
+ expiresIn: process.env.TOKEN_EXPIRATION,
13
+ privateKey: fs.readFileSync(privateKeyPath, 'utf8'),
14
+ publicKey: fs.readFileSync(publicKeyPath, 'utf8'),
15
+ apiKey: process.env.API_KEY,
16
+ };
17
+
18
+ export const bankConfig = {
19
+ //Based on current BankConfiguration
20
+ BANK1_DATA_KEY: process.env.BANK1_DATA_KEY || '',
21
+ BANK1_AUTH_KEY: process.env.BANK1_AUTH_KEY || '',
22
+ BANK2_AUTH_KEY: process.env.BANK2_AUTH_KEY || '',
23
+ BANK1_URL: process.env.BANK1_URL || '',
24
+ BANK2_URL: process.env.BANK2_URL || '',
25
+ BANK1_DATA_PORT: Number(process.env.BANK1_DATA_PORT),
26
+ BANK2_DATA_PORT: Number(process.env.BANK2_DATA_PORT),
27
+ BANK1_MESSAGE_ID: process.env.BANK1_MESSAGE_ID || '',
28
+ //ASPAC
29
+ ASPAC_URL: process.env.ASPAC_URL || '',
30
+ ASPAC_API_KEY: process.env.ASPAC_API_KEY || '',
31
+ ASPAC_VERSION_KEY: process.env.ASPAC_VERSION_KEY || '',
32
+ //WELCOMEBANK
33
+ WELCOMEBANK_URL: process.env.WELCOMEBANK_URL || '',
34
+ WELCOMEBANK_PORT: Number(process.env.WELCOMEBANK_PORT),
35
+ WELCOMEBANK_API_KEY: process.env.WELCOMEBANK_API_KEY || '',
36
+ WELCOMEBANK_VERSION_KEY: process.env.WELCOMEBANK_VERSION_KEY || '',
37
+ WELCOMBANK_ENABLEENCRYPTION: process.env.WELCOMBANK_ENABLEENCRYPTION === 'true',
38
+ //WBWIN
39
+ MBWIN_URL: process.env.MBWIN_URL || '',
40
+ MBWIN_PORT: Number(process.env.MBWIN_PORT),
41
+ MBWIN_API_KEY: process.env.MBWIN_API_KEY || '',
42
+ }