@nest-boot/crypt 7.0.2 → 7.1.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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Derives a 32-byte key using HKDF-SHA256 via Web Crypto API.
3
+ *
4
+ * @param secret - The input key material (any length)
5
+ * @returns A 32-byte (256-bit) derived key suitable for AES-256
6
+ */
7
+ export declare function deriveKey(secret: string): Promise<Uint8Array>;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deriveKey = deriveKey;
4
+ /**
5
+ * Derives a 32-byte key using HKDF-SHA256 via Web Crypto API.
6
+ *
7
+ * @param secret - The input key material (any length)
8
+ * @returns A 32-byte (256-bit) derived key suitable for AES-256
9
+ */
10
+ async function deriveKey(secret) {
11
+ const enc = new TextEncoder();
12
+ const ikm = enc.encode(secret);
13
+ const salt = enc.encode("");
14
+ const info = enc.encode("");
15
+ return new Uint8Array(await crypto.subtle.deriveBits({
16
+ name: "HKDF",
17
+ hash: "SHA-256",
18
+ salt,
19
+ info,
20
+ }, await crypto.subtle.importKey("raw", ikm, "HKDF", false, ["deriveBits"]), 256));
21
+ }
22
+ //# sourceMappingURL=derive-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive-key.js","sourceRoot":"","sources":["../../src/utils/derive-key.ts"],"names":[],"mappings":";;AAMA,8BAkBC;AAxBD;;;;;GAKG;AACI,KAAK,UAAU,SAAS,CAAC,MAAc;IAC5C,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAE5B,OAAO,IAAI,UAAU,CACnB,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAC5B;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;QACf,IAAI;QACJ,IAAI;KACL,EACD,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,EACxE,GAAG,CACJ,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Estimates the entropy of a string in bits.
3
+ * This is a simple approximation that helps detect low-entropy secrets.
4
+ *
5
+ * @param str - The string to estimate entropy for
6
+ * @returns The estimated entropy in bits
7
+ */
8
+ export declare function estimateEntropy(str: string): number;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.estimateEntropy = estimateEntropy;
4
+ /**
5
+ * Estimates the entropy of a string in bits.
6
+ * This is a simple approximation that helps detect low-entropy secrets.
7
+ *
8
+ * @param str - The string to estimate entropy for
9
+ * @returns The estimated entropy in bits
10
+ */
11
+ function estimateEntropy(str) {
12
+ const unique = new Set(str).size;
13
+ if (unique === 0)
14
+ return 0;
15
+ return Math.log2(Math.pow(unique, str.length));
16
+ }
17
+ //# sourceMappingURL=estimate-entropy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-entropy.js","sourceRoot":"","sources":["../../src/utils/estimate-entropy.ts"],"names":[],"mappings":";;AAOA,0CAIC;AAXD;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IACjC,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const estimate_entropy_1 = require("./estimate-entropy");
4
+ describe("estimateEntropy", () => {
5
+ it("should return 0 for empty string", () => {
6
+ expect((0, estimate_entropy_1.estimateEntropy)("")).toBe(0);
7
+ });
8
+ it("should return positive entropy for non-empty string", () => {
9
+ expect((0, estimate_entropy_1.estimateEntropy)("abc")).toBeGreaterThan(0);
10
+ });
11
+ it("should return higher entropy for more unique characters", () => {
12
+ const lowEntropy = (0, estimate_entropy_1.estimateEntropy)("aaa");
13
+ const highEntropy = (0, estimate_entropy_1.estimateEntropy)("abc");
14
+ expect(highEntropy).toBeGreaterThan(lowEntropy);
15
+ });
16
+ });
17
+ //# sourceMappingURL=estimate-entropy.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-entropy.spec.js","sourceRoot":"","sources":["../../src/utils/estimate-entropy.spec.ts"],"names":[],"mappings":";;AAAA,yDAAqD;AAErD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,IAAA,kCAAe,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,IAAA,kCAAe,EAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,UAAU,GAAG,IAAA,kCAAe,EAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,IAAA,kCAAe,EAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,WAAW,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Checks if a string is a valid JWE (JSON Web Encryption) compact serialization.
3
+ *
4
+ * JWE compact serialization format:
5
+ * BASE64URL(UTF8(JWE Protected Header)) || '.' ||
6
+ * BASE64URL(JWE Encrypted Key) || '.' ||
7
+ * BASE64URL(JWE Initialization Vector) || '.' ||
8
+ * BASE64URL(JWE Ciphertext) || '.' ||
9
+ * BASE64URL(JWE Authentication Tag)
10
+ *
11
+ * @param value - The string to check
12
+ * @returns true if the string appears to be a valid JWE
13
+ */
14
+ export declare function isJwe(value: string): boolean;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isJwe = isJwe;
4
+ /**
5
+ * Checks if a string is a valid JWE (JSON Web Encryption) compact serialization.
6
+ *
7
+ * JWE compact serialization format:
8
+ * BASE64URL(UTF8(JWE Protected Header)) || '.' ||
9
+ * BASE64URL(JWE Encrypted Key) || '.' ||
10
+ * BASE64URL(JWE Initialization Vector) || '.' ||
11
+ * BASE64URL(JWE Ciphertext) || '.' ||
12
+ * BASE64URL(JWE Authentication Tag)
13
+ *
14
+ * @param value - The string to check
15
+ * @returns true if the string appears to be a valid JWE
16
+ */
17
+ function isJwe(value) {
18
+ // JWE compact serialization has exactly 5 parts
19
+ const parts = value.split(".");
20
+ if (parts.length !== 5) {
21
+ return false;
22
+ }
23
+ // Try to decode and validate the protected header (first part)
24
+ try {
25
+ const header = JSON.parse(Buffer.from(parts[0], "base64url").toString("utf8"));
26
+ // JWE header must have 'alg' and 'enc' fields
27
+ return (typeof header === "object" &&
28
+ header !== null &&
29
+ "alg" in header &&
30
+ "enc" in header &&
31
+ typeof header.alg === "string" &&
32
+ typeof header.enc === "string");
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ //# sourceMappingURL=is-jwe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-jwe.js","sourceRoot":"","sources":["../../src/utils/is-jwe.ts"],"names":[],"mappings":";;AAaA,sBAyBC;AAtCD;;;;;;;;;;;;GAYG;AACH,SAAgB,KAAK,CAAC,KAAa;IACjC,gDAAgD;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+DAA+D;IAC/D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CACzC,CAAC;QAEb,8CAA8C;QAC9C,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;YAC1B,MAAM,KAAK,IAAI;YACf,KAAK,IAAI,MAAM;YACf,KAAK,IAAI,MAAM;YACf,OAAQ,MAA2B,CAAC,GAAG,KAAK,QAAQ;YACpD,OAAQ,MAA2B,CAAC,GAAG,KAAK,QAAQ,CACrD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const crypt_service_1 = require("../crypt.service");
4
+ const is_jwe_1 = require("./is-jwe");
5
+ const TEST_SECRET = "myTestSecretThatIsAtLeast32Chars!";
6
+ describe("isJwe", () => {
7
+ beforeAll(() => {
8
+ crypt_service_1.CryptService.init(TEST_SECRET);
9
+ });
10
+ it("should return true for valid JWE", async () => {
11
+ const encrypted = await crypt_service_1.CryptService.encrypt("test");
12
+ expect((0, is_jwe_1.isJwe)(encrypted)).toBe(true);
13
+ });
14
+ it("should return false for empty string", () => {
15
+ expect((0, is_jwe_1.isJwe)("")).toBe(false);
16
+ });
17
+ it("should return false for plain text", () => {
18
+ expect((0, is_jwe_1.isJwe)("hello world")).toBe(false);
19
+ });
20
+ it("should return false for string with 5 dots but invalid header", () => {
21
+ expect((0, is_jwe_1.isJwe)("a.b.c.d.e")).toBe(false);
22
+ });
23
+ it("should return false for string with valid base64 but missing alg/enc", () => {
24
+ // base64url of '{}'
25
+ const emptyHeader = Buffer.from("{}").toString("base64url");
26
+ expect((0, is_jwe_1.isJwe)(`${emptyHeader}.b.c.d.e`)).toBe(false);
27
+ });
28
+ it("should return false for string with only alg field", () => {
29
+ const headerWithAlg = Buffer.from('{"alg":"A256GCMKW"}').toString("base64url");
30
+ expect((0, is_jwe_1.isJwe)(`${headerWithAlg}.b.c.d.e`)).toBe(false);
31
+ });
32
+ it("should return false for string with only enc field", () => {
33
+ const headerWithEnc = Buffer.from('{"enc":"A256GCM"}').toString("base64url");
34
+ expect((0, is_jwe_1.isJwe)(`${headerWithEnc}.b.c.d.e`)).toBe(false);
35
+ });
36
+ it("should return true for string with both alg and enc fields", () => {
37
+ const validHeader = Buffer.from('{"alg":"A256GCMKW","enc":"A256GCM"}').toString("base64url");
38
+ expect((0, is_jwe_1.isJwe)(`${validHeader}.b.c.d.e`)).toBe(true);
39
+ });
40
+ it("should return false for JWT (wrong structure)", () => {
41
+ // JWT has only 3 parts
42
+ const jwtHeader = Buffer.from('{"alg":"HS256","typ":"JWT"}').toString("base64url");
43
+ expect((0, is_jwe_1.isJwe)(`${jwtHeader}.payload.signature`)).toBe(false);
44
+ });
45
+ it("should return false for non-string alg/enc values", () => {
46
+ const invalidHeader = Buffer.from('{"alg":123,"enc":"A256GCM"}').toString("base64url");
47
+ expect((0, is_jwe_1.isJwe)(`${invalidHeader}.b.c.d.e`)).toBe(false);
48
+ });
49
+ });
50
+ //# sourceMappingURL=is-jwe.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-jwe.spec.js","sourceRoot":"","sources":["../../src/utils/is-jwe.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@nest-boot/crypt",
3
- "version": "7.0.2",
3
+ "version": "7.1.1",
4
4
  "description": "",
5
- "author": "d4rkcr0w <me@d4rkcr0w.com>",
5
+ "author": {
6
+ "name": "Xudong Huang",
7
+ "email": "me@huangxudong.com",
8
+ "url": "https://www.huangxudong.com/"
9
+ },
6
10
  "homepage": "",
7
11
  "license": "MIT",
8
12
  "main": "dist/index.js",
@@ -15,24 +19,26 @@
15
19
  "templates"
16
20
  ],
17
21
  "devDependencies": {
18
- "@nestjs/common": "^11.1.9",
19
- "@nestjs/core": "^11.1.9",
20
- "@nestjs/testing": "^11.1.9",
22
+ "@nestjs/common": "^11.1.11",
23
+ "@nestjs/core": "^11.1.11",
24
+ "@nestjs/testing": "^11.1.11",
21
25
  "@types/jest": "^29.5.14",
22
26
  "@types/node": "^22.18.6",
23
- "eslint": "^9.36.0",
27
+ "eslint": "^9.39.2",
24
28
  "jest": "^29.7.0",
29
+ "jose": "^6.1.3",
25
30
  "reflect-metadata": "^0.2.2",
26
31
  "rxjs": "^7.8.2",
27
32
  "ts-jest": "^29.4.4",
28
33
  "typescript": "^5.9.3",
29
34
  "@nest-boot/eslint-config": "^7.0.2",
30
- "@nest-boot/eslint-plugin": "^7.0.3",
35
+ "@nest-boot/eslint-plugin": "^7.0.4",
31
36
  "@nest-boot/tsconfig": "^7.0.1"
32
37
  },
33
38
  "peerDependencies": {
34
39
  "@nestjs/common": "^11.0.0",
35
40
  "@nestjs/core": "^11.0.0",
41
+ "jose": "^5.0.0 || ^6.0.0",
36
42
  "reflect-metadata": "^0.2.2",
37
43
  "rxjs": "^7.0.0"
38
44
  },