@nest-boot/hash 7.0.2 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,6 +49,18 @@ let HashModule = class HashModule extends hash_module_definition_1.ConfigurableM
49
49
  exports.HashModule = HashModule;
50
50
  exports.HashModule = HashModule = __decorate([
51
51
  (0, common_1.Global)(),
52
- (0, common_1.Module)({ providers: [hash_service_1.HashService], exports: [hash_service_1.HashService] })
52
+ (0, common_1.Module)({
53
+ providers: [
54
+ {
55
+ provide: hash_service_1.HashService,
56
+ inject: [{ token: hash_module_definition_1.MODULE_OPTIONS_TOKEN, optional: true }],
57
+ useFactory: (options) => {
58
+ hash_service_1.HashService.init(options.secret ?? process.env.HASH_SECRET ?? process.env.APP_SECRET);
59
+ return hash_service_1.HashService.instance;
60
+ },
61
+ },
62
+ ],
63
+ exports: [hash_service_1.HashService],
64
+ })
53
65
  ], HashModule);
54
66
  //# sourceMappingURL=hash.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash.module.js","sourceRoot":"","sources":["../src/hash.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAoE;AAEpE,qEAIkC;AAClC,iDAA6C;AAE7C;;;;;;;;;;;;;;;;;GAiBG;AAGI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,gDAAuB;IACrD;;;;OAIG;IACH,MAAM,CAAU,QAAQ,CAAC,OAA4B;QACnD,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAU,aAAa,CAC3B,OAAkC;QAElC,OAAO,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;CACF,CAAA;AApBY,gCAAU;qBAAV,UAAU;IAFtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,SAAS,EAAE,CAAC,0BAAW,CAAC,EAAE,OAAO,EAAE,CAAC,0BAAW,CAAC,EAAE,CAAC;GAChD,UAAU,CAoBtB"}
1
+ {"version":3,"file":"hash.module.js","sourceRoot":"","sources":["../src/hash.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAoE;AAEpE,qEAKkC;AAClC,iDAA6C;AAG7C;;;;;;;;;;;;;;;;;GAiBG;AAkBI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,gDAAuB;IACrD;;;;OAIG;IACH,MAAM,CAAU,QAAQ,CAAC,OAA4B;QACnD,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAU,aAAa,CAC3B,OAAkC;QAElC,OAAO,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;CACF,CAAA;AApBY,gCAAU;qBAAV,UAAU;IAjBtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,0BAAW;gBACpB,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,6CAAoB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACzD,UAAU,EAAE,CAAC,OAA0B,EAAE,EAAE;oBACzC,0BAAW,CAAC,IAAI,CACd,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CACpE,CAAC;oBAEF,OAAO,0BAAW,CAAC,QAAQ,CAAC;gBAC9B,CAAC;aACF;SACF;QACD,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;GACW,UAAU,CAoBtB"}
@@ -1,4 +1,3 @@
1
- import { HashModuleOptions } from "./hash-module-options.interface";
2
1
  /**
3
2
  * Service that provides password hashing and verification using Argon2 algorithm.
4
3
  *
@@ -6,32 +5,71 @@ import { HashModuleOptions } from "./hash-module-options.interface";
6
5
  * ```typescript
7
6
  * import { HashService } from '@nest-boot/hash';
8
7
  *
9
- * @Injectable()
10
- * export class AuthService {
11
- * constructor(private readonly hashService: HashService) {}
8
+ * // Initialize at application startup
9
+ * HashService.init(process.env.HASH_SECRET);
12
10
  *
13
- * async hashPassword(password: string): Promise<string> {
14
- * return this.hashService.create(password);
15
- * }
16
- *
17
- * async verifyPassword(hash: string, password: string): Promise<boolean> {
18
- * return this.hashService.verify(hash, password);
19
- * }
20
- * }
11
+ * // Use static methods
12
+ * const hashed = await HashService.hash(password);
13
+ * const isValid = await HashService.verify(hashed, password);
21
14
  * ```
22
15
  */
23
16
  export declare class HashService {
17
+ private static _instance?;
18
+ /**
19
+ * Gets the static HashService instance.
20
+ * @throws Error if HashService has not been initialized via `init()`
21
+ * @returns The HashService instance
22
+ */
23
+ static get instance(): HashService;
24
+ /**
25
+ * Initializes the static HashService instance with the given secret.
26
+ * Call this method at application startup to configure the default secret.
27
+ *
28
+ * @param secret - The secret key to use for hashing
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // In your application bootstrap
33
+ * HashService.init(process.env.HASH_SECRET);
34
+ * ```
35
+ */
36
+ static init(secret?: string): void;
37
+ /**
38
+ * Creates a hash from the given value using the static instance.
39
+ * @param value - The value to hash (password or other sensitive data)
40
+ * @param secret - Optional secret key to use instead of the default
41
+ * @returns The hashed string
42
+ * @throws Error if HashService has not been initialized via `init()`
43
+ */
44
+ static hash(value: string | Buffer, secret?: string): Promise<string>;
45
+ /**
46
+ * Verifies a value against a hash using the static instance.
47
+ * @param hashed - The hash to verify against
48
+ * @param value - The value to verify
49
+ * @param secret - Optional secret key to use instead of the default
50
+ * @returns True if the value matches the hash, false otherwise
51
+ * @throws Error if HashService has not been initialized via `init()`
52
+ */
53
+ static verify(hashed: string | Buffer, value: string | Buffer, secret?: string): Promise<boolean>;
24
54
  private readonly secret?;
25
55
  /**
26
56
  * Creates an instance of HashService.
27
- * @param options - Configuration options for the hash service
57
+ * @param secret - Optional secret key to use for hashing
58
+ */
59
+ constructor(secret?: string);
60
+ /**
61
+ * Creates a hash from the given value using Argon2.
62
+ * @param value - The value to hash (password or other sensitive data)
63
+ * @param secret - Optional secret key to use instead of the default
64
+ * @returns The hashed string
28
65
  */
29
- constructor(options?: HashModuleOptions);
66
+ hash(value: string | Buffer, secret?: string): Promise<string>;
30
67
  /**
31
68
  * Creates a hash from the given value using Argon2.
32
69
  * @param value - The value to hash (password or other sensitive data)
33
70
  * @param secret - Optional secret key to use instead of the default
34
71
  * @returns The hashed string
72
+ * @deprecated Use `hash` instead
35
73
  */
36
74
  create(value: string | Buffer, secret?: string): Promise<string>;
37
75
  /**
@@ -1,21 +1,7 @@
1
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
- return function (target, key) { decorator(target, key, paramIndex); }
13
- };
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
3
  exports.HashService = void 0;
16
- const common_1 = require("@nestjs/common");
17
4
  const argon2_1 = require("@node-rs/argon2");
18
- const hash_module_definition_1 = require("./hash.module-definition");
19
5
  /**
20
6
  * Service that provides password hashing and verification using Argon2 algorithm.
21
7
  *
@@ -23,30 +9,68 @@ const hash_module_definition_1 = require("./hash.module-definition");
23
9
  * ```typescript
24
10
  * import { HashService } from '@nest-boot/hash';
25
11
  *
26
- * @Injectable()
27
- * export class AuthService {
28
- * constructor(private readonly hashService: HashService) {}
12
+ * // Initialize at application startup
13
+ * HashService.init(process.env.HASH_SECRET);
29
14
  *
30
- * async hashPassword(password: string): Promise<string> {
31
- * return this.hashService.create(password);
32
- * }
33
- *
34
- * async verifyPassword(hash: string, password: string): Promise<boolean> {
35
- * return this.hashService.verify(hash, password);
36
- * }
37
- * }
15
+ * // Use static methods
16
+ * const hashed = await HashService.hash(password);
17
+ * const isValid = await HashService.verify(hashed, password);
38
18
  * ```
39
19
  */
40
- let HashService = class HashService {
20
+ class HashService {
41
21
  /**
42
- * Creates an instance of HashService.
43
- * @param options - Configuration options for the hash service
22
+ * Gets the static HashService instance.
23
+ * @throws Error if HashService has not been initialized via `init()`
24
+ * @returns The HashService instance
44
25
  */
45
- constructor(options = {}) {
46
- const secret = options.secret ?? process.env.HASH_SECRET ?? process.env.APP_SECRET;
47
- if (secret) {
48
- this.secret = Buffer.from(secret);
26
+ static get instance() {
27
+ if (!this._instance) {
28
+ throw new Error("HashService not initialized");
49
29
  }
30
+ return this._instance;
31
+ }
32
+ /**
33
+ * Initializes the static HashService instance with the given secret.
34
+ * Call this method at application startup to configure the default secret.
35
+ *
36
+ * @param secret - The secret key to use for hashing
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // In your application bootstrap
41
+ * HashService.init(process.env.HASH_SECRET);
42
+ * ```
43
+ */
44
+ static init(secret) {
45
+ this._instance = new HashService(secret);
46
+ }
47
+ /**
48
+ * Creates a hash from the given value using the static instance.
49
+ * @param value - The value to hash (password or other sensitive data)
50
+ * @param secret - Optional secret key to use instead of the default
51
+ * @returns The hashed string
52
+ * @throws Error if HashService has not been initialized via `init()`
53
+ */
54
+ static hash(value, secret) {
55
+ return this.instance.hash(value, secret);
56
+ }
57
+ /**
58
+ * Verifies a value against a hash using the static instance.
59
+ * @param hashed - The hash to verify against
60
+ * @param value - The value to verify
61
+ * @param secret - Optional secret key to use instead of the default
62
+ * @returns True if the value matches the hash, false otherwise
63
+ * @throws Error if HashService has not been initialized via `init()`
64
+ */
65
+ static verify(hashed, value, secret) {
66
+ return this.instance.verify(hashed, value, secret);
67
+ }
68
+ /**
69
+ * Creates an instance of HashService.
70
+ * @param secret - Optional secret key to use for hashing
71
+ */
72
+ constructor(secret) {
73
+ this.secret = secret ? Buffer.from(secret) : undefined;
50
74
  }
51
75
  /**
52
76
  * Creates a hash from the given value using Argon2.
@@ -54,11 +78,21 @@ let HashService = class HashService {
54
78
  * @param secret - Optional secret key to use instead of the default
55
79
  * @returns The hashed string
56
80
  */
57
- async create(value, secret) {
81
+ async hash(value, secret) {
58
82
  return await (0, argon2_1.hash)(value, {
59
83
  secret: typeof secret !== "undefined" ? Buffer.from(secret) : this.secret,
60
84
  });
61
85
  }
86
+ /**
87
+ * Creates a hash from the given value using Argon2.
88
+ * @param value - The value to hash (password or other sensitive data)
89
+ * @param secret - Optional secret key to use instead of the default
90
+ * @returns The hashed string
91
+ * @deprecated Use `hash` instead
92
+ */
93
+ async create(value, secret) {
94
+ return await this.hash(value, secret);
95
+ }
62
96
  /**
63
97
  * Verifies a value against a hash.
64
98
  * @param hashed - The hash to verify against
@@ -71,12 +105,6 @@ let HashService = class HashService {
71
105
  secret: typeof secret !== "undefined" ? Buffer.from(secret) : this.secret,
72
106
  });
73
107
  }
74
- };
108
+ }
75
109
  exports.HashService = HashService;
76
- exports.HashService = HashService = __decorate([
77
- (0, common_1.Injectable)(),
78
- __param(0, (0, common_1.Optional)()),
79
- __param(0, (0, common_1.Inject)(hash_module_definition_1.MODULE_OPTIONS_TOKEN)),
80
- __metadata("design:paramtypes", [Object])
81
- ], HashService);
82
110
  //# sourceMappingURL=hash.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash.service.js","sourceRoot":"","sources":["../src/hash.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA8D;AAC9D,4CAA+C;AAE/C,qEAAgE;AAGhE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAW;IAGtB;;;OAGG;IACH,YAGE,UAA6B,EAAE;QAE/B,MAAM,MAAM,GACV,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAEtE,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,KAAsB,EAAE,MAAe;QAClD,OAAO,MAAM,IAAA,aAAI,EAAC,KAAK,EAAE;YACvB,MAAM,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;SAC1E,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CACV,MAAuB,EACvB,KAAsB,EACtB,MAAe;QAEf,OAAO,MAAM,IAAA,eAAM,EAAC,MAAM,EAAE,KAAK,EAAE;YACjC,MAAM,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;SAC1E,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAhDY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;IASR,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,6CAAoB,CAAC,CAAA;;GATpB,WAAW,CAgDvB"}
1
+ {"version":3,"file":"hash.service.js","sourceRoot":"","sources":["../src/hash.service.ts"],"names":[],"mappings":";;;AAAA,4CAA+C;AAE/C;;;;;;;;;;;;;;GAcG;AAEH,MAAa,WAAW;IAGtB;;;;OAIG;IACH,MAAM,KAAK,QAAQ;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,IAAI,CAAC,MAAe;QACzB,IAAI,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,KAAsB,EAAE,MAAe;QACjD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CACX,MAAuB,EACvB,KAAsB,EACtB,MAAe;QAEf,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAID;;;OAGG;IACH,YAAY,MAAe;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,KAAsB,EAAE,MAAe;QAChD,OAAO,MAAM,IAAA,aAAI,EAAC,KAAK,EAAE;YACvB,MAAM,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;SAC1E,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CAAC,KAAsB,EAAE,MAAe;QAClD,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CACV,MAAuB,EACvB,KAAsB,EACtB,MAAe;QAEf,OAAO,MAAM,IAAA,eAAM,EAAC,MAAM,EAAE,KAAK,EAAE;YACjC,MAAM,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;SAC1E,CAAC,CAAC;IACL,CAAC;CACF;AA5GD,kCA4GC"}
@@ -1,42 +1,200 @@
1
1
  "use strict";
2
+ /* eslint-disable @typescript-eslint/no-deprecated */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  const testing_1 = require("@nestjs/testing");
4
5
  const _1 = require(".");
5
6
  describe("HashService", () => {
6
7
  const globalSecret = "myGlobalSecret";
7
- let hashService;
8
- beforeEach(async () => {
9
- const moduleRef = await testing_1.Test.createTestingModule({
10
- imports: [_1.HashModule.register({ secret: globalSecret })],
11
- }).compile();
12
- hashService = moduleRef.get(_1.HashService);
8
+ describe("instance methods (via HashModule.register)", () => {
9
+ let hashService;
10
+ beforeEach(async () => {
11
+ const moduleRef = await testing_1.Test.createTestingModule({
12
+ imports: [_1.HashModule.register({ secret: globalSecret })],
13
+ }).compile();
14
+ hashService = moduleRef.get(_1.HashService);
15
+ });
16
+ describe("hash", () => {
17
+ it("should create a hash with the provided value and secret", async () => {
18
+ const value = "password";
19
+ const secret = "mySecret";
20
+ const result = await hashService.hash(value, secret);
21
+ expect(result).toBeDefined();
22
+ expect(result).toContain("$argon2");
23
+ });
24
+ it("should create a hash with the provided value and default secret", async () => {
25
+ const value = "password";
26
+ const result = await hashService.hash(value);
27
+ expect(result).toBeDefined();
28
+ expect(result).toContain("$argon2");
29
+ });
30
+ });
31
+ describe("create (deprecated)", () => {
32
+ it("should create a hash with the provided value and secret", async () => {
33
+ const value = "password";
34
+ const secret = "mySecret";
35
+ const result = await hashService.create(value, secret);
36
+ expect(result).toBeDefined();
37
+ expect(result).toContain("$argon2");
38
+ });
39
+ it("should create a hash with the provided value and default secret", async () => {
40
+ const value = "password";
41
+ const result = await hashService.create(value);
42
+ expect(result).toBeDefined();
43
+ expect(result).toContain("$argon2");
44
+ });
45
+ });
46
+ describe("verify", () => {
47
+ it("should verify the hashed value with the provided value and secret", async () => {
48
+ const value = "password";
49
+ const secret = "mySecret";
50
+ const hashed = await hashService.hash(value, secret);
51
+ const result = await hashService.verify(hashed, value, secret);
52
+ expect(result).toBe(true);
53
+ });
54
+ it("should verify the hashed value with the provided value and default secret", async () => {
55
+ const value = "password";
56
+ const hashed = await hashService.hash(value);
57
+ const result = await hashService.verify(hashed, value);
58
+ expect(result).toBe(true);
59
+ });
60
+ it("should return false for incorrect password", async () => {
61
+ const value = "password";
62
+ const hashed = await hashService.hash(value);
63
+ const result = await hashService.verify(hashed, "wrongpassword");
64
+ expect(result).toBe(false);
65
+ });
66
+ });
67
+ });
68
+ describe("static methods", () => {
69
+ beforeEach(() => {
70
+ // Reset static instance before each test
71
+ _1.HashService._instance =
72
+ undefined;
73
+ });
74
+ describe("instance getter", () => {
75
+ it("should throw error when not initialized", () => {
76
+ expect(() => _1.HashService.instance).toThrow("HashService not initialized");
77
+ });
78
+ it("should return instance after initialization", () => {
79
+ _1.HashService.init("secret");
80
+ expect(_1.HashService.instance).toBeInstanceOf(_1.HashService);
81
+ });
82
+ });
83
+ describe("init", () => {
84
+ it("should initialize with secret", () => {
85
+ _1.HashService.init("mySecret");
86
+ expect(_1.HashService.instance).toBeDefined();
87
+ });
88
+ it("should initialize without secret", () => {
89
+ _1.HashService.init();
90
+ expect(_1.HashService.instance).toBeDefined();
91
+ });
92
+ });
93
+ describe("hash (static)", () => {
94
+ it("should create a hash using static method", async () => {
95
+ _1.HashService.init("mySecret");
96
+ const value = "password";
97
+ const result = await _1.HashService.hash(value);
98
+ expect(result).toBeDefined();
99
+ expect(result).toContain("$argon2");
100
+ });
101
+ it("should create a hash with custom secret using static method", async () => {
102
+ _1.HashService.init();
103
+ const value = "password";
104
+ const secret = "customSecret";
105
+ const result = await _1.HashService.hash(value, secret);
106
+ expect(result).toBeDefined();
107
+ expect(result).toContain("$argon2");
108
+ });
109
+ });
110
+ describe("verify (static)", () => {
111
+ it("should verify using static method", async () => {
112
+ _1.HashService.init("mySecret");
113
+ const value = "password";
114
+ const hashed = await _1.HashService.hash(value);
115
+ const result = await _1.HashService.verify(hashed, value);
116
+ expect(result).toBe(true);
117
+ });
118
+ it("should verify with custom secret using static method", async () => {
119
+ _1.HashService.init();
120
+ const value = "password";
121
+ const secret = "customSecret";
122
+ const hashed = await _1.HashService.hash(value, secret);
123
+ const result = await _1.HashService.verify(hashed, value, secret);
124
+ expect(result).toBe(true);
125
+ });
126
+ });
13
127
  });
14
- describe("create", () => {
15
- it("should create a hash with the provided value and secret", async () => {
16
- const value = "password";
17
- const secret = "mySecret";
18
- const result = await hashService.create(value, secret);
19
- expect(result).toBeDefined();
20
- });
21
- it("should create a hash with the provided value and default secret", async () => {
22
- const value = "password";
23
- const result = await hashService.create(value);
24
- expect(result).toBeDefined();
128
+ describe("constructor", () => {
129
+ it("should create instance with secret", () => {
130
+ const service = new _1.HashService("mySecret");
131
+ expect(service).toBeDefined();
132
+ });
133
+ it("should create instance without secret", () => {
134
+ const service = new _1.HashService();
135
+ expect(service).toBeDefined();
25
136
  });
26
137
  });
27
- describe("verify", () => {
28
- it("should verify the hashed value with the provided value and secret", async () => {
29
- const hashed = "$argon2id$v=19$m=19456,t=2,p=1$pLzJg4HZZPyJmwa4UrBOIw$faLtt/ZlZd4Rc34V1vTV69bATK7gXULr/0pQvPhXi7k";
30
- const value = "password";
31
- const secret = "mySecret";
32
- const result = await hashService.verify(hashed, value, secret);
33
- expect(result).toBe(true);
34
- });
35
- it("should verify the hashed value with the provided value and default secret", async () => {
36
- const hashed = "$argon2id$v=19$m=19456,t=2,p=1$HMuzTfczqMM3OU1YHm3h6A$+xwVTb3sE531tRcZQvMp7ubEi0i5xj/isTz59kK5BVg";
37
- const value = "password";
38
- const result = await hashService.verify(hashed, value);
39
- expect(result).toBe(true);
138
+ });
139
+ describe("HashModule", () => {
140
+ const originalEnv = process.env;
141
+ beforeEach(() => {
142
+ // Reset static instance before each test
143
+ _1.HashService._instance = undefined;
144
+ // Reset environment variables
145
+ process.env = { ...originalEnv };
146
+ delete process.env.HASH_SECRET;
147
+ delete process.env.APP_SECRET;
148
+ });
149
+ afterAll(() => {
150
+ process.env = originalEnv;
151
+ });
152
+ describe("registerAsync", () => {
153
+ it("should register module with async factory", async () => {
154
+ const moduleRef = await testing_1.Test.createTestingModule({
155
+ imports: [
156
+ _1.HashModule.registerAsync({
157
+ useFactory: () => ({
158
+ secret: "asyncSecret",
159
+ }),
160
+ }),
161
+ ],
162
+ }).compile();
163
+ const hashService = moduleRef.get(_1.HashService);
164
+ expect(hashService).toBeDefined();
165
+ const hashed = await hashService.hash("password");
166
+ expect(hashed).toContain("$argon2");
167
+ });
168
+ });
169
+ describe("register with fallback secrets", () => {
170
+ it("should use HASH_SECRET env when no secret provided", async () => {
171
+ process.env.HASH_SECRET = "envHashSecret";
172
+ const moduleRef = await testing_1.Test.createTestingModule({
173
+ imports: [_1.HashModule.register({})],
174
+ }).compile();
175
+ const hashService = moduleRef.get(_1.HashService);
176
+ expect(hashService).toBeDefined();
177
+ const hashed = await hashService.hash("password");
178
+ expect(hashed).toContain("$argon2");
179
+ });
180
+ it("should use APP_SECRET env when no secret or HASH_SECRET provided", async () => {
181
+ process.env.APP_SECRET = "envAppSecret";
182
+ const moduleRef = await testing_1.Test.createTestingModule({
183
+ imports: [_1.HashModule.register({})],
184
+ }).compile();
185
+ const hashService = moduleRef.get(_1.HashService);
186
+ expect(hashService).toBeDefined();
187
+ const hashed = await hashService.hash("password");
188
+ expect(hashed).toContain("$argon2");
189
+ });
190
+ it("should work without any secret", async () => {
191
+ const moduleRef = await testing_1.Test.createTestingModule({
192
+ imports: [_1.HashModule.register({})],
193
+ }).compile();
194
+ const hashService = moduleRef.get(_1.HashService);
195
+ expect(hashService).toBeDefined();
196
+ const hashed = await hashService.hash("password");
197
+ expect(hashed).toContain("$argon2");
40
198
  });
41
199
  });
42
200
  });
@@ -1 +1 @@
1
- {"version":3,"file":"hash.service.spec.js","sourceRoot":"","sources":["../src/hash.service.spec.ts"],"names":[],"mappings":";;AAAA,6CAAuC;AAEvC,wBAA4C;AAE5C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,MAAM,YAAY,GAAG,gBAAgB,CAAC;IACtC,IAAI,WAAwB,CAAC;IAE7B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,SAAS,GAAG,MAAM,cAAI,CAAC,mBAAmB,CAAC;YAC/C,OAAO,EAAE,CAAC,aAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;SACzD,CAAC,CAAC,OAAO,EAAE,CAAC;QAEb,WAAW,GAAG,SAAS,CAAC,GAAG,CAAc,cAAW,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,KAAK,GAAG,UAAU,CAAC;YACzB,MAAM,MAAM,GAAG,UAAU,CAAC;YAE1B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEvD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,MAAM,KAAK,GAAG,UAAU,CAAC;YAEzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAE/C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,MAAM,GACV,mGAAmG,CAAC;YACtG,MAAM,KAAK,GAAG,UAAU,CAAC;YACzB,MAAM,MAAM,GAAG,UAAU,CAAC;YAE1B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAE/D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;YACzF,MAAM,MAAM,GACV,mGAAmG,CAAC;YACtG,MAAM,KAAK,GAAG,UAAU,CAAC;YAEzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAEvD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"hash.service.spec.js","sourceRoot":"","sources":["../src/hash.service.spec.ts"],"names":[],"mappings":"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"}