@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.
- package/.prettierrc +4 -0
- package/Dockerfile +26 -0
- package/README.md +109 -0
- package/dist/app.module.d.ts +3 -0
- package/dist/app.module.d.ts.map +1 -0
- package/dist/app.module.js +44 -0
- package/dist/app.module.js.map +1 -0
- package/dist/auth/apikey.guard.d.ts +9 -0
- package/dist/auth/apikey.guard.d.ts.map +1 -0
- package/dist/auth/apikey.guard.js +86 -0
- package/dist/auth/apikey.guard.js.map +1 -0
- package/dist/auth/auth.controller.d.ts +10 -0
- package/dist/auth/auth.controller.d.ts.map +1 -0
- package/dist/auth/auth.controller.js +65 -0
- package/dist/auth/auth.controller.js.map +1 -0
- package/dist/auth/auth.interface.d.ts +8 -0
- package/dist/auth/auth.interface.d.ts.map +1 -0
- package/dist/auth/auth.interface.js +3 -0
- package/dist/auth/auth.interface.js.map +1 -0
- package/dist/auth/auth.module.d.ts +6 -0
- package/dist/auth/auth.module.d.ts.map +1 -0
- package/dist/auth/auth.module.js +81 -0
- package/dist/auth/auth.module.js.map +1 -0
- package/dist/auth/constant.d.ts +2 -0
- package/dist/auth/constant.d.ts.map +1 -0
- package/dist/auth/constant.js +5 -0
- package/dist/auth/constant.js.map +1 -0
- package/dist/auth/jwt-constant.d.ts +8 -0
- package/dist/auth/jwt-constant.d.ts.map +1 -0
- package/dist/auth/jwt-constant.js +60 -0
- package/dist/auth/jwt-constant.js.map +1 -0
- package/dist/auth/jwt-guard.d.ts +5 -0
- package/dist/auth/jwt-guard.d.ts.map +1 -0
- package/dist/auth/jwt-guard.js +18 -0
- package/dist/auth/jwt-guard.js.map +1 -0
- package/dist/auth/jwt-strategy.d.ts +16 -0
- package/dist/auth/jwt-strategy.d.ts.map +1 -0
- package/dist/auth/jwt-strategy.js +59 -0
- package/dist/auth/jwt-strategy.js.map +1 -0
- package/dist/auth/services/auth.service.d.ts +14 -0
- package/dist/auth/services/auth.service.d.ts.map +1 -0
- package/dist/auth/services/auth.service.js +56 -0
- package/dist/auth/services/auth.service.js.map +1 -0
- package/dist/auth/services/encryption.service.d.ts +11 -0
- package/dist/auth/services/encryption.service.d.ts.map +1 -0
- package/dist/auth/services/encryption.service.js +49 -0
- package/dist/auth/services/encryption.service.js.map +1 -0
- package/dist/auth.config.d.ts +29 -0
- package/dist/auth.config.d.ts.map +1 -0
- package/dist/auth.config.js +71 -0
- package/dist/auth.config.js.map +1 -0
- package/dist/banking/banking.controller.d.ts +18 -0
- package/dist/banking/banking.controller.d.ts.map +1 -0
- package/dist/banking/banking.controller.js +146 -0
- package/dist/banking/banking.controller.js.map +1 -0
- package/dist/banking/banking.module.d.ts +6 -0
- package/dist/banking/banking.module.d.ts.map +1 -0
- package/dist/banking/banking.module.js +90 -0
- package/dist/banking/banking.module.js.map +1 -0
- package/dist/banking/dto/account-transfer.dto.d.ts +17 -0
- package/dist/banking/dto/account-transfer.dto.d.ts.map +1 -0
- package/dist/banking/dto/account-transfer.dto.js +101 -0
- package/dist/banking/dto/account-transfer.dto.js.map +1 -0
- package/dist/banking/dto/account.dto.d.ts +19 -0
- package/dist/banking/dto/account.dto.d.ts.map +1 -0
- package/dist/banking/dto/account.dto.js +104 -0
- package/dist/banking/dto/account.dto.js.map +1 -0
- package/dist/banking/dto/fetch-bank-balance.dto.d.ts +12 -0
- package/dist/banking/dto/fetch-bank-balance.dto.d.ts.map +1 -0
- package/dist/banking/dto/fetch-bank-balance.dto.js +71 -0
- package/dist/banking/dto/fetch-bank-balance.dto.js.map +1 -0
- package/dist/banking/dto/transaction-history.dto.d.ts +15 -0
- package/dist/banking/dto/transaction-history.dto.d.ts.map +1 -0
- package/dist/banking/dto/transaction-history.dto.js +89 -0
- package/dist/banking/dto/transaction-history.dto.js.map +1 -0
- package/dist/banking/factory/bank-strategy.factory.d.ts +9 -0
- package/dist/banking/factory/bank-strategy.factory.d.ts.map +1 -0
- package/dist/banking/factory/bank-strategy.factory.js +48 -0
- package/dist/banking/factory/bank-strategy.factory.js.map +1 -0
- package/dist/banking/interfaces/bank-config.interface.d.ts +22 -0
- package/dist/banking/interfaces/bank-config.interface.d.ts.map +1 -0
- package/dist/banking/interfaces/bank-config.interface.js +3 -0
- package/dist/banking/interfaces/bank-config.interface.js.map +1 -0
- package/dist/banking/interfaces/bank-service.interface.d.ts +19 -0
- package/dist/banking/interfaces/bank-service.interface.d.ts.map +1 -0
- package/dist/banking/interfaces/bank-service.interface.js +3 -0
- package/dist/banking/interfaces/bank-service.interface.js.map +1 -0
- package/dist/banking/services/ASPAC.service.d.ts +25 -0
- package/dist/banking/services/ASPAC.service.d.ts.map +1 -0
- package/dist/banking/services/ASPAC.service.js +498 -0
- package/dist/banking/services/ASPAC.service.js.map +1 -0
- package/dist/banking/services/BankGateway.service.d.ts +18 -0
- package/dist/banking/services/BankGateway.service.d.ts.map +1 -0
- package/dist/banking/services/BankGateway.service.js +71 -0
- package/dist/banking/services/BankGateway.service.js.map +1 -0
- package/dist/banking/services/MBWIN.service.d.ts +25 -0
- package/dist/banking/services/MBWIN.service.d.ts.map +1 -0
- package/dist/banking/services/MBWIN.service.js +655 -0
- package/dist/banking/services/MBWIN.service.js.map +1 -0
- package/dist/banking/services/WelcomeBank.service.d.ts +29 -0
- package/dist/banking/services/WelcomeBank.service.d.ts.map +1 -0
- package/dist/banking/services/WelcomeBank.service.js +840 -0
- package/dist/banking/services/WelcomeBank.service.js.map +1 -0
- package/dist/banking/services/sms.service.d.ts +10 -0
- package/dist/banking/services/sms.service.d.ts.map +1 -0
- package/dist/banking/services/sms.service.js +97 -0
- package/dist/banking/services/sms.service.js.map +1 -0
- package/dist/banking/tokens/bank-service.tokens.d.ts +5 -0
- package/dist/banking/tokens/bank-service.tokens.d.ts.map +1 -0
- package/dist/banking/tokens/bank-service.tokens.js +8 -0
- package/dist/banking/tokens/bank-service.tokens.js.map +1 -0
- package/dist/banking/types.d.ts +10 -0
- package/dist/banking/types.d.ts.map +1 -0
- package/dist/banking/types.js +3 -0
- package/dist/banking/types.js.map +1 -0
- package/dist/decorators/response_message.decorator.d.ts +2 -0
- package/dist/decorators/response_message.decorator.d.ts.map +1 -0
- package/dist/decorators/response_message.decorator.js +7 -0
- package/dist/decorators/response_message.decorator.js.map +1 -0
- package/dist/helpers/axios-error.helper.d.ts +6 -0
- package/dist/helpers/axios-error.helper.d.ts.map +1 -0
- package/dist/helpers/axios-error.helper.js +78 -0
- package/dist/helpers/axios-error.helper.js.map +1 -0
- package/dist/helpers/response-format.helper.d.ts +4 -0
- package/dist/helpers/response-format.helper.d.ts.map +1 -0
- package/dist/helpers/response-format.helper.js +15 -0
- package/dist/helpers/response-format.helper.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptors/response.interceptor.d.ts +16 -0
- package/dist/interceptors/response.interceptor.d.ts.map +1 -0
- package/dist/interceptors/response.interceptor.js +80 -0
- package/dist/interceptors/response.interceptor.js.map +1 -0
- package/dist/logger/logger-interceptor.d.ts +14 -0
- package/dist/logger/logger-interceptor.d.ts.map +1 -0
- package/dist/logger/logger-interceptor.js +60 -0
- package/dist/logger/logger-interceptor.js.map +1 -0
- package/dist/logger/logger-option.d.ts +6 -0
- package/dist/logger/logger-option.d.ts.map +1 -0
- package/dist/logger/logger-option.js +103 -0
- package/dist/logger/logger-option.js.map +1 -0
- package/dist/logger/logger.config.d.ts +3 -0
- package/dist/logger/logger.config.d.ts.map +1 -0
- package/dist/logger/logger.config.js +31 -0
- package/dist/logger/logger.config.js.map +1 -0
- package/dist/logger/logger.module.d.ts +3 -0
- package/dist/logger/logger.module.d.ts.map +1 -0
- package/dist/logger/logger.module.js +76 -0
- package/dist/logger/logger.module.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +13 -0
- package/dist/main.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/docker-compose.yml +14 -0
- package/ecosystem.config.js +35 -0
- package/eslint.config.mjs +34 -0
- package/nest-cli.json +8 -0
- package/package.json +102 -0
- package/src/app.module.ts +33 -0
- package/src/auth/apikey.guard.ts +42 -0
- package/src/auth/auth.controller.ts +41 -0
- package/src/auth/auth.interface.ts +7 -0
- package/src/auth/auth.module.ts +125 -0
- package/src/auth/constant.ts +1 -0
- package/src/auth/jwt-constant.ts +31 -0
- package/src/auth/jwt-guard.ts +5 -0
- package/src/auth/jwt-strategy.ts +43 -0
- package/src/auth/services/auth.service.ts +33 -0
- package/src/auth/services/encryption.service.ts +35 -0
- package/src/auth.config.ts +42 -0
- package/src/banking/banking.controller.ts +142 -0
- package/src/banking/banking.module.ts +142 -0
- package/src/banking/dto/account-transfer.dto.ts +66 -0
- package/src/banking/dto/account.dto.ts +70 -0
- package/src/banking/dto/fetch-bank-balance.dto.ts +46 -0
- package/src/banking/dto/transaction-history.dto.ts +58 -0
- package/src/banking/factory/bank-strategy.factory.ts +25 -0
- package/src/banking/interfaces/bank-config.interface.ts +25 -0
- package/src/banking/interfaces/bank-service.interface.ts +164 -0
- package/src/banking/services/ASPAC.service.ts +574 -0
- package/src/banking/services/BankGateway.service.ts +64 -0
- package/src/banking/services/MBWIN.service.ts +779 -0
- package/src/banking/services/WelcomeBank.service.ts +990 -0
- package/src/banking/services/sms.service.ts +50 -0
- package/src/banking/tokens/bank-service.tokens.ts +4 -0
- package/src/banking/types.ts +10 -0
- package/src/decorators/response_message.decorator.ts +4 -0
- package/src/helpers/axios-error.helper.ts +63 -0
- package/src/helpers/response-format.helper.ts +15 -0
- package/src/index.ts +15 -0
- package/src/interceptors/response.interceptor.ts +53 -0
- package/src/logger/logger-interceptor.ts +55 -0
- package/src/logger/logger-option.ts +119 -0
- package/src/logger/logger.config.ts +31 -0
- package/src/logger/logger.module.ts +31 -0
- package/src/main.ts +10 -0
- package/src/types/pino-daily-rotate-file.d.ts +31 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +22 -0
|
@@ -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
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,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,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
|
+
}
|