@nivinjoseph/n-sec 4.0.4 → 5.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/dist/api-security/alg-type.js +1 -0
- package/dist/api-security/alg-type.js.map +1 -1
- package/dist/api-security/claim.d.ts +0 -1
- package/dist/api-security/claim.js +2 -2
- 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.d.ts +0 -1
- package/dist/api-security/expired-token-exception.js +2 -2
- package/dist/api-security/expired-token-exception.js.map +1 -1
- package/dist/api-security/invalid-token-exception.d.ts +0 -1
- package/dist/api-security/invalid-token-exception.js +3 -3
- package/dist/api-security/invalid-token-exception.js.map +1 -1
- package/dist/api-security/json-web-token.d.ts +2 -3
- package/dist/api-security/json-web-token.js +58 -70
- package/dist/api-security/json-web-token.js.map +1 -1
- package/dist/api-security/security-token.js +1 -0
- package/dist/api-security/security-token.js.map +1 -1
- package/dist/crypto/crypto-exception.js +1 -0
- package/dist/crypto/crypto-exception.js.map +1 -1
- package/dist/crypto/hash.d.ts +2 -3
- package/dist/crypto/hash.js +5 -5
- package/dist/crypto/hash.js.map +1 -1
- package/dist/crypto/hmac.d.ts +1 -2
- package/dist/crypto/hmac.js +4 -4
- package/dist/crypto/hmac.js.map +1 -1
- package/dist/crypto/symmetric-encryption.d.ts +1 -2
- package/dist/crypto/symmetric-encryption.js +15 -20
- package/dist/crypto/symmetric-encryption.js.map +1 -1
- package/dist/index.js +12 -11
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
- package/src/api-security/claim.ts +1 -2
- package/src/api-security/expired-token-exception.ts +1 -2
- package/src/api-security/invalid-token-exception.ts +2 -3
- package/src/api-security/json-web-token.ts +26 -27
- package/src/crypto/hash.ts +6 -7
- package/src/crypto/hmac.ts +4 -5
- package/src/crypto/symmetric-encryption.ts +17 -25
- package/test/hash.test.ts +22 -23
- package/test/hmac.test.ts +9 -9
- package/test/json-web-token.test.ts +35 -33
- package/test/symmetric-encryption.test.ts +2 -1
- package/tsconfig.json +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nivinjoseph/n-sec",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "Security library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -32,17 +32,17 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://github.com/nivinjoseph/n-sec#readme",
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/mocha": "^
|
|
36
|
-
"@types/node": "^
|
|
37
|
-
"mocha": "^
|
|
38
|
-
"ts-node": "^
|
|
39
|
-
"tslint": "^
|
|
40
|
-
"typescript": "^3.
|
|
41
|
-
"typescript-tslint-plugin": "^0.
|
|
35
|
+
"@types/mocha": "^8.2.2",
|
|
36
|
+
"@types/node": "^14.14.43",
|
|
37
|
+
"mocha": "^8.3.2",
|
|
38
|
+
"ts-node": "^9.1.1",
|
|
39
|
+
"tslint": "^6.1.3",
|
|
40
|
+
"typescript": "^4.3.5",
|
|
41
|
+
"typescript-tslint-plugin": "^1.0.1"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@nivinjoseph/n-defensive": "^1.0.
|
|
45
|
-
"@nivinjoseph/n-exception": "^1.0.
|
|
46
|
-
"@nivinjoseph/n-ext": "^1.1.
|
|
44
|
+
"@nivinjoseph/n-defensive": "^1.0.37",
|
|
45
|
+
"@nivinjoseph/n-exception": "^1.0.24",
|
|
46
|
+
"@nivinjoseph/n-ext": "^1.1.34"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { given } from "@nivinjoseph/n-defensive";
|
|
2
|
-
import "@nivinjoseph/n-ext";
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
// public
|
|
@@ -15,7 +14,7 @@ export class Claim
|
|
|
15
14
|
|
|
16
15
|
public constructor(type: string, value: any)
|
|
17
16
|
{
|
|
18
|
-
given(type, "type").ensureHasValue()
|
|
17
|
+
given(type, "type").ensureHasValue();
|
|
19
18
|
|
|
20
19
|
this._type = type.trim();
|
|
21
20
|
this._value = value;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Exception } from "@nivinjoseph/n-exception";
|
|
2
2
|
import { given } from "@nivinjoseph/n-defensive";
|
|
3
|
-
import "@nivinjoseph/n-ext";
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
// public
|
|
@@ -14,7 +13,7 @@ export class ExpiredTokenException extends Exception
|
|
|
14
13
|
|
|
15
14
|
public constructor(token: string)
|
|
16
15
|
{
|
|
17
|
-
given(token, "token").ensureHasValue()
|
|
16
|
+
given(token, "token").ensureHasValue();
|
|
18
17
|
token = token.trim();
|
|
19
18
|
super(`Token '${token}' is expired.`);
|
|
20
19
|
this._token = token;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Exception } from "@nivinjoseph/n-exception";
|
|
2
2
|
import { given } from "@nivinjoseph/n-defensive";
|
|
3
|
-
import "@nivinjoseph/n-ext";
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
// public
|
|
@@ -16,8 +15,8 @@ export class InvalidTokenException extends Exception
|
|
|
16
15
|
|
|
17
16
|
public constructor(token: string, reason: string)
|
|
18
17
|
{
|
|
19
|
-
given(token, "token").ensureHasValue()
|
|
20
|
-
given(reason, "reason").ensureHasValue()
|
|
18
|
+
given(token, "token").ensureHasValue();
|
|
19
|
+
given(reason, "reason").ensureHasValue();
|
|
21
20
|
|
|
22
21
|
token = token.trim();
|
|
23
22
|
super(`Token '${token}' is invalid because ${reason}.`);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Claim } from "./claim";
|
|
2
2
|
import { InvalidOperationException } from "@nivinjoseph/n-exception";
|
|
3
3
|
import { given } from "@nivinjoseph/n-defensive";
|
|
4
|
-
import "@nivinjoseph/n-ext";
|
|
5
4
|
import { InvalidTokenException } from "./invalid-token-exception";
|
|
6
5
|
import { AlgType } from "./alg-type";
|
|
7
6
|
import { Hmac } from "./../crypto/hmac";
|
|
@@ -32,9 +31,9 @@ export class JsonWebToken
|
|
|
32
31
|
private constructor(issuer: string, algType: AlgType, key: string, isFullKey: boolean, expiry: number,
|
|
33
32
|
claims: Array<Claim>)
|
|
34
33
|
{
|
|
35
|
-
given(issuer, "issuer").ensureHasValue()
|
|
36
|
-
given(algType, "algType").ensureHasValue().
|
|
37
|
-
given(key, "key").ensureHasValue()
|
|
34
|
+
given(issuer, "issuer").ensureHasValue();
|
|
35
|
+
given(algType, "algType").ensureHasValue().ensureIsEnum(AlgType);
|
|
36
|
+
given(key, "key").ensureHasValue();
|
|
38
37
|
given(isFullKey, "isFullKey").ensureHasValue();
|
|
39
38
|
given(expiry, "expiry").ensureHasValue();
|
|
40
39
|
given(claims, "claims")
|
|
@@ -49,29 +48,29 @@ export class JsonWebToken
|
|
|
49
48
|
this._claims = [...claims];
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
public
|
|
51
|
+
public generateToken(): string
|
|
53
52
|
{
|
|
54
53
|
if (!this._isfullKey)
|
|
55
54
|
throw new InvalidOperationException("generating token using an instance created from token");
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
const header: Header = {
|
|
58
57
|
iss: this._issuer,
|
|
59
58
|
alg: this._algType,
|
|
60
59
|
exp: this._expiry
|
|
61
60
|
};
|
|
62
61
|
|
|
63
|
-
|
|
62
|
+
const body: any = {};
|
|
64
63
|
this._claims.forEach(t => body[t.type] = t.value);
|
|
65
64
|
|
|
66
|
-
|
|
65
|
+
const headerAndBody = this.toHex(header) + "." + this.toHex(body);
|
|
67
66
|
|
|
68
67
|
// let signature = this._algType === AlgType.hmac
|
|
69
68
|
// ? await Hmac.create(this._key, headerAndBody)
|
|
70
69
|
// : await DigitalSignature.sign(this._key, headerAndBody);
|
|
71
70
|
|
|
72
|
-
|
|
71
|
+
const signature = Hmac.create(this._key, headerAndBody);
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
const token = headerAndBody + "." + signature;
|
|
75
74
|
return token;
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -82,27 +81,27 @@ export class JsonWebToken
|
|
|
82
81
|
return new JsonWebToken(issuer, algType, key, true, expiry, claims);
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
public static
|
|
84
|
+
public static fromToken(issuer: string, algType: AlgType, key: string, token: string): JsonWebToken
|
|
86
85
|
{
|
|
87
|
-
given(issuer, "issuer").ensureHasValue()
|
|
88
|
-
given(algType, "algType").ensureHasValue().
|
|
89
|
-
given(key, "key").ensureHasValue()
|
|
90
|
-
given(token, "token").ensureHasValue()
|
|
86
|
+
given(issuer, "issuer").ensureHasValue();
|
|
87
|
+
given(algType, "algType").ensureHasValue().ensureIsEnum(AlgType);
|
|
88
|
+
given(key, "key").ensureHasValue();
|
|
89
|
+
given(token, "token").ensureHasValue();
|
|
91
90
|
|
|
92
91
|
issuer = issuer.trim();
|
|
93
92
|
key = key.trim();
|
|
94
93
|
token = token.trim();
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
const tokenSplitted = token.split(".");
|
|
97
96
|
if (tokenSplitted.length !== 3)
|
|
98
97
|
throw new InvalidTokenException(token, "format is incorrect");
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
const headerString = tokenSplitted[0];
|
|
100
|
+
const bodyString = tokenSplitted[1];
|
|
101
|
+
const signature = tokenSplitted[2];
|
|
103
102
|
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
const header: Header = JsonWebToken.toObject(headerString) as Header;
|
|
104
|
+
const body: any = JsonWebToken.toObject(bodyString);
|
|
106
105
|
|
|
107
106
|
if (header.iss === undefined || header.iss === null)
|
|
108
107
|
throw new InvalidTokenException(token, "iss was not present");
|
|
@@ -140,11 +139,11 @@ export class JsonWebToken
|
|
|
140
139
|
// throw new InvalidTokenException(token, "signature could not be verified");
|
|
141
140
|
// }
|
|
142
141
|
|
|
143
|
-
|
|
142
|
+
const computedSignature = Hmac.create(key, headerString + "." + bodyString);
|
|
144
143
|
if (computedSignature !== signature)
|
|
145
144
|
throw new InvalidTokenException(token, "signature could not be verified");
|
|
146
145
|
|
|
147
|
-
|
|
146
|
+
const claims = new Array<Claim>();
|
|
148
147
|
for (let item in body)
|
|
149
148
|
claims.push(new Claim(item, body[item]));
|
|
150
149
|
|
|
@@ -153,15 +152,15 @@ export class JsonWebToken
|
|
|
153
152
|
|
|
154
153
|
private toHex(obj: object): string
|
|
155
154
|
{
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
const json = JSON.stringify(obj);
|
|
156
|
+
const hex = Buffer.from(json, "utf8").toString("hex");
|
|
158
157
|
return hex.toUpperCase();
|
|
159
158
|
}
|
|
160
159
|
|
|
161
160
|
private static toObject(hex: string): object
|
|
162
161
|
{
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
const json = Buffer.from(hex.toLowerCase(), "hex").toString("utf8");
|
|
163
|
+
const obj = JSON.parse(json);
|
|
165
164
|
return obj;
|
|
166
165
|
}
|
|
167
166
|
}
|
package/src/crypto/hash.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { given } from "@nivinjoseph/n-defensive";
|
|
2
|
-
import "@nivinjoseph/n-ext";
|
|
3
2
|
import * as Crypto from "crypto";
|
|
4
3
|
|
|
5
4
|
|
|
@@ -9,21 +8,21 @@ export class Hash
|
|
|
9
8
|
private constructor() { }
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
public static create(value: string):
|
|
11
|
+
public static create(value: string): string
|
|
13
12
|
{
|
|
14
|
-
given(value, "value").ensureHasValue().ensureIsString()
|
|
13
|
+
given(value, "value").ensureHasValue().ensureIsString();
|
|
15
14
|
|
|
16
15
|
value = value.trim();
|
|
17
16
|
|
|
18
17
|
const hash = Crypto.createHash("sha512");
|
|
19
18
|
hash.update(value, "utf8");
|
|
20
|
-
return
|
|
19
|
+
return hash.digest("hex").toUpperCase();
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
public static createUsingSalt(value: string, salt: string):
|
|
22
|
+
public static createUsingSalt(value: string, salt: string): string
|
|
24
23
|
{
|
|
25
|
-
given(value, "value").ensureHasValue().ensureIsString()
|
|
26
|
-
given(salt, "salt").ensureHasValue().ensureIsString()
|
|
24
|
+
given(value, "value").ensureHasValue().ensureIsString();
|
|
25
|
+
given(salt, "salt").ensureHasValue().ensureIsString();
|
|
27
26
|
|
|
28
27
|
value = value.trim();
|
|
29
28
|
salt = salt.trim();
|
package/src/crypto/hmac.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { given } from "@nivinjoseph/n-defensive";
|
|
2
|
-
import "@nivinjoseph/n-ext";
|
|
3
2
|
import * as Crypto from "crypto";
|
|
4
3
|
|
|
5
4
|
|
|
@@ -9,10 +8,10 @@ export class Hmac
|
|
|
9
8
|
private constructor() { }
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
public static create(key: string, value: string):
|
|
11
|
+
public static create(key: string, value: string): string
|
|
13
12
|
{
|
|
14
|
-
given(key, "key").ensureHasValue().ensureIsString()
|
|
15
|
-
given(value, "value").ensureHasValue().ensureIsString()
|
|
13
|
+
given(key, "key").ensureHasValue().ensureIsString();
|
|
14
|
+
given(value, "value").ensureHasValue().ensureIsString();
|
|
16
15
|
|
|
17
16
|
key = key.trim();
|
|
18
17
|
value = value.trim();
|
|
@@ -20,6 +19,6 @@ export class Hmac
|
|
|
20
19
|
const hmac = Crypto.createHmac("sha256", Buffer.from(key, "hex"));
|
|
21
20
|
|
|
22
21
|
hmac.update(value, "utf8");
|
|
23
|
-
return
|
|
22
|
+
return hmac.digest("hex").toUpperCase();
|
|
24
23
|
}
|
|
25
24
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as Crypto from "crypto";
|
|
2
2
|
import { CryptoException } from "./crypto-exception";
|
|
3
3
|
import { given } from "@nivinjoseph/n-defensive";
|
|
4
|
-
import "@nivinjoseph/n-ext";
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
// public
|
|
@@ -29,14 +28,14 @@ export class SymmetricEncryption
|
|
|
29
28
|
|
|
30
29
|
public static encrypt(key: string, value: string): Promise<string>
|
|
31
30
|
{
|
|
32
|
-
given(key, "key").ensureHasValue().ensureIsString().ensure(t => !t.isEmptyOrWhiteSpace());
|
|
33
|
-
given(value, "value").ensureHasValue().ensureIsString().ensure(t => !t.isEmptyOrWhiteSpace());
|
|
34
|
-
|
|
35
|
-
key = key.trim();
|
|
36
|
-
value = value.trim();
|
|
37
|
-
|
|
38
31
|
return new Promise<string>((resolve, reject) =>
|
|
39
32
|
{
|
|
33
|
+
given(key, "key").ensureHasValue().ensureIsString();
|
|
34
|
+
given(value, "value").ensureHasValue().ensureIsString();
|
|
35
|
+
|
|
36
|
+
key = key.trim();
|
|
37
|
+
value = value.trim();
|
|
38
|
+
|
|
40
39
|
Crypto.randomBytes(16, (err, buf) =>
|
|
41
40
|
{
|
|
42
41
|
if (err)
|
|
@@ -64,29 +63,22 @@ export class SymmetricEncryption
|
|
|
64
63
|
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
public static decrypt(key: string, value: string):
|
|
66
|
+
public static decrypt(key: string, value: string): string
|
|
68
67
|
{
|
|
69
|
-
given(key, "key").ensureHasValue().ensureIsString()
|
|
70
|
-
given(value, "value").ensureHasValue().ensureIsString()
|
|
68
|
+
given(key, "key").ensureHasValue().ensureIsString();
|
|
69
|
+
given(value, "value").ensureHasValue().ensureIsString();
|
|
71
70
|
|
|
72
71
|
key = key.trim();
|
|
73
72
|
value = value.trim();
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (splitted.length !== 2)
|
|
79
|
-
throw new CryptoException("Invalid value.");
|
|
74
|
+
const splitted = value.split(".");
|
|
75
|
+
if (splitted.length !== 2)
|
|
76
|
+
throw new CryptoException("Invalid value.");
|
|
80
77
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
catch (error)
|
|
88
|
-
{
|
|
89
|
-
return Promise.reject(error);
|
|
90
|
-
}
|
|
78
|
+
const iv = Buffer.from(splitted[1], "hex");
|
|
79
|
+
const deCipher = Crypto.createDecipheriv("AES-256-CBC", Buffer.from(key, "hex"), iv);
|
|
80
|
+
let decrypted = deCipher.update(splitted[0], "hex", "utf8");
|
|
81
|
+
decrypted += deCipher.final("utf8");
|
|
82
|
+
return decrypted;
|
|
91
83
|
}
|
|
92
84
|
}
|
package/test/hash.test.ts
CHANGED
|
@@ -2,34 +2,33 @@ import * as Assert from "assert";
|
|
|
2
2
|
import { Hash } from "./../src/index";
|
|
3
3
|
import "@nivinjoseph/n-ext";
|
|
4
4
|
// import { CryptoException } from "./../src/crypto-exception";
|
|
5
|
-
import "@nivinjoseph/n-ext";
|
|
6
5
|
|
|
7
6
|
suite("Hash", () =>
|
|
8
7
|
{
|
|
9
8
|
suite("create", () =>
|
|
10
9
|
{
|
|
11
|
-
test("must return a string value that is not null, empty, whitespace or same as input when called with a valid input",
|
|
10
|
+
test("must return a string value that is not null, empty, whitespace or same as input when called with a valid input", () =>
|
|
12
11
|
{
|
|
13
12
|
let input = "hello world";
|
|
14
|
-
let hash =
|
|
13
|
+
let hash = Hash.create(input);
|
|
15
14
|
Assert.ok(hash !== null && !hash.isEmptyOrWhiteSpace());
|
|
16
15
|
Assert.notStrictEqual(hash, input);
|
|
17
16
|
});
|
|
18
17
|
|
|
19
|
-
test("multiple invocations with the same input must return the same output",
|
|
18
|
+
test("multiple invocations with the same input must return the same output", () =>
|
|
20
19
|
{
|
|
21
20
|
let input = "hello world";
|
|
22
|
-
let hash1 =
|
|
23
|
-
let hash2 =
|
|
21
|
+
let hash1 = Hash.create(input);
|
|
22
|
+
let hash2 = Hash.create(input);
|
|
24
23
|
Assert.strictEqual(hash1, hash2);
|
|
25
24
|
});
|
|
26
25
|
|
|
27
|
-
test("multiple invocations with the different inputs must return different outputs",
|
|
26
|
+
test("multiple invocations with the different inputs must return different outputs", () =>
|
|
28
27
|
{
|
|
29
28
|
let input1 = "hello world";
|
|
30
|
-
let hash1 =
|
|
29
|
+
let hash1 = Hash.create(input1);
|
|
31
30
|
let input2 = "goodbye world";
|
|
32
|
-
let hash2 =
|
|
31
|
+
let hash2 = Hash.create(input2);
|
|
33
32
|
Assert.notStrictEqual(hash1, hash2);
|
|
34
33
|
});
|
|
35
34
|
|
|
@@ -92,58 +91,58 @@ suite("Hash", () =>
|
|
|
92
91
|
|
|
93
92
|
suite("createUsingSalt", () =>
|
|
94
93
|
{
|
|
95
|
-
test("must return a string value that is not null, empty, whitespace or same as input or salt when called with a valid input and salt",
|
|
94
|
+
test("must return a string value that is not null, empty, whitespace or same as input or salt when called with a valid input and salt", () =>
|
|
96
95
|
{
|
|
97
96
|
let input = "hello world";
|
|
98
97
|
let salt = "salt";
|
|
99
|
-
let hash =
|
|
98
|
+
let hash = Hash.createUsingSalt(input, salt);
|
|
100
99
|
Assert.ok(hash !== null && !hash.isEmptyOrWhiteSpace());
|
|
101
100
|
Assert.notStrictEqual(hash, input);
|
|
102
101
|
Assert.notStrictEqual(hash, salt);
|
|
103
102
|
});
|
|
104
103
|
|
|
105
|
-
test("multiple invocations with the same input and salt must return the same output",
|
|
104
|
+
test("multiple invocations with the same input and salt must return the same output", () =>
|
|
106
105
|
{
|
|
107
106
|
let input = "hello world";
|
|
108
107
|
let salt = "salt";
|
|
109
|
-
let hash1 =
|
|
110
|
-
let hash2 =
|
|
108
|
+
let hash1 = Hash.createUsingSalt(input, salt);
|
|
109
|
+
let hash2 = Hash.createUsingSalt(input, salt);
|
|
111
110
|
Assert.strictEqual(hash1, hash2);
|
|
112
111
|
});
|
|
113
112
|
|
|
114
|
-
test("multiple invocations with different inputs and different salts must return different outputs",
|
|
113
|
+
test("multiple invocations with different inputs and different salts must return different outputs", () =>
|
|
115
114
|
{
|
|
116
115
|
let input1 = "hello world";
|
|
117
116
|
let salt1 = "salt-1";
|
|
118
|
-
let hash1 =
|
|
117
|
+
let hash1 = Hash.createUsingSalt(input1, salt1);
|
|
119
118
|
|
|
120
119
|
let input2 = "goodbye world";
|
|
121
120
|
let salt2 = "salt-2";
|
|
122
|
-
let hash2 =
|
|
121
|
+
let hash2 = Hash.createUsingSalt(input2, salt2);
|
|
123
122
|
|
|
124
123
|
Assert.notStrictEqual(hash1, hash2);
|
|
125
124
|
});
|
|
126
125
|
|
|
127
|
-
test("multiple invocations with different inputs and the same salt must return different outputs",
|
|
126
|
+
test("multiple invocations with different inputs and the same salt must return different outputs", () =>
|
|
128
127
|
{
|
|
129
128
|
let input1 = "hello world";
|
|
130
129
|
let salt1 = "salt-1";
|
|
131
|
-
let hash1 =
|
|
130
|
+
let hash1 = Hash.createUsingSalt(input1, salt1);
|
|
132
131
|
|
|
133
132
|
let input2 = "goodbye world";
|
|
134
|
-
let hash2 =
|
|
133
|
+
let hash2 = Hash.createUsingSalt(input2, salt1);
|
|
135
134
|
|
|
136
135
|
Assert.notStrictEqual(hash1, hash2);
|
|
137
136
|
});
|
|
138
137
|
|
|
139
|
-
test("multiple invocations with the same input and different salts must return different outputs",
|
|
138
|
+
test("multiple invocations with the same input and different salts must return different outputs", () =>
|
|
140
139
|
{
|
|
141
140
|
let input = "hello world";
|
|
142
141
|
let salt1 = "salt-1";
|
|
143
|
-
let hash1 =
|
|
142
|
+
let hash1 = Hash.createUsingSalt(input, salt1);
|
|
144
143
|
|
|
145
144
|
let salt2 = "salt-2";
|
|
146
|
-
let hash2 =
|
|
145
|
+
let hash2 = Hash.createUsingSalt(input, salt2);
|
|
147
146
|
|
|
148
147
|
Assert.notStrictEqual(hash1, hash2);
|
|
149
148
|
});
|
package/test/hmac.test.ts
CHANGED
|
@@ -11,7 +11,7 @@ suite("Hmac", () =>
|
|
|
11
11
|
{
|
|
12
12
|
let key = await SymmetricEncryption.generateKey();
|
|
13
13
|
let value = "hello world";
|
|
14
|
-
let hmac =
|
|
14
|
+
let hmac = Hmac.create(key, value);
|
|
15
15
|
Assert.ok(hmac !== null && !hmac.isEmptyOrWhiteSpace());
|
|
16
16
|
Assert.notStrictEqual(hmac, key);
|
|
17
17
|
Assert.notStrictEqual(hmac, value);
|
|
@@ -21,8 +21,8 @@ suite("Hmac", () =>
|
|
|
21
21
|
{
|
|
22
22
|
let key = await SymmetricEncryption.generateKey();
|
|
23
23
|
let value = "hello world";
|
|
24
|
-
let hmac1 =
|
|
25
|
-
let hmac2 =
|
|
24
|
+
let hmac1 = Hmac.create(key, value);
|
|
25
|
+
let hmac2 = Hmac.create(key, value);
|
|
26
26
|
Assert.strictEqual(hmac1, hmac2);
|
|
27
27
|
});
|
|
28
28
|
|
|
@@ -30,11 +30,11 @@ suite("Hmac", () =>
|
|
|
30
30
|
{
|
|
31
31
|
let key1 = await SymmetricEncryption.generateKey();
|
|
32
32
|
let value1 = "hello world";
|
|
33
|
-
let hmac1 =
|
|
33
|
+
let hmac1 = Hmac.create(key1, value1);
|
|
34
34
|
|
|
35
35
|
let key2 = await SymmetricEncryption.generateKey();
|
|
36
36
|
let value2 = "goodbye world";
|
|
37
|
-
let hmac2 =
|
|
37
|
+
let hmac2 = Hmac.create(key2, value2);
|
|
38
38
|
Assert.notStrictEqual(hmac1, hmac2);
|
|
39
39
|
});
|
|
40
40
|
|
|
@@ -43,8 +43,8 @@ suite("Hmac", () =>
|
|
|
43
43
|
let key = await SymmetricEncryption.generateKey();
|
|
44
44
|
let value1 = "hello world";
|
|
45
45
|
let value2 = "goodbye world";
|
|
46
|
-
let hmac1 =
|
|
47
|
-
let hmac2 =
|
|
46
|
+
let hmac1 = Hmac.create(key, value1);
|
|
47
|
+
let hmac2 = Hmac.create(key, value2);
|
|
48
48
|
Assert.notStrictEqual(hmac1, hmac2);
|
|
49
49
|
});
|
|
50
50
|
|
|
@@ -53,8 +53,8 @@ suite("Hmac", () =>
|
|
|
53
53
|
let key1 = await SymmetricEncryption.generateKey();
|
|
54
54
|
let key2 = await SymmetricEncryption.generateKey();
|
|
55
55
|
let value = "hello world";
|
|
56
|
-
let hmac1 =
|
|
57
|
-
let hmac2 =
|
|
56
|
+
let hmac1 = Hmac.create(key1, value);
|
|
57
|
+
let hmac2 = Hmac.create(key2, value);
|
|
58
58
|
Assert.notStrictEqual(hmac1, hmac2);
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -17,8 +17,8 @@ suite("Json Web Token ", () =>
|
|
|
17
17
|
let claim = new Claim("this_claim", "ThisValue");
|
|
18
18
|
let key = await SymmetricEncryption.generateKey();
|
|
19
19
|
let time = Date.now();
|
|
20
|
-
let token =
|
|
21
|
-
let jwt =
|
|
20
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim]).generateToken();
|
|
21
|
+
let jwt = JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
22
22
|
Assert.ok(jwt !== null || jwt !== undefined);
|
|
23
23
|
Assert.strictEqual(jwt.issuer, "issuer1");
|
|
24
24
|
Assert.strictEqual(jwt.algType, 1);
|
|
@@ -32,8 +32,8 @@ suite("Json Web Token ", () =>
|
|
|
32
32
|
let claim2 = new Claim("that_claim", "ThatValue");
|
|
33
33
|
let key = await SymmetricEncryption.generateKey();
|
|
34
34
|
let time = Date.now();
|
|
35
|
-
let token =
|
|
36
|
-
let jwt =
|
|
35
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim1, claim2]).generateToken();
|
|
36
|
+
let jwt = JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
37
37
|
Assert.ok(jwt !== null || jwt !== undefined);
|
|
38
38
|
Assert.strictEqual(jwt.issuer, "issuer1");
|
|
39
39
|
Assert.strictEqual(jwt.algType, 1);
|
|
@@ -47,8 +47,8 @@ suite("Json Web Token ", () =>
|
|
|
47
47
|
let claim2 = new Claim("that_claim", "ThatValue");
|
|
48
48
|
let key = await SymmetricEncryption.generateKey();
|
|
49
49
|
let time = Date.now();
|
|
50
|
-
let token =
|
|
51
|
-
let jwt =
|
|
50
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim1, claim2]).generateToken();
|
|
51
|
+
let jwt = JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
52
52
|
Assert.ok(jwt !== null || jwt !== undefined);
|
|
53
53
|
Assert.strictEqual(jwt.issuer, "issuer1");
|
|
54
54
|
Assert.strictEqual(jwt.algType, 1);
|
|
@@ -62,10 +62,10 @@ suite("Json Web Token ", () =>
|
|
|
62
62
|
let claim2 = new Claim("that_claim", "ThatValue");
|
|
63
63
|
let key = await SymmetricEncryption.generateKey();
|
|
64
64
|
let time = Date.now();
|
|
65
|
-
let token =
|
|
65
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 10000000, [claim1, claim2]).generateToken();
|
|
66
66
|
try
|
|
67
67
|
{
|
|
68
|
-
|
|
68
|
+
JsonWebToken.fromToken("notTheIssuer", 1, key, token);
|
|
69
69
|
}
|
|
70
70
|
catch (exp)
|
|
71
71
|
{
|
|
@@ -82,10 +82,10 @@ suite("Json Web Token ", () =>
|
|
|
82
82
|
let claim2 = new Claim("that_claim", "ThatValue");
|
|
83
83
|
let key = await SymmetricEncryption.generateKey();
|
|
84
84
|
let time = Date.now();
|
|
85
|
-
let token =
|
|
85
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time, [claim1, claim2]).generateToken();
|
|
86
86
|
try
|
|
87
87
|
{
|
|
88
|
-
|
|
88
|
+
JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
89
89
|
}
|
|
90
90
|
catch (exp)
|
|
91
91
|
{
|
|
@@ -96,25 +96,27 @@ suite("Json Web Token ", () =>
|
|
|
96
96
|
Assert.ok(false);
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
99
|
+
// TODO: right now we only support one alg type. When we support others, we should uncomment this test
|
|
100
|
+
// test("should throw an exception when getting JWT algorithm given is different than what was used for the token generation", async () =>
|
|
101
|
+
// {
|
|
102
|
+
// let claim1 = new Claim("this_claim", "ThisValue");
|
|
103
|
+
// let claim2 = new Claim("that_claim", "ThatValue");
|
|
104
|
+
// let key = await SymmetricEncryption.generateKey();
|
|
105
|
+
// let time = Date.now();
|
|
106
|
+
// let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 1000000, [claim1, claim2]).generateToken();
|
|
107
|
+
// try
|
|
108
|
+
// {
|
|
109
|
+
// JsonWebToken.fromToken("issuer1", 2, key, token);
|
|
110
|
+
// }
|
|
111
|
+
// catch (exp)
|
|
112
|
+
// {
|
|
113
|
+
// console.log(exp);
|
|
114
|
+
// Assert.ok(exp instanceof InvalidTokenException);
|
|
115
|
+
// Assert.equal(exp.message, `Token '${token}' is invalid because alg was expected to be '${2}' but instead was '${1}'.`);
|
|
116
|
+
// return;
|
|
117
|
+
// }
|
|
118
|
+
// Assert.ok(false);
|
|
119
|
+
// });
|
|
118
120
|
|
|
119
121
|
test("should throw an exception when getting JWT key given is different than what was used for the token generation", async () =>
|
|
120
122
|
{
|
|
@@ -123,10 +125,10 @@ suite("Json Web Token ", () =>
|
|
|
123
125
|
let key = await SymmetricEncryption.generateKey();
|
|
124
126
|
let key2 = await SymmetricEncryption.generateKey();
|
|
125
127
|
let time = Date.now();
|
|
126
|
-
let token =
|
|
128
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 1000000, [claim1, claim2]).generateToken();
|
|
127
129
|
try
|
|
128
130
|
{
|
|
129
|
-
|
|
131
|
+
JsonWebToken.fromToken("issuer1", 1, key2, token);
|
|
130
132
|
}
|
|
131
133
|
catch (exp)
|
|
132
134
|
{
|
|
@@ -143,11 +145,11 @@ suite("Json Web Token ", () =>
|
|
|
143
145
|
let claim2 = new Claim("that_claim", "ThatValue");
|
|
144
146
|
let key = await SymmetricEncryption.generateKey();
|
|
145
147
|
let time = Date.now();
|
|
146
|
-
let token =
|
|
148
|
+
let token = JsonWebToken.fromClaims("issuer1", 1, key, time + 1000000, [claim1, claim2]).generateToken();
|
|
147
149
|
token = token + "someStuff";
|
|
148
150
|
try
|
|
149
151
|
{
|
|
150
|
-
|
|
152
|
+
JsonWebToken.fromToken("issuer1", 1, key, token);
|
|
151
153
|
}
|
|
152
154
|
catch (exp)
|
|
153
155
|
{
|