@nivinjoseph/n-sec 6.0.2 → 7.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/.yarn/releases/yarn-4.14.1.cjs +940 -0
- package/.yarnrc.yml +6 -1
- package/README.md +114 -1
- package/dist/api-security/claim.js +2 -0
- package/dist/api-security/claim.js.map +1 -1
- package/dist/api-security/claims-identity.js +1 -0
- package/dist/api-security/claims-identity.js.map +1 -1
- package/dist/api-security/expired-token-exception.js +1 -0
- package/dist/api-security/expired-token-exception.js.map +1 -1
- package/dist/api-security/invalid-token-exception.js +2 -0
- package/dist/api-security/invalid-token-exception.js.map +1 -1
- package/dist/api-security/json-web-token.d.ts +1 -1
- package/dist/api-security/json-web-token.d.ts.map +1 -1
- package/dist/api-security/json-web-token.js +35 -10
- package/dist/api-security/json-web-token.js.map +1 -1
- package/dist/api-security/security-token.js +2 -0
- package/dist/api-security/security-token.js.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/crypto/hash.d.ts +40 -0
- package/dist/crypto/hash.d.ts.map +1 -1
- package/dist/crypto/hash.js +60 -1
- package/dist/crypto/hash.js.map +1 -1
- package/dist/crypto/symmetric-encryption.d.ts +51 -3
- package/dist/crypto/symmetric-encryption.d.ts.map +1 -1
- package/dist/crypto/symmetric-encryption.js +90 -44
- package/dist/crypto/symmetric-encryption.js.map +1 -1
- package/dist/tsconfig.json +1 -0
- package/eslint.config.js +5 -5
- package/package.json +15 -15
- package/src/api-security/json-web-token.ts +37 -12
- package/src/bin.ts +1 -1
- package/src/crypto/hash.ts +66 -1
- package/src/crypto/symmetric-encryption.ts +98 -55
- package/test/hash.test.ts +89 -0
- package/test/hmac.test.ts +12 -12
- package/test/json-web-token.test.ts +76 -10
- package/test/symmetric-encryption.test.ts +51 -12
- package/tsconfig.json +5 -2
- package/.yarn/releases/yarn-4.0.2.cjs +0 -893
package/test/hash.test.ts
CHANGED
|
@@ -164,6 +164,95 @@ await describe("Hash", async () =>
|
|
|
164
164
|
|
|
165
165
|
Hash.createUsingSalt(password, salt);
|
|
166
166
|
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
await describe("createForPassword", async () =>
|
|
170
|
+
{
|
|
171
|
+
await test("must return a 128-character uppercase hex string", () =>
|
|
172
|
+
{
|
|
173
|
+
const hash = Hash.createForPassword("password", "some-salt");
|
|
174
|
+
assert.match(hash, /^[0-9A-F]{128}$/);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
await test("same password and salt must produce the same output", () =>
|
|
178
|
+
{
|
|
179
|
+
const hash1 = Hash.createForPassword("password", "some-salt");
|
|
180
|
+
const hash2 = Hash.createForPassword("password", "some-salt");
|
|
181
|
+
assert.strictEqual(hash1, hash2);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
await test("different passwords with the same salt must produce different outputs", () =>
|
|
185
|
+
{
|
|
186
|
+
const hash1 = Hash.createForPassword("password1", "some-salt");
|
|
187
|
+
const hash2 = Hash.createForPassword("password2", "some-salt");
|
|
188
|
+
assert.notStrictEqual(hash1, hash2);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
await test("same password with different salts must produce different outputs", () =>
|
|
192
|
+
{
|
|
193
|
+
const hash1 = Hash.createForPassword("password", "salt-1");
|
|
194
|
+
const hash2 = Hash.createForPassword("password", "salt-2");
|
|
195
|
+
assert.notStrictEqual(hash1, hash2);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
await test("passwords differing only in trailing whitespace must produce different outputs", () =>
|
|
199
|
+
{
|
|
200
|
+
const hash1 = Hash.createForPassword("password", "some-salt");
|
|
201
|
+
const hash2 = Hash.createForPassword("password ", "some-salt");
|
|
202
|
+
assert.notStrictEqual(hash1, hash2);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
await test("passwords differing only in leading whitespace must produce different outputs", () =>
|
|
206
|
+
{
|
|
207
|
+
const hash1 = Hash.createForPassword("password", "some-salt");
|
|
208
|
+
const hash2 = Hash.createForPassword(" password", "some-salt");
|
|
209
|
+
assert.notStrictEqual(hash1, hash2);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await describe("verifyPassword", async () =>
|
|
214
|
+
{
|
|
215
|
+
await test("must return true for the same password and salt that produced the hash", () =>
|
|
216
|
+
{
|
|
217
|
+
const hash = Hash.createForPassword("password", "some-salt");
|
|
218
|
+
assert.strictEqual(Hash.verifyPassword("password", "some-salt", hash), true);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
await test("must accept the hash in lowercase as well as uppercase", () =>
|
|
222
|
+
{
|
|
223
|
+
const hash = Hash.createForPassword("password", "some-salt");
|
|
224
|
+
assert.strictEqual(Hash.verifyPassword("password", "some-salt", hash.toLowerCase()), true);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
await test("must return false for a wrong password", () =>
|
|
228
|
+
{
|
|
229
|
+
const hash = Hash.createForPassword("password", "some-salt");
|
|
230
|
+
assert.strictEqual(Hash.verifyPassword("wrong-password", "some-salt", hash), false);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
await test("must return false for a wrong salt", () =>
|
|
234
|
+
{
|
|
235
|
+
const hash = Hash.createForPassword("password", "some-salt");
|
|
236
|
+
assert.strictEqual(Hash.verifyPassword("password", "different-salt", hash), false);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
await test("must return false for a tampered hash", () =>
|
|
240
|
+
{
|
|
241
|
+
const hash = Hash.createForPassword("password", "some-salt");
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
243
|
+
const tampered = (hash[0] === "A" ? "B" : "A") + hash.slice(1);
|
|
244
|
+
assert.strictEqual(Hash.verifyPassword("password", "some-salt", tampered), false);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
await test("must return false for a hash of the wrong length", () =>
|
|
248
|
+
{
|
|
249
|
+
assert.strictEqual(Hash.verifyPassword("password", "some-salt", "ABCD"), false);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
await test("must return false for a non-hex hash", () =>
|
|
253
|
+
{
|
|
254
|
+
assert.strictEqual(Hash.verifyPassword("password", "some-salt", "Z".repeat(128)), false);
|
|
255
|
+
});
|
|
167
256
|
|
|
168
257
|
|
|
169
258
|
|
package/test/hmac.test.ts
CHANGED
|
@@ -8,9 +8,9 @@ await describe("Hmac", async () =>
|
|
|
8
8
|
{
|
|
9
9
|
await describe("create", async () =>
|
|
10
10
|
{
|
|
11
|
-
await test("should return string value that is not null, empty, whitespace or same as the key or input",
|
|
11
|
+
await test("should return string value that is not null, empty, whitespace or same as the key or input", () =>
|
|
12
12
|
{
|
|
13
|
-
const key =
|
|
13
|
+
const key = SymmetricEncryption.generateKey();
|
|
14
14
|
const value = "hello world";
|
|
15
15
|
const hmac = Hmac.create(key, value);
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -19,30 +19,30 @@ await describe("Hmac", async () =>
|
|
|
19
19
|
assert.notStrictEqual(hmac, value);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
await test("multiple invocations with the same key and value must return the same output",
|
|
22
|
+
await test("multiple invocations with the same key and value must return the same output", () =>
|
|
23
23
|
{
|
|
24
|
-
const key =
|
|
24
|
+
const key = SymmetricEncryption.generateKey();
|
|
25
25
|
const value = "hello world";
|
|
26
26
|
const hmac1 = Hmac.create(key, value);
|
|
27
27
|
const hmac2 = Hmac.create(key, value);
|
|
28
28
|
assert.strictEqual(hmac1, hmac2);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
await test("multiple invocations with different keys and different values must return different outputs",
|
|
31
|
+
await test("multiple invocations with different keys and different values must return different outputs", () =>
|
|
32
32
|
{
|
|
33
|
-
const key1 =
|
|
33
|
+
const key1 = SymmetricEncryption.generateKey();
|
|
34
34
|
const value1 = "hello world";
|
|
35
35
|
const hmac1 = Hmac.create(key1, value1);
|
|
36
36
|
|
|
37
|
-
const key2 =
|
|
37
|
+
const key2 = SymmetricEncryption.generateKey();
|
|
38
38
|
const value2 = "goodbye world";
|
|
39
39
|
const hmac2 = Hmac.create(key2, value2);
|
|
40
40
|
assert.notStrictEqual(hmac1, hmac2);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
await test("multiple invocations with the same key and different values must return different outputs",
|
|
43
|
+
await test("multiple invocations with the same key and different values must return different outputs", () =>
|
|
44
44
|
{
|
|
45
|
-
const key =
|
|
45
|
+
const key = SymmetricEncryption.generateKey();
|
|
46
46
|
const value1 = "hello world";
|
|
47
47
|
const value2 = "goodbye world";
|
|
48
48
|
const hmac1 = Hmac.create(key, value1);
|
|
@@ -50,10 +50,10 @@ await describe("Hmac", async () =>
|
|
|
50
50
|
assert.notStrictEqual(hmac1, hmac2);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
await test("multiple invocations with different keys and the same value must return different outputs",
|
|
53
|
+
await test("multiple invocations with different keys and the same value must return different outputs", () =>
|
|
54
54
|
{
|
|
55
|
-
const key1 =
|
|
56
|
-
const key2 =
|
|
55
|
+
const key1 = SymmetricEncryption.generateKey();
|
|
56
|
+
const key2 = SymmetricEncryption.generateKey();
|
|
57
57
|
const value = "hello world";
|
|
58
58
|
const hmac1 = Hmac.create(key1, value);
|
|
59
59
|
const hmac2 = Hmac.create(key2, value);
|
|
@@ -2,20 +2,29 @@ import { describe, test } from "node:test";
|
|
|
2
2
|
import assert from "node:assert";
|
|
3
3
|
import { JsonWebToken } from "./../src/api-security/json-web-token.js";
|
|
4
4
|
import { Claim } from "../src/api-security/claim.js";
|
|
5
|
-
import { SymmetricEncryption } from "../src/index.js";
|
|
5
|
+
import { Hmac, SymmetricEncryption } from "../src/index.js";
|
|
6
6
|
import { InvalidTokenException } from "../src/api-security/invalid-token-exception.js";
|
|
7
7
|
import { ExpiredTokenException } from "../src/api-security/expired-token-exception.js";
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
function buildToken(key: string, headerJson: string, bodyJson: string): string
|
|
11
|
+
{
|
|
12
|
+
const headerHex = Buffer.from(headerJson, "utf8").toString("hex").toUpperCase();
|
|
13
|
+
const bodyHex = Buffer.from(bodyJson, "utf8").toString("hex").toUpperCase();
|
|
14
|
+
const signature = Hmac.create(key, `${headerHex}.${bodyHex}`);
|
|
15
|
+
return `${headerHex}.${bodyHex}.${signature}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
10
19
|
await describe("Json Web Token ", async () =>
|
|
11
20
|
{
|
|
12
21
|
await describe("Hmac", async () =>
|
|
13
22
|
{
|
|
14
23
|
|
|
15
|
-
await test("should successfully create a token using hmac with one claim",
|
|
24
|
+
await test("should successfully create a token using hmac with one claim", () =>
|
|
16
25
|
{
|
|
17
26
|
const claim = new Claim("this_claim", "ThisValue");
|
|
18
|
-
const key =
|
|
27
|
+
const key = SymmetricEncryption.generateKey();
|
|
19
28
|
const time = Date.now();
|
|
20
29
|
const token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim]).generateToken();
|
|
21
30
|
const jwt = JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
@@ -31,7 +40,7 @@ await describe("Json Web Token ", async () =>
|
|
|
31
40
|
{
|
|
32
41
|
const claim1 = new Claim("this_claim", "ThisValue");
|
|
33
42
|
const claim2 = new Claim("that_claim", "ThatValue");
|
|
34
|
-
const key =
|
|
43
|
+
const key = SymmetricEncryption.generateKey();
|
|
35
44
|
const time = Date.now();
|
|
36
45
|
const token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim1, claim2]).generateToken();
|
|
37
46
|
const jwt = JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
@@ -47,7 +56,7 @@ await describe("Json Web Token ", async () =>
|
|
|
47
56
|
{
|
|
48
57
|
const claim1 = new Claim("this_claim", "ThisValue");
|
|
49
58
|
const claim2 = new Claim("that_claim", "ThatValue");
|
|
50
|
-
const key =
|
|
59
|
+
const key = SymmetricEncryption.generateKey();
|
|
51
60
|
const time = Date.now();
|
|
52
61
|
const token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim1, claim2]).generateToken();
|
|
53
62
|
const jwt = JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
@@ -63,7 +72,7 @@ await describe("Json Web Token ", async () =>
|
|
|
63
72
|
{
|
|
64
73
|
const claim1 = new Claim("this_claim", "ThisValue");
|
|
65
74
|
const claim2 = new Claim("that_claim", "ThatValue");
|
|
66
|
-
const key =
|
|
75
|
+
const key = SymmetricEncryption.generateKey();
|
|
67
76
|
const time = Date.now();
|
|
68
77
|
const token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim1, claim2]).generateToken();
|
|
69
78
|
try
|
|
@@ -83,7 +92,7 @@ await describe("Json Web Token ", async () =>
|
|
|
83
92
|
{
|
|
84
93
|
const claim1 = new Claim("this_claim", "ThisValue");
|
|
85
94
|
const claim2 = new Claim("that_claim", "ThatValue");
|
|
86
|
-
const key =
|
|
95
|
+
const key = SymmetricEncryption.generateKey();
|
|
87
96
|
const time = Date.now();
|
|
88
97
|
const token = JsonWebToken.fromClaims("issuer1", 1, key, time, [claim1, claim2]).generateToken();
|
|
89
98
|
try
|
|
@@ -125,8 +134,8 @@ await describe("Json Web Token ", async () =>
|
|
|
125
134
|
{
|
|
126
135
|
const claim1 = new Claim("this_claim", "ThisValue");
|
|
127
136
|
const claim2 = new Claim("that_claim", "ThatValue");
|
|
128
|
-
const key =
|
|
129
|
-
const key2 =
|
|
137
|
+
const key = SymmetricEncryption.generateKey();
|
|
138
|
+
const key2 = SymmetricEncryption.generateKey();
|
|
130
139
|
const time = Date.now();
|
|
131
140
|
const token = JsonWebToken.fromClaims("issuer1", 1, key, time + 1000000, [claim1, claim2]).generateToken();
|
|
132
141
|
try
|
|
@@ -146,7 +155,7 @@ await describe("Json Web Token ", async () =>
|
|
|
146
155
|
{
|
|
147
156
|
const claim1 = new Claim("this_claim", "ThisValue");
|
|
148
157
|
const claim2 = new Claim("that_claim", "ThatValue");
|
|
149
|
-
const key =
|
|
158
|
+
const key = SymmetricEncryption.generateKey();
|
|
150
159
|
const time = Date.now();
|
|
151
160
|
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 1000000, [claim1, claim2]).generateToken();
|
|
152
161
|
token = token + "someStuff";
|
|
@@ -162,6 +171,63 @@ await describe("Json Web Token ", async () =>
|
|
|
162
171
|
}
|
|
163
172
|
assert.ok(false);
|
|
164
173
|
});
|
|
174
|
+
|
|
175
|
+
await test("should throw an exception when body contains '__proto__' as a claim type", () =>
|
|
176
|
+
{
|
|
177
|
+
const key = SymmetricEncryption.generateKey();
|
|
178
|
+
const headerJson = JSON.stringify({ iss: "issuer1", alg: 1, exp: Date.now() + 10000000 });
|
|
179
|
+
const bodyJson = `{"__proto__":"evil"}`;
|
|
180
|
+
const token = buildToken(key, headerJson, bodyJson);
|
|
181
|
+
try
|
|
182
|
+
{
|
|
183
|
+
JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
184
|
+
}
|
|
185
|
+
catch (exp)
|
|
186
|
+
{
|
|
187
|
+
assert.ok(exp instanceof InvalidTokenException);
|
|
188
|
+
assert.equal(exp.message, `Token '${token}' is invalid because body contains invalid key '__proto__'.`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
assert.ok(false);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
await test("should throw an exception when body contains 'constructor' as a claim type", () =>
|
|
195
|
+
{
|
|
196
|
+
const key = SymmetricEncryption.generateKey();
|
|
197
|
+
const headerJson = JSON.stringify({ iss: "issuer1", alg: 1, exp: Date.now() + 10000000 });
|
|
198
|
+
const bodyJson = `{"constructor":"evil"}`;
|
|
199
|
+
const token = buildToken(key, headerJson, bodyJson);
|
|
200
|
+
try
|
|
201
|
+
{
|
|
202
|
+
JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
203
|
+
}
|
|
204
|
+
catch (exp)
|
|
205
|
+
{
|
|
206
|
+
assert.ok(exp instanceof InvalidTokenException);
|
|
207
|
+
assert.equal(exp.message, `Token '${token}' is invalid because body contains invalid key 'constructor'.`);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
assert.ok(false);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await test("should throw an exception when body contains 'prototype' as a claim type", () =>
|
|
214
|
+
{
|
|
215
|
+
const key = SymmetricEncryption.generateKey();
|
|
216
|
+
const headerJson = JSON.stringify({ iss: "issuer1", alg: 1, exp: Date.now() + 10000000 });
|
|
217
|
+
const bodyJson = `{"prototype":"evil"}`;
|
|
218
|
+
const token = buildToken(key, headerJson, bodyJson);
|
|
219
|
+
try
|
|
220
|
+
{
|
|
221
|
+
JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
222
|
+
}
|
|
223
|
+
catch (exp)
|
|
224
|
+
{
|
|
225
|
+
assert.ok(exp instanceof InvalidTokenException);
|
|
226
|
+
assert.equal(exp.message, `Token '${token}' is invalid because body contains invalid key 'prototype'.`);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
assert.ok(false);
|
|
230
|
+
});
|
|
165
231
|
});
|
|
166
232
|
|
|
167
233
|
// await describe("digital Signature", () =>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import { SymmetricEncryption } from "./../src/index.js";
|
|
4
|
-
// import { CryptoException } from "./../src/crypto-exception";
|
|
3
|
+
import { CryptoException, SymmetricEncryption } from "./../src/index.js";
|
|
5
4
|
import "@nivinjoseph/n-ext";
|
|
6
5
|
|
|
7
6
|
|
|
@@ -9,30 +8,30 @@ await describe("SymmetricEncryption", async () =>
|
|
|
9
8
|
{
|
|
10
9
|
await describe("generateKey", async () =>
|
|
11
10
|
{
|
|
12
|
-
await test("must return string value that is not null, empty or whitespace",
|
|
11
|
+
await test("must return string value that is not null, empty or whitespace", () =>
|
|
13
12
|
{
|
|
14
|
-
const key =
|
|
13
|
+
const key = SymmetricEncryption.generateKey();
|
|
15
14
|
console.log("key", key);
|
|
16
15
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
17
16
|
assert.ok(key !== null && !key.isEmptyOrWhiteSpace());
|
|
18
17
|
});
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
await test("consecutive calls must yield unique values",
|
|
20
|
+
await test("consecutive calls must yield unique values", () =>
|
|
22
21
|
{
|
|
23
|
-
const key1 =
|
|
24
|
-
const key2 =
|
|
22
|
+
const key1 = SymmetricEncryption.generateKey();
|
|
23
|
+
const key2 = SymmetricEncryption.generateKey();
|
|
25
24
|
assert.notStrictEqual(key1, key2);
|
|
26
25
|
});
|
|
27
26
|
});
|
|
28
27
|
|
|
29
28
|
await describe("encrypt", async () =>
|
|
30
29
|
{
|
|
31
|
-
await test("must return cipher text value when called with key and plain text value",
|
|
30
|
+
await test("must return cipher text value when called with key and plain text value", () =>
|
|
32
31
|
{
|
|
33
32
|
const key = "E25B269440F88601C453CD171D76EDDC11D8CF33230742DF8CAD5873D28F78B2";
|
|
34
33
|
const value = "password";
|
|
35
|
-
const encrypted =
|
|
34
|
+
const encrypted = SymmetricEncryption.encrypt(key, value);
|
|
36
35
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
37
36
|
assert.ok(encrypted !== null);
|
|
38
37
|
assert.notStrictEqual(encrypted, value);
|
|
@@ -172,15 +171,55 @@ await describe("SymmetricEncryption", async () =>
|
|
|
172
171
|
|
|
173
172
|
await describe("decrypt", async () =>
|
|
174
173
|
{
|
|
175
|
-
await test("must return plain text value when called with key and cipher text value",
|
|
174
|
+
await test("must return plain text value when called with key and cipher text value", () =>
|
|
176
175
|
{
|
|
177
|
-
const key =
|
|
176
|
+
const key = SymmetricEncryption.generateKey();
|
|
178
177
|
const value = "password";
|
|
179
|
-
const encrypted =
|
|
178
|
+
const encrypted = SymmetricEncryption.encrypt(key, value);
|
|
180
179
|
const decrypted = SymmetricEncryption.decrypt(key, encrypted);
|
|
181
180
|
assert.strictEqual(decrypted, value);
|
|
182
181
|
});
|
|
183
182
|
|
|
183
|
+
await test("round-trips successfully when the same aad is supplied to encrypt and decrypt", () =>
|
|
184
|
+
{
|
|
185
|
+
const key = SymmetricEncryption.generateKey();
|
|
186
|
+
const value = "password";
|
|
187
|
+
const aad = "user:42|purpose:session";
|
|
188
|
+
const encrypted = SymmetricEncryption.encrypt(key, value, aad);
|
|
189
|
+
const decrypted = SymmetricEncryption.decrypt(key, encrypted, aad);
|
|
190
|
+
assert.strictEqual(decrypted, value);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
await test("throws CryptoException when decrypting with a different aad than was used to encrypt", () =>
|
|
194
|
+
{
|
|
195
|
+
const key = SymmetricEncryption.generateKey();
|
|
196
|
+
const encrypted = SymmetricEncryption.encrypt(key, "password", "user:42");
|
|
197
|
+
assert.throws(
|
|
198
|
+
() => SymmetricEncryption.decrypt(key, encrypted, "user:99"),
|
|
199
|
+
CryptoException
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
await test("throws CryptoException when decrypting without aad a ciphertext that was encrypted with aad", () =>
|
|
204
|
+
{
|
|
205
|
+
const key = SymmetricEncryption.generateKey();
|
|
206
|
+
const encrypted = SymmetricEncryption.encrypt(key, "password", "user:42");
|
|
207
|
+
assert.throws(
|
|
208
|
+
() => SymmetricEncryption.decrypt(key, encrypted),
|
|
209
|
+
CryptoException
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await test("throws CryptoException when decrypting with aad a ciphertext that was encrypted without aad", () =>
|
|
214
|
+
{
|
|
215
|
+
const key = SymmetricEncryption.generateKey();
|
|
216
|
+
const encrypted = SymmetricEncryption.encrypt(key, "password");
|
|
217
|
+
assert.throws(
|
|
218
|
+
() => SymmetricEncryption.decrypt(key, encrypted, "user:42"),
|
|
219
|
+
CryptoException
|
|
220
|
+
);
|
|
221
|
+
});
|
|
222
|
+
|
|
184
223
|
// await test("decrypt with a valid encryption key", async () =>
|
|
185
224
|
// {
|
|
186
225
|
// let key = await SymmetricEncryption.generateKey();
|
package/tsconfig.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"module": "NodeNext",
|
|
4
|
-
"target": "
|
|
4
|
+
"target": "ES2023",
|
|
5
5
|
"lib": [
|
|
6
6
|
"ES2023"
|
|
7
7
|
],
|
|
8
|
+
"types": [
|
|
9
|
+
"node"
|
|
10
|
+
],
|
|
8
11
|
"strict": true,
|
|
9
12
|
"strictNullChecks": true,
|
|
10
13
|
"strictFunctionTypes": true,
|
|
@@ -23,7 +26,7 @@
|
|
|
23
26
|
"noEmitHelpers": true,
|
|
24
27
|
"noImplicitOverride": true,
|
|
25
28
|
"pretty": true,
|
|
26
|
-
"esModuleInterop":
|
|
29
|
+
"esModuleInterop": true,
|
|
27
30
|
"allowSyntheticDefaultImports": true
|
|
28
31
|
}
|
|
29
32
|
}
|