@toeichust/common 0.0.12 → 1.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.
@@ -10,8 +10,8 @@ exports.SWAGGER_DESCRIPTION = `<table border="0">
10
10
  <td>
11
11
  <h3>Giới thiệu</h3>
12
12
  <ul>
13
- <li>Đây là API cho <code>${process.env.npm_package_name || 'Tên mặc định'}</code></li>
14
- <li><a href="https://github.com/ToeicHUST/${process.env.npm_package_name || 'Tên mặc định'}">Xem thông tin github</a></li>
13
+ <li>Đây là API cho <code>${process.env.NAME_SERVICE || 'Tên mặc định'}</code></li>
14
+ <li><a href="https://github.com/${process.env.NAME_SERVICE || 'Tên mặc định'}">Xem thông tin github</a></li>
15
15
  </ul>
16
16
  <h3>JSON và YAML docs:</h3>
17
17
  <ul>
@@ -1 +1 @@
1
- {"version":3,"file":"swagger.constant.js","sourceRoot":"","sources":["../../src/constants/swagger.constant.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,MAAM,CAAC;AAC3B,QAAA,gBAAgB,GAAG,YAAY,CAAC;AAChC,QAAA,cAAc,GACzB,0DAA0D,CAAC;AAChD,QAAA,sBAAsB,GACjC,wGAAwG,CAAC;AAC9F,QAAA,mBAAmB,GAAG;;;;;mCAKA,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc;oDAC7B,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc;;;;wBAI1E,yBAAiB;wBACjB,yBAAiB;;;;kBAIvB,8BAAsB;;;SAG/B,CAAC"}
1
+ {"version":3,"file":"swagger.constant.js","sourceRoot":"","sources":["../../src/constants/swagger.constant.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,MAAM,CAAC;AAC3B,QAAA,gBAAgB,GAAG,YAAY,CAAC;AAChC,QAAA,cAAc,GACzB,0DAA0D,CAAC;AAChD,QAAA,sBAAsB,GACjC,wGAAwG,CAAC;AAC9F,QAAA,mBAAmB,GAAG;;;;;mCAKA,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,cAAc;0CACnC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,cAAc;;;;wBAI5D,yBAAiB;wBACjB,yBAAiB;;;;kBAIvB,8BAAsB;;;SAG/B,CAAC"}
@@ -4,7 +4,7 @@ exports.logAppBootstrap = logAppBootstrap;
4
4
  const swagger_constant_1 = require("../constants/swagger.constant");
5
5
  function logAppBootstrap(port) {
6
6
  console.log(`ENVIRONMENT: ${process.env.NODE_ENV}`);
7
- console.log(`NAME: ${process.env.npm_package_name}`);
7
+ console.log(`NAME: ${process.env.NAME_SERVICE}`);
8
8
  console.log(`PORT: ${port}`);
9
9
  console.log(`Application is running on: http://toeicHUST.local:${port}/${swagger_constant_1.SWAGGER_DOCS_PATH}`);
10
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.helper.js","sourceRoot":"","sources":["../../src/helpers/bootstrap.helper.ts"],"names":[],"mappings":";;AAEA,0CAWC;AAbD,oEAAmE;AAEnE,SAAgB,eAAe,CAAC,IAAqB;IAGnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CACT,qDAAqD,IAAI,IAAI,oCAAiB,EAAE,CACjF,CAAC;AAGJ,CAAC"}
1
+ {"version":3,"file":"bootstrap.helper.js","sourceRoot":"","sources":["../../src/helpers/bootstrap.helper.ts"],"names":[],"mappings":";;AAEA,0CAWC;AAbD,oEAAmE;AAEnE,SAAgB,eAAe,CAAC,IAAqB;IAGnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CACT,qDAAqD,IAAI,IAAI,oCAAiB,EAAE,CACjF,CAAC;AAGJ,CAAC"}
@@ -5,7 +5,7 @@ const swagger_1 = require("@nestjs/swagger");
5
5
  const swagger_constant_1 = require("../constants/swagger.constant");
6
6
  function setupSwagger(app) {
7
7
  const swaggerConfig = new swagger_1.DocumentBuilder()
8
- .setTitle(process.env.npm_package_name || 'Tên mặc định')
8
+ .setTitle(process.env.NAME_SERVICE || 'Tên mặc định')
9
9
  .setVersion(process.env.npm_package_version || '1.0.0')
10
10
  .setContact('vuvannghia.work@gmail.com', '', 'vuvannghia.work@gmail.com')
11
11
  .setDescription(swagger_constant_1.SWAGGER_DESCRIPTION)
@@ -23,7 +23,7 @@ function setupSwagger(app) {
23
23
  const baseOptions = {
24
24
  jsonDocumentUrl: `${swagger_constant_1.SWAGGER_DOCS_PATH}/json`,
25
25
  yamlDocumentUrl: `${swagger_constant_1.SWAGGER_DOCS_PATH}/yaml`,
26
- customSiteTitle: process.env.npm_package_name || 'Tên mặc định',
26
+ customSiteTitle: process.env.NAME_SERVICE || 'Tên mặc định',
27
27
  customfavIcon: `${swagger_constant_1.SWAGGER_CUSTOM_FAVICON}`,
28
28
  swaggerOptions: {
29
29
  persistAuthorization: true,
@@ -1 +1 @@
1
- {"version":3,"file":"swagger.helper.js","sourceRoot":"","sources":["../../src/helpers/swagger.helper.ts"],"names":[],"mappings":";;AAcA,oCA8DC;AA3ED,6CAAiE;AACjE,oEAMuC;AAMvC,SAAgB,YAAY,CAC1B,GAAqB;IAGrB,MAAM,aAAa,GAAG,IAAI,yBAAe,EAAE;SACxC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc,CAAC;SACxD,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC;SACtD,UAAU,CAAC,2BAA2B,EAAE,EAAE,EAAE,2BAA2B,CAAC;SACxE,cAAc,CAAC,sCAAmB,CAAC;SACnC,aAAa,CACZ;QACE,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,KAAK;QACnB,IAAI,EAAE,mCAAgB;QACtB,WAAW,EAAE,4BAA4B;QACzC,EAAE,EAAE,QAAQ;KACb,EACD,mCAAgB,CACjB;SACA,KAAK,EAAE,CAAC;IAEX,MAAM,eAAe,GAAG,GAAG,EAAE,CAC3B,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;IAG5D,MAAM,WAAW,GAAG;QAClB,eAAe,EAAE,GAAG,oCAAiB,OAAO;QAC5C,eAAe,EAAE,GAAG,oCAAiB,OAAO;QAC5C,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc;QAC/D,aAAa,EAAE,GAAG,yCAAsB,EAAE;QAC1C,cAAc,EAAE;YACd,oBAAoB,EAAE,IAAI;YAC1B,UAAU,EAAE,OAAO;YACnB,gBAAgB,EAAE,OAAO;SAE1B;KACF,CAAC;IAGF,MAAM,oBAAoB,GAAG,YAAY;QACvC,CAAC,CAAC;YACE,GAAG,WAAW;YACd,QAAQ,EAAE;gBACR,GAAG,iCAAc,2BAA2B;gBAC5C,GAAG,iCAAc,sCAAsC;aACxD;YACD,YAAY,EAAE;gBACZ,GAAG,iCAAc,qBAAqB;gBACtC,GAAG,iCAAc,iBAAiB;aACnC;SACF;QACH,CAAC,CAAC,WAAW,CAAC;IAEhB,uBAAa,CAAC,KAAK,CACjB,oCAAiB,EACjB,GAAG,EACH,eAAe,EACf,oBAAoB,CACrB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"swagger.helper.js","sourceRoot":"","sources":["../../src/helpers/swagger.helper.ts"],"names":[],"mappings":";;AAcA,oCA8DC;AA3ED,6CAAiE;AACjE,oEAMuC;AAMvC,SAAgB,YAAY,CAC1B,GAAqB;IAGrB,MAAM,aAAa,GAAG,IAAI,yBAAe,EAAE;SACxC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,cAAc,CAAC;SACpD,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC;SACtD,UAAU,CAAC,2BAA2B,EAAE,EAAE,EAAE,2BAA2B,CAAC;SACxE,cAAc,CAAC,sCAAmB,CAAC;SACnC,aAAa,CACZ;QACE,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,KAAK;QACnB,IAAI,EAAE,mCAAgB;QACtB,WAAW,EAAE,4BAA4B;QACzC,EAAE,EAAE,QAAQ;KACb,EACD,mCAAgB,CACjB;SACA,KAAK,EAAE,CAAC;IAEX,MAAM,eAAe,GAAG,GAAG,EAAE,CAC3B,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;IAG5D,MAAM,WAAW,GAAG;QAClB,eAAe,EAAE,GAAG,oCAAiB,OAAO;QAC5C,eAAe,EAAE,GAAG,oCAAiB,OAAO;QAC5C,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,cAAc;QAC3D,aAAa,EAAE,GAAG,yCAAsB,EAAE;QAC1C,cAAc,EAAE;YACd,oBAAoB,EAAE,IAAI;YAC1B,UAAU,EAAE,OAAO;YACnB,gBAAgB,EAAE,OAAO;SAE1B;KACF,CAAC;IAGF,MAAM,oBAAoB,GAAG,YAAY;QACvC,CAAC,CAAC;YACE,GAAG,WAAW;YACd,QAAQ,EAAE;gBACR,GAAG,iCAAc,2BAA2B;gBAC5C,GAAG,iCAAc,sCAAsC;aACxD;YACD,YAAY,EAAE;gBACZ,GAAG,iCAAc,qBAAqB;gBACtC,GAAG,iCAAc,iBAAiB;aACnC;SACF;QACH,CAAC,CAAC,WAAW,CAAC;IAEhB,uBAAa,CAAC,KAAK,CACjB,oCAAiB,EACjB,GAAG,EACH,eAAe,EACf,oBAAoB,CACrB,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,3 +2,6 @@ export * from './constants/swagger.constant';
2
2
  export * from './helpers/bootstrap.helper';
3
3
  export * from './helpers/swagger.helper';
4
4
  export * from './middlewares/logger.middleware';
5
+ export * from './modules/vault/vault.module';
6
+ export * from './modules/vault/vault.service.spec';
7
+ export * from './modules/vault/vault.service';
package/dist/index.js CHANGED
@@ -18,4 +18,7 @@ __exportStar(require("./constants/swagger.constant"), exports);
18
18
  __exportStar(require("./helpers/bootstrap.helper"), exports);
19
19
  __exportStar(require("./helpers/swagger.helper"), exports);
20
20
  __exportStar(require("./middlewares/logger.middleware"), exports);
21
+ __exportStar(require("./modules/vault/vault.module"), exports);
22
+ __exportStar(require("./modules/vault/vault.service.spec"), exports);
23
+ __exportStar(require("./modules/vault/vault.service"), exports);
21
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAIA,+DAA6C;AAC7C,6DAA2C;AAC3C,2DAAyC;AACzC,kEAAgD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAIA,+DAA6C;AAC7C,6DAA2C;AAC3C,2DAAyC;AACzC,kEAAgD;AAChD,+DAA6C;AAC7C,qEAAmD;AACnD,gEAA8C"}
@@ -0,0 +1,2 @@
1
+ export declare class VaultModule {
2
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.VaultModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const vault_service_1 = require("./vault.service");
12
+ const config_1 = require("@nestjs/config");
13
+ let VaultModule = class VaultModule {
14
+ };
15
+ exports.VaultModule = VaultModule;
16
+ exports.VaultModule = VaultModule = __decorate([
17
+ (0, common_1.Global)(),
18
+ (0, common_1.Module)({
19
+ imports: [config_1.ConfigModule],
20
+ providers: [
21
+ {
22
+ provide: vault_service_1.VaultService,
23
+ useFactory: async (configService) => {
24
+ const vaultService = new vault_service_1.VaultService(configService);
25
+ await vaultService.loadSecrets();
26
+ return vaultService;
27
+ },
28
+ inject: [config_1.ConfigService],
29
+ },
30
+ ],
31
+ exports: [vault_service_1.VaultService],
32
+ })
33
+ ], VaultModule);
34
+ //# sourceMappingURL=vault.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.module.js","sourceRoot":"","sources":["../../../src/modules/vault/vault.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAChD,mDAA+C;AAC/C,2CAA6D;AAoBtD,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,kCAAW;sBAAX,WAAW;IAlBvB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,qBAAY,CAAC;QACvB,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,4BAAY;gBACrB,UAAU,EAAE,KAAK,EAAE,aAA4B,EAAE,EAAE;oBACjD,MAAM,YAAY,GAAG,IAAI,4BAAY,CAAC,aAAa,CAAC,CAAC;oBAErD,MAAM,YAAY,CAAC,WAAW,EAAE,CAAC;oBAEjC,OAAO,YAAY,CAAC;gBACtB,CAAC;gBACD,MAAM,EAAE,CAAC,sBAAa,CAAC;aACxB;SACF;QACD,OAAO,EAAE,CAAC,4BAAY,CAAC;KACxB,CAAC;GACW,WAAW,CAAG"}
@@ -0,0 +1,10 @@
1
+ import { ConfigService } from '@nestjs/config';
2
+ export declare class VaultService {
3
+ private configService;
4
+ constructor(configService: ConfigService);
5
+ private readonly logger;
6
+ private vaultClient;
7
+ private secrets;
8
+ loadSecrets(): Promise<void>;
9
+ get<T = string>(key: string): T;
10
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ var VaultService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.VaultService = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const config_1 = require("@nestjs/config");
19
+ const node_vault_1 = __importDefault(require("node-vault"));
20
+ let VaultService = VaultService_1 = class VaultService {
21
+ configService;
22
+ constructor(configService) {
23
+ this.configService = configService;
24
+ }
25
+ logger = new common_1.Logger(VaultService_1.name);
26
+ vaultClient;
27
+ secrets = {};
28
+ async loadSecrets() {
29
+ this.logger.log('Đang kết nối tới Vault...');
30
+ const NODE_ENV = this.configService.get('NODE_ENV');
31
+ const isDevelopment = NODE_ENV === 'development';
32
+ const VAULT_ADDR = this.configService.get('VAULT_ADDR');
33
+ const VAULT_ROLE_ID = this.configService.get('VAULT_ROLE_ID');
34
+ const VAULT_SECRET_ID = this.configService.get('VAULT_SECRET_ID');
35
+ const VAULT_DATA_PATH = this.configService.get('VAULT_DATA_PATH');
36
+ if (!VAULT_ADDR || !VAULT_ROLE_ID || !VAULT_SECRET_ID) {
37
+ this.logger.error('Thiếu cấu hình Vault (ADDR, ROLE_ID hoặc SECRET_ID)');
38
+ throw new Error('Missing Vault configuration');
39
+ }
40
+ this.vaultClient = (0, node_vault_1.default)({
41
+ apiVersion: 'v1',
42
+ endpoint: VAULT_ADDR,
43
+ });
44
+ try {
45
+ const loginResult = await this.vaultClient.approleLogin({
46
+ role_id: VAULT_ROLE_ID,
47
+ secret_id: VAULT_SECRET_ID,
48
+ });
49
+ this.vaultClient.token = loginResult.auth.client_token;
50
+ const vaultPath = VAULT_DATA_PATH || 'secret/data/myapp';
51
+ const response = await this.vaultClient.read(vaultPath);
52
+ let fetchedSecrets = {};
53
+ if (response.data && response.data.data && response.data.metadata) {
54
+ fetchedSecrets = response.data.data;
55
+ }
56
+ else {
57
+ fetchedSecrets = response.data || {};
58
+ }
59
+ if (isDevelopment) {
60
+ const overriddenKeys = [];
61
+ Object.keys(fetchedSecrets).forEach((key) => {
62
+ const envValue = this.configService.get(key);
63
+ if (envValue !== undefined && envValue !== null && envValue !== '') {
64
+ fetchedSecrets[key] = envValue;
65
+ overriddenKeys.push(key);
66
+ }
67
+ });
68
+ this.secrets = fetchedSecrets;
69
+ if (overriddenKeys.length > 0) {
70
+ this.logger.warn(`⚠️ Các biến sau đây đang sử dụng giá trị từ ENV (ghi đè Vault): ${overriddenKeys.join(', ')}`);
71
+ }
72
+ }
73
+ else {
74
+ this.secrets = fetchedSecrets;
75
+ }
76
+ this.logger.log('Đã kết nối và lấy dữ liệu thành công từ Vault');
77
+ }
78
+ catch (error) {
79
+ this.logger.error(`Lỗi kết nối Vault: ${error.message}`, error.stack);
80
+ throw error;
81
+ }
82
+ }
83
+ get(key) {
84
+ return this.secrets[key];
85
+ }
86
+ };
87
+ exports.VaultService = VaultService;
88
+ exports.VaultService = VaultService = VaultService_1 = __decorate([
89
+ (0, common_1.Injectable)(),
90
+ __metadata("design:paramtypes", [config_1.ConfigService])
91
+ ], VaultService);
92
+ //# sourceMappingURL=vault.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.service.js","sourceRoot":"","sources":["../../../src/modules/vault/vault.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const testing_1 = require("@nestjs/testing");
7
+ const config_1 = require("@nestjs/config");
8
+ const vault_service_1 = require("./vault.service");
9
+ const node_vault_1 = __importDefault(require("node-vault"));
10
+ jest.mock('node-vault');
11
+ describe('VaultService', () => {
12
+ let service;
13
+ let configService;
14
+ let mockVaultClient;
15
+ beforeEach(async () => {
16
+ mockVaultClient = {
17
+ approleLogin: jest.fn(),
18
+ read: jest.fn(),
19
+ token: null,
20
+ };
21
+ node_vault_1.default.mockReturnValue(mockVaultClient);
22
+ const module = await testing_1.Test.createTestingModule({
23
+ providers: [
24
+ vault_service_1.VaultService,
25
+ {
26
+ provide: config_1.ConfigService,
27
+ useValue: {
28
+ get: jest.fn(),
29
+ },
30
+ },
31
+ ],
32
+ }).compile();
33
+ service = module.get(vault_service_1.VaultService);
34
+ configService = module.get(config_1.ConfigService);
35
+ });
36
+ it('should be defined', () => {
37
+ expect(service).toBeDefined();
38
+ });
39
+ describe('loadSecrets', () => {
40
+ it('should throw error when VAULT_ADDR is missing', async () => {
41
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
42
+ if (key === 'VAULT_ROLE_ID')
43
+ return 'test-role-id';
44
+ if (key === 'VAULT_SECRET_ID')
45
+ return 'test-secret-id';
46
+ return undefined;
47
+ });
48
+ await expect(service.loadSecrets()).rejects.toThrow('Missing Vault configuration');
49
+ });
50
+ it('should throw error when VAULT_ROLE_ID is missing', async () => {
51
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
52
+ if (key === 'VAULT_ADDR')
53
+ return 'http://localhost:8200';
54
+ if (key === 'VAULT_SECRET_ID')
55
+ return 'test-secret-id';
56
+ return undefined;
57
+ });
58
+ await expect(service.loadSecrets()).rejects.toThrow('Missing Vault configuration');
59
+ });
60
+ it('should throw error when VAULT_SECRET_ID is missing', async () => {
61
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
62
+ if (key === 'VAULT_ADDR')
63
+ return 'http://localhost:8200';
64
+ if (key === 'VAULT_ROLE_ID')
65
+ return 'test-role-id';
66
+ return undefined;
67
+ });
68
+ await expect(service.loadSecrets()).rejects.toThrow('Missing Vault configuration');
69
+ });
70
+ it('should successfully connect to Vault and fetch secrets with KV v2 engine', async () => {
71
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
72
+ const config = {
73
+ NODE_ENV: 'production',
74
+ VAULT_ADDR: 'http://localhost:8200',
75
+ VAULT_ROLE_ID: 'test-role-id',
76
+ VAULT_SECRET_ID: 'test-secret-id',
77
+ VAULT_DATA_PATH: 'secret/data/myapp',
78
+ };
79
+ return config[key];
80
+ });
81
+ mockVaultClient.approleLogin.mockResolvedValue({
82
+ auth: { client_token: 'test-token' },
83
+ });
84
+ mockVaultClient.read.mockResolvedValue({
85
+ data: {
86
+ data: { DB_HOST: 'localhost', DB_PORT: '5432' },
87
+ metadata: { version: 1 },
88
+ },
89
+ });
90
+ await service.loadSecrets();
91
+ expect(mockVaultClient.approleLogin).toHaveBeenCalledWith({
92
+ role_id: 'test-role-id',
93
+ secret_id: 'test-secret-id',
94
+ });
95
+ expect(mockVaultClient.token).toBe('test-token');
96
+ expect(mockVaultClient.read).toHaveBeenCalledWith('secret/data/myapp');
97
+ });
98
+ it('should successfully fetch secrets with KV v1 engine', async () => {
99
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
100
+ const config = {
101
+ NODE_ENV: 'production',
102
+ VAULT_ADDR: 'http://localhost:8200',
103
+ VAULT_ROLE_ID: 'test-role-id',
104
+ VAULT_SECRET_ID: 'test-secret-id',
105
+ VAULT_DATA_PATH: 'secret/myapp',
106
+ };
107
+ return config[key];
108
+ });
109
+ mockVaultClient.approleLogin.mockResolvedValue({
110
+ auth: { client_token: 'test-token' },
111
+ });
112
+ mockVaultClient.read.mockResolvedValue({
113
+ data: { API_KEY: 'secret-key', DB_PASSWORD: 'password123' },
114
+ });
115
+ await service.loadSecrets();
116
+ expect(service.get('API_KEY')).toBe('secret-key');
117
+ expect(service.get('DB_PASSWORD')).toBe('password123');
118
+ });
119
+ it('should override Vault secrets with ENV variables in development mode', async () => {
120
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
121
+ const config = {
122
+ NODE_ENV: 'development',
123
+ VAULT_ADDR: 'http://localhost:8200',
124
+ VAULT_ROLE_ID: 'test-role-id',
125
+ VAULT_SECRET_ID: 'test-secret-id',
126
+ VAULT_DATA_PATH: 'secret/data/myapp',
127
+ DB_HOST: 'localhost-override',
128
+ };
129
+ return config[key];
130
+ });
131
+ mockVaultClient.approleLogin.mockResolvedValue({
132
+ auth: { client_token: 'test-token' },
133
+ });
134
+ mockVaultClient.read.mockResolvedValue({
135
+ data: {
136
+ data: { DB_HOST: 'vault-host', DB_PORT: '5432' },
137
+ metadata: { version: 1 },
138
+ },
139
+ });
140
+ await service.loadSecrets();
141
+ expect(service.get('DB_HOST')).toBe('localhost-override');
142
+ expect(service.get('DB_PORT')).toBe('5432');
143
+ });
144
+ it('should not override Vault secrets with empty ENV variables in development mode', async () => {
145
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
146
+ const config = {
147
+ NODE_ENV: 'development',
148
+ VAULT_ADDR: 'http://localhost:8200',
149
+ VAULT_ROLE_ID: 'test-role-id',
150
+ VAULT_SECRET_ID: 'test-secret-id',
151
+ DB_HOST: '',
152
+ };
153
+ return config[key];
154
+ });
155
+ mockVaultClient.approleLogin.mockResolvedValue({
156
+ auth: { client_token: 'test-token' },
157
+ });
158
+ mockVaultClient.read.mockResolvedValue({
159
+ data: {
160
+ data: { DB_HOST: 'vault-host' },
161
+ metadata: { version: 1 },
162
+ },
163
+ });
164
+ await service.loadSecrets();
165
+ expect(service.get('DB_HOST')).toBe('vault-host');
166
+ });
167
+ it('should throw error when Vault login fails', async () => {
168
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
169
+ const config = {
170
+ VAULT_ADDR: 'http://localhost:8200',
171
+ VAULT_ROLE_ID: 'test-role-id',
172
+ VAULT_SECRET_ID: 'test-secret-id',
173
+ };
174
+ return config[key];
175
+ });
176
+ mockVaultClient.approleLogin.mockRejectedValue(new Error('Authentication failed'));
177
+ await expect(service.loadSecrets()).rejects.toThrow('Authentication failed');
178
+ });
179
+ it('should throw error when reading Vault path fails', async () => {
180
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
181
+ const config = {
182
+ VAULT_ADDR: 'http://localhost:8200',
183
+ VAULT_ROLE_ID: 'test-role-id',
184
+ VAULT_SECRET_ID: 'test-secret-id',
185
+ VAULT_DATA_PATH: 'secret/data/myapp',
186
+ };
187
+ return config[key];
188
+ });
189
+ mockVaultClient.approleLogin.mockResolvedValue({
190
+ auth: { client_token: 'test-token' },
191
+ });
192
+ mockVaultClient.read.mockRejectedValue(new Error('Path not found'));
193
+ await expect(service.loadSecrets()).rejects.toThrow('Path not found');
194
+ });
195
+ it('should use default VAULT_DATA_PATH when not provided', async () => {
196
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
197
+ const config = {
198
+ VAULT_ADDR: 'http://localhost:8200',
199
+ VAULT_ROLE_ID: 'test-role-id',
200
+ VAULT_SECRET_ID: 'test-secret-id',
201
+ };
202
+ return config[key];
203
+ });
204
+ mockVaultClient.approleLogin.mockResolvedValue({
205
+ auth: { client_token: 'test-token' },
206
+ });
207
+ mockVaultClient.read.mockResolvedValue({
208
+ data: { data: {}, metadata: { version: 1 } },
209
+ });
210
+ await service.loadSecrets();
211
+ expect(mockVaultClient.read).toHaveBeenCalledWith('secret/data/myapp');
212
+ });
213
+ });
214
+ describe('get', () => {
215
+ it('should return secret value for existing key', async () => {
216
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
217
+ const config = {
218
+ NODE_ENV: 'production',
219
+ VAULT_ADDR: 'http://localhost:8200',
220
+ VAULT_ROLE_ID: 'test-role-id',
221
+ VAULT_SECRET_ID: 'test-secret-id',
222
+ };
223
+ return config[key];
224
+ });
225
+ mockVaultClient.approleLogin.mockResolvedValue({
226
+ auth: { client_token: 'test-token' },
227
+ });
228
+ mockVaultClient.read.mockResolvedValue({
229
+ data: {
230
+ data: { API_KEY: 'my-secret-key' },
231
+ metadata: { version: 1 },
232
+ },
233
+ });
234
+ await service.loadSecrets();
235
+ expect(service.get('API_KEY')).toBe('my-secret-key');
236
+ });
237
+ it('should return undefined for non-existing key', async () => {
238
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
239
+ const config = {
240
+ NODE_ENV: 'production',
241
+ VAULT_ADDR: 'http://localhost:8200',
242
+ VAULT_ROLE_ID: 'test-role-id',
243
+ VAULT_SECRET_ID: 'test-secret-id',
244
+ };
245
+ return config[key];
246
+ });
247
+ mockVaultClient.approleLogin.mockResolvedValue({
248
+ auth: { client_token: 'test-token' },
249
+ });
250
+ mockVaultClient.read.mockResolvedValue({
251
+ data: { data: {}, metadata: { version: 1 } },
252
+ });
253
+ await service.loadSecrets();
254
+ expect(service.get('NON_EXISTING_KEY')).toBeUndefined();
255
+ });
256
+ it('should return typed value when type parameter is provided', async () => {
257
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
258
+ const config = {
259
+ NODE_ENV: 'production',
260
+ VAULT_ADDR: 'http://localhost:8200',
261
+ VAULT_ROLE_ID: 'test-role-id',
262
+ VAULT_SECRET_ID: 'test-secret-id',
263
+ };
264
+ return config[key];
265
+ });
266
+ mockVaultClient.approleLogin.mockResolvedValue({
267
+ auth: { client_token: 'test-token' },
268
+ });
269
+ mockVaultClient.read.mockResolvedValue({
270
+ data: {
271
+ data: { PORT: '3000', IS_ENABLED: 'true' },
272
+ metadata: { version: 1 },
273
+ },
274
+ });
275
+ await service.loadSecrets();
276
+ const port = service.get('PORT');
277
+ const isEnabled = service.get('IS_ENABLED');
278
+ expect(port).toBe('3000');
279
+ expect(isEnabled).toBe('true');
280
+ });
281
+ it('should fallback to empty object when response.data is null in KV v1', async () => {
282
+ jest.spyOn(configService, 'get').mockImplementation((key) => {
283
+ if (key === 'VAULT_ADDR')
284
+ return 'http://localhost:8200';
285
+ if (key === 'VAULT_ROLE_ID')
286
+ return 'test-role-id';
287
+ if (key === 'VAULT_SECRET_ID')
288
+ return 'test-secret-id';
289
+ return undefined;
290
+ });
291
+ mockVaultClient.approleLogin.mockResolvedValue({
292
+ auth: { client_token: 'test-token' },
293
+ });
294
+ mockVaultClient.read.mockResolvedValue({ data: null });
295
+ await service.loadSecrets();
296
+ expect(service.get('ANY_KEY')).toBeUndefined();
297
+ });
298
+ });
299
+ });
300
+ //# sourceMappingURL=vault.service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.service.spec.js","sourceRoot":"","sources":["../../../src/modules/vault/vault.service.spec.ts"],"names":[],"mappings":"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"}