@payello-module/jwt 0.1.0 → 0.1.2
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/JWT.d.ts +32 -0
- package/dist/{index.esm.js → JWT.js} +35 -12
- package/dist/JwtError.js +6 -0
- package/dist/JwtExtractOpts.js +1 -0
- package/dist/JwtHeader.js +1 -0
- package/dist/JwtSignOpts.js +1 -0
- package/dist/example.d.ts +1 -0
- package/dist/example.js +13 -0
- package/dist/index.js +7 -87
- package/package.json +28 -41
- package/readme.md +94 -28
- package/dist/index.mjs +0 -85
- package/dist/index.mjs.map +0 -1
- package/dist/types/JWT.d.ts +0 -10
- /package/dist/{types/JwtError.d.ts → JwtError.d.ts} +0 -0
- /package/dist/{types/JwtExtract.d.ts → JwtExtract.d.ts} +0 -0
- /package/dist/{types/example.d.ts → JwtExtract.js} +0 -0
- /package/dist/{types/JwtExtractOpts.d.ts → JwtExtractOpts.d.ts} +0 -0
- /package/dist/{types/JwtHeader.d.ts → JwtHeader.d.ts} +0 -0
- /package/dist/{types/JwtSignOpts.d.ts → JwtSignOpts.d.ts} +0 -0
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
package/dist/JWT.d.ts
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import { JwtSignOpts } from "./JwtSignOpts";
|
2
|
+
import { JwtExtract } from "./JwtExtract";
|
3
|
+
import { JwtExtractOpts } from "./JwtExtractOpts";
|
4
|
+
/**
|
5
|
+
* Class representing JSON Web Tokens (JWT) functionalities, including signing, extracting components,
|
6
|
+
* and verifying the signature of the token.
|
7
|
+
*/
|
8
|
+
export declare class JWT {
|
9
|
+
/**
|
10
|
+
* Signs the given payload and returns a JWT string.
|
11
|
+
* @param payload - The payload of the JWT which is the content that you want to protect.
|
12
|
+
* @param options - The options for signing the JWT, including the private key, public key, and algorithm.
|
13
|
+
* @returns A promise that resolves to the signed JWT string.
|
14
|
+
*/
|
15
|
+
static sign(payload: any, options?: JwtSignOpts): Promise<string>;
|
16
|
+
/**
|
17
|
+
* Extracts and returns the header, payload, and signature components from a JWT string.
|
18
|
+
* @param input - The JWT string to be parsed.
|
19
|
+
* @param opts - Optional parameters, including the requirements for the presence of required properties in the payload.
|
20
|
+
* @returns A promise that resolves to an object containing the separated components of the JWT (header, payload, signature).
|
21
|
+
*/
|
22
|
+
static extract(input: string, opts?: JwtExtractOpts): Promise<JwtExtract>;
|
23
|
+
/**
|
24
|
+
* Verifies the given JWT string using the secret key fetched by the given issuer.
|
25
|
+
* @param input - The JWT string to be verified.
|
26
|
+
* @param opts - An object containing a function getSecretKey to retrieve the secret key based on the issuer.
|
27
|
+
* @returns A promise that resolves to a boolean indicating whether the JWT has been verified successfully or not.
|
28
|
+
*/
|
29
|
+
static verify(input: string, opts: {
|
30
|
+
getSecretKey(issuer: string): Promise<string>;
|
31
|
+
}): Promise<true>;
|
32
|
+
}
|
@@ -1,18 +1,22 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
import { HmacSha256, HmacSha512 } from "@payello-module/encryption";
|
2
|
+
import { JwtError } from "./JwtError";
|
3
|
+
/**
|
4
|
+
* Class representing JSON Web Tokens (JWT) functionalities, including signing, extracting components,
|
5
|
+
* and verifying the signature of the token.
|
6
|
+
*/
|
7
|
+
export class JWT {
|
8
|
+
/**
|
9
|
+
* Signs the given payload and returns a JWT string.
|
10
|
+
* @param payload - The payload of the JWT which is the content that you want to protect.
|
11
|
+
* @param options - The options for signing the JWT, including the private key, public key, and algorithm.
|
12
|
+
* @returns A promise that resolves to the signed JWT string.
|
13
|
+
*/
|
11
14
|
static async sign(payload, options = { privKey: '', pubKey: '', algorithm: 'HS512' }) {
|
12
15
|
const _header = {
|
13
16
|
typ: 'JWT',
|
14
17
|
alg: options.algorithm
|
15
18
|
};
|
19
|
+
// Create payload with unique identifier, issued-at time, and incorporate the public key if provided.
|
16
20
|
const _payload = {
|
17
21
|
jti: `jti_${Date.now().valueOf()}`,
|
18
22
|
iat: Math.floor(Date.now().valueOf() / 1000),
|
@@ -21,6 +25,7 @@ class JWT {
|
|
21
25
|
};
|
22
26
|
const _body = btoa(JSON.stringify(_header)) + "." + btoa(JSON.stringify(_payload));
|
23
27
|
let signature = "";
|
28
|
+
// Create signature based on selected algorithm.
|
24
29
|
switch (options.algorithm) {
|
25
30
|
case 'HS256':
|
26
31
|
signature = await HmacSha256.encrypt(_body, options.privKey);
|
@@ -29,10 +34,18 @@ class JWT {
|
|
29
34
|
signature = await HmacSha512.encrypt(_body, options.privKey);
|
30
35
|
break;
|
31
36
|
}
|
37
|
+
// Returns the final JWT token as a concatenation of header, payload, and signature
|
32
38
|
return _body + "." + signature;
|
33
39
|
}
|
40
|
+
/**
|
41
|
+
* Extracts and returns the header, payload, and signature components from a JWT string.
|
42
|
+
* @param input - The JWT string to be parsed.
|
43
|
+
* @param opts - Optional parameters, including the requirements for the presence of required properties in the payload.
|
44
|
+
* @returns A promise that resolves to an object containing the separated components of the JWT (header, payload, signature).
|
45
|
+
*/
|
34
46
|
static async extract(input, opts = {}) {
|
35
47
|
const bits = input.split(".");
|
48
|
+
// Ensures that the JWT string has three parts: header, payload, and signature.
|
36
49
|
if (bits.length !== 3) {
|
37
50
|
throw new JwtError(`Invalid number of parts in JWT string. Expected 3 but got ${bits.length}`);
|
38
51
|
}
|
@@ -44,26 +57,37 @@ class JWT {
|
|
44
57
|
if (!payload || !payload.jti) {
|
45
58
|
throw new JwtError("Payload invalid or missing jti value");
|
46
59
|
}
|
60
|
+
// Validates the present of required properties in the payload.
|
47
61
|
const requiredProps = opts.requiredProps || ["jti", "iss", "iat"];
|
48
62
|
for (const prop in requiredProps) {
|
49
63
|
if (!payload[prop]) {
|
50
64
|
throw new JwtError(`Payload missing ${prop} value`);
|
51
65
|
}
|
52
66
|
}
|
67
|
+
// Returns an object containing the extracted components of the JWT.
|
53
68
|
return {
|
54
69
|
header: header,
|
55
70
|
payload: payload,
|
56
71
|
signature: bits[2]
|
57
72
|
};
|
58
73
|
}
|
74
|
+
/**
|
75
|
+
* Verifies the given JWT string using the secret key fetched by the given issuer.
|
76
|
+
* @param input - The JWT string to be verified.
|
77
|
+
* @param opts - An object containing a function getSecretKey to retrieve the secret key based on the issuer.
|
78
|
+
* @returns A promise that resolves to a boolean indicating whether the JWT has been verified successfully or not.
|
79
|
+
*/
|
59
80
|
static async verify(input, opts) {
|
60
81
|
const extracted = await this.extract(input);
|
82
|
+
// Fetches the secret key based on the issuer in the payload.
|
61
83
|
const secretKey = await opts.getSecretKey(extracted.payload.jti);
|
62
84
|
if (!secretKey) {
|
63
85
|
throw new JwtError(`Public key not found`);
|
64
86
|
}
|
65
87
|
let verify = false;
|
88
|
+
// Preparation of the data to verify the signature.
|
66
89
|
const data = `${btoa(JSON.stringify(extracted.header))}.${btoa(JSON.stringify(extracted.payload))}`;
|
90
|
+
// Verification of the signature based on the algorithm specified in the header.
|
67
91
|
switch (extracted.header.alg) {
|
68
92
|
case 'HS256':
|
69
93
|
verify = await HmacSha256.verify(data, extracted.signature, secretKey);
|
@@ -77,8 +101,7 @@ class JWT {
|
|
77
101
|
if (!verify) {
|
78
102
|
throw new JwtError(`Signature not verified`);
|
79
103
|
}
|
104
|
+
// Returns the result of the verification process.
|
80
105
|
return verify;
|
81
106
|
}
|
82
107
|
}
|
83
|
-
|
84
|
-
export { JWT, JwtError };
|
package/dist/JwtError.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/dist/example.js
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import { JWT } from "./JWT";
|
2
|
+
async function example() {
|
3
|
+
const payload = {
|
4
|
+
exp: Math.floor(Date.now().valueOf() / 1000) + 300 // Expire in 300 seconds
|
5
|
+
};
|
6
|
+
const opts = {
|
7
|
+
privKey: "79c4e267e63845a986e669388fce66e9", // Private/Secret Key
|
8
|
+
pubKey: "f266a28e-5e9a-4fe3-90a8-2e8b2ef0f62d", // Public Key (Issuer ID)
|
9
|
+
algorithm: "HS256" // Possible values: HS256 or HS512
|
10
|
+
};
|
11
|
+
const jwt = await JWT.sign(payload, opts);
|
12
|
+
console.log(jwt);
|
13
|
+
}
|
package/dist/index.js
CHANGED
@@ -1,87 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
super(message, options);
|
9
|
-
}
|
10
|
-
}
|
11
|
-
|
12
|
-
class JWT {
|
13
|
-
static async sign(payload, options = { privKey: '', pubKey: '', algorithm: 'HS512' }) {
|
14
|
-
const _header = {
|
15
|
-
typ: 'JWT',
|
16
|
-
alg: options.algorithm
|
17
|
-
};
|
18
|
-
const _payload = {
|
19
|
-
jti: `jti_${Date.now().valueOf()}`,
|
20
|
-
iat: Math.floor(Date.now().valueOf() / 1000),
|
21
|
-
iss: options.pubKey,
|
22
|
-
...payload
|
23
|
-
};
|
24
|
-
const _body = btoa(JSON.stringify(_header)) + "." + btoa(JSON.stringify(_payload));
|
25
|
-
let signature = "";
|
26
|
-
switch (options.algorithm) {
|
27
|
-
case 'HS256':
|
28
|
-
signature = await encryption.HmacSha256.encrypt(_body, options.privKey);
|
29
|
-
break;
|
30
|
-
case 'HS512':
|
31
|
-
signature = await encryption.HmacSha512.encrypt(_body, options.privKey);
|
32
|
-
break;
|
33
|
-
}
|
34
|
-
return _body + "." + signature;
|
35
|
-
}
|
36
|
-
static async extract(input, opts = {}) {
|
37
|
-
const bits = input.split(".");
|
38
|
-
if (bits.length !== 3) {
|
39
|
-
throw new JwtError(`Invalid number of parts in JWT string. Expected 3 but got ${bits.length}`);
|
40
|
-
}
|
41
|
-
const header = JSON.parse(bits[0]);
|
42
|
-
if (!header || !header.typ || header.typ !== "JWT") {
|
43
|
-
throw new JwtError("Header invalid or type is not JWT");
|
44
|
-
}
|
45
|
-
const payload = JSON.parse(bits[1]);
|
46
|
-
if (!payload || !payload.jti) {
|
47
|
-
throw new JwtError("Payload invalid or missing jti value");
|
48
|
-
}
|
49
|
-
const requiredProps = opts.requiredProps || ["jti", "iss", "iat"];
|
50
|
-
for (const prop in requiredProps) {
|
51
|
-
if (!payload[prop]) {
|
52
|
-
throw new JwtError(`Payload missing ${prop} value`);
|
53
|
-
}
|
54
|
-
}
|
55
|
-
return {
|
56
|
-
header: header,
|
57
|
-
payload: payload,
|
58
|
-
signature: bits[2]
|
59
|
-
};
|
60
|
-
}
|
61
|
-
static async verify(input, opts) {
|
62
|
-
const extracted = await this.extract(input);
|
63
|
-
const secretKey = await opts.getSecretKey(extracted.payload.jti);
|
64
|
-
if (!secretKey) {
|
65
|
-
throw new JwtError(`Public key not found`);
|
66
|
-
}
|
67
|
-
let verify = false;
|
68
|
-
const data = `${btoa(JSON.stringify(extracted.header))}.${btoa(JSON.stringify(extracted.payload))}`;
|
69
|
-
switch (extracted.header.alg) {
|
70
|
-
case 'HS256':
|
71
|
-
verify = await encryption.HmacSha256.verify(data, extracted.signature, secretKey);
|
72
|
-
break;
|
73
|
-
case 'HS512':
|
74
|
-
verify = await encryption.HmacSha512.verify(data, extracted.signature, secretKey);
|
75
|
-
break;
|
76
|
-
default:
|
77
|
-
throw new JwtError(`Unsupported algorithm`);
|
78
|
-
}
|
79
|
-
if (!verify) {
|
80
|
-
throw new JwtError(`Signature not verified`);
|
81
|
-
}
|
82
|
-
return verify;
|
83
|
-
}
|
84
|
-
}
|
85
|
-
|
86
|
-
exports.JWT = JWT;
|
87
|
-
exports.JwtError = JwtError;
|
1
|
+
export * from './JWT';
|
2
|
+
export * from './JwtError';
|
3
|
+
export * from './JwtExtract';
|
4
|
+
export * from './JwtExtractOpts';
|
5
|
+
export * from './JwtHeader';
|
6
|
+
export * from './JwtSignOpts';
|
7
|
+
export * from './example';
|
package/package.json
CHANGED
@@ -1,41 +1,28 @@
|
|
1
|
-
{
|
2
|
-
"name": "@payello-module/jwt",
|
3
|
-
"
|
4
|
-
"author": "Payello (https://payello.com/)",
|
5
|
-
"
|
6
|
-
"
|
7
|
-
"
|
8
|
-
"
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
"
|
27
|
-
|
28
|
-
|
29
|
-
"tslib": "^2.6.2",
|
30
|
-
"typescript": "^5.2.2"
|
31
|
-
},
|
32
|
-
"scripts": {
|
33
|
-
"build": "cti create ./src -b -w & rollup -c",
|
34
|
-
"patch": "npm update & npm version patch -f & npm run build & npm publish -access=public",
|
35
|
-
"minor": "npm update & npm version minor -f & npm run build & npm publish -access=public",
|
36
|
-
"major": "npm update & npm version major -f & npm run build & npm publish -access=public"
|
37
|
-
},
|
38
|
-
"dependencies": {
|
39
|
-
"@payello-module/encryption": "^0.1.1"
|
40
|
-
}
|
41
|
-
}
|
1
|
+
{
|
2
|
+
"name": "@payello-module/jwt",
|
3
|
+
"version": "0.1.2",
|
4
|
+
"author": "Payello <devsupport@payello.com> (https://payello.com/)",
|
5
|
+
"displayName": "@payello-module/jwt",
|
6
|
+
"description": "JSON Web Token Module",
|
7
|
+
"main": "dist/index.js",
|
8
|
+
"types": "dist/index.d.ts",
|
9
|
+
"scripts": {
|
10
|
+
"build": "tsc --build --clean && tsc",
|
11
|
+
"watch": "tsc --watch",
|
12
|
+
"prepare": "npm run build"
|
13
|
+
},
|
14
|
+
"devDependencies": {
|
15
|
+
"typescript": "^5.3.3"
|
16
|
+
},
|
17
|
+
"files": [
|
18
|
+
"dist/*"
|
19
|
+
],
|
20
|
+
"license": "UNLICENSED",
|
21
|
+
"repository": {
|
22
|
+
"type": "git",
|
23
|
+
"url": "https://git.fuse.hk/payello/dev/payello-module/jwt"
|
24
|
+
},
|
25
|
+
"dependencies": {
|
26
|
+
"@payello-module/encryption": "^0.1.3"
|
27
|
+
}
|
28
|
+
}
|
package/readme.md
CHANGED
@@ -1,28 +1,94 @@
|
|
1
|
-
# JWT Module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
1
|
+
# JWT Module
|
2
|
+
|
3
|
+
This is a TypeScript library for working with JSON Web Tokens (JWT). It provides easy-to-use asynchronous methods to sign, extract, and verify JWTs using HMAC SHA256 and HMAC SHA512 hashing algorithms.
|
4
|
+
|
5
|
+
This module relies on the `@payello-module/encryption` package for encryption operations.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- **Sign JWTs:** Create signed JWTs with custom payloads and options.
|
10
|
+
- **Extract JWTs:** Extract the payload, header, and signature from a JWT.
|
11
|
+
- **Verify JWTs:** Verify the authenticity of a JWT against a secret key.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
You can install the module using npm or yarn:
|
16
|
+
|
17
|
+
```shell
|
18
|
+
npm install @payello-module/jwt
|
19
|
+
# or
|
20
|
+
yarn add @payello-module/jwt
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### Signing a JWT
|
26
|
+
|
27
|
+
```typescript
|
28
|
+
import { JWT } from '@payello-module/jwt';
|
29
|
+
|
30
|
+
const payload = { /* Your JWT payload here */ };
|
31
|
+
const options = {
|
32
|
+
privKey: 'your_private_key',
|
33
|
+
pubKey: 'your_public_key',
|
34
|
+
algorithm: 'HS512' // or 'HS256'
|
35
|
+
};
|
36
|
+
|
37
|
+
JWT.sign(payload, options)
|
38
|
+
.then(token => console.log(token))
|
39
|
+
.catch(error => console.error(error));
|
40
|
+
```
|
41
|
+
|
42
|
+
### Extracting a JWT
|
43
|
+
|
44
|
+
```typescript
|
45
|
+
import { JWT } from '@payello-module/jwt';
|
46
|
+
|
47
|
+
const token = 'your.jwt.token';
|
48
|
+
|
49
|
+
JWT.extract(token)
|
50
|
+
.then(({ header, payload, signature }) => {
|
51
|
+
console.log(header, payload, signature);
|
52
|
+
})
|
53
|
+
.catch(error => console.error(error));
|
54
|
+
```
|
55
|
+
|
56
|
+
### Verifying a JWT
|
57
|
+
|
58
|
+
```typescript
|
59
|
+
import { JWT } from '@payello-module/jwt';
|
60
|
+
|
61
|
+
const token = 'your.jwt.token';
|
62
|
+
const getSecretKey = async (issuer) => {
|
63
|
+
// Logic to retrieve the secret key for a given issuer
|
64
|
+
return 'secret_key';
|
65
|
+
};
|
66
|
+
|
67
|
+
JWT.verify(token, { getSecretKey })
|
68
|
+
.then(isVerified => console.log(isVerified))
|
69
|
+
.catch(error => console.error(error));
|
70
|
+
```
|
71
|
+
|
72
|
+
## API Reference
|
73
|
+
|
74
|
+
#### `JWT.sign(payload: any, options: JwtSignOpts): Promise<string>`
|
75
|
+
|
76
|
+
Signs the provided payload and returns a JWT string.
|
77
|
+
|
78
|
+
#### `JWT.extract(input: string, opts: JwtExtractOpts): Promise<JwtExtract>`
|
79
|
+
|
80
|
+
Extracts and returns the header, payload, and signature from a JWT string.
|
81
|
+
|
82
|
+
#### `JWT.verify(input: string, opts: { getSecretKey(issuer: string): Promise<string> }): Promise<boolean>`
|
83
|
+
|
84
|
+
Verifies a JWT string against a secret key retrieved by the `getSecretKey` function.
|
85
|
+
|
86
|
+
## Contributing
|
87
|
+
|
88
|
+
We welcome contributions to this module! Please consider the following guidelines when contributing:
|
89
|
+
|
90
|
+
1. Fork the repository and create your branch from `main`.
|
91
|
+
2. If you've added code that should be tested, add tests.
|
92
|
+
3. Ensure your code passes existing tests.
|
93
|
+
4. Ensure your code follows the existing code style.
|
94
|
+
5. Issue that pull request!
|
package/dist/index.mjs
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
import { HmacSha512, HmacSha256 } from '@payello-module/encryption';
|
2
|
-
|
3
|
-
class JwtError extends Error {
|
4
|
-
type = "@payello/module-jwt#JwtError";
|
5
|
-
constructor(message, options) {
|
6
|
-
super(message, options);
|
7
|
-
}
|
8
|
-
}
|
9
|
-
|
10
|
-
class JWT {
|
11
|
-
static async sign(payload, options = { privKey: '', pubKey: '', algorithm: 'HS512' }) {
|
12
|
-
const _header = {
|
13
|
-
typ: 'JWT',
|
14
|
-
alg: options.algorithm
|
15
|
-
};
|
16
|
-
const _payload = {
|
17
|
-
jti: `jti_${Date.now().valueOf()}`,
|
18
|
-
iat: Math.floor(Date.now().valueOf() / 1000),
|
19
|
-
iss: options.pubKey,
|
20
|
-
...payload
|
21
|
-
};
|
22
|
-
const _body = btoa(JSON.stringify(_header)) + "." + btoa(JSON.stringify(_payload));
|
23
|
-
let signature = "";
|
24
|
-
switch (options.algorithm) {
|
25
|
-
case 'HS256':
|
26
|
-
signature = await HmacSha256.encrypt(_body, options.privKey);
|
27
|
-
break;
|
28
|
-
case 'HS512':
|
29
|
-
signature = await HmacSha512.encrypt(_body, options.privKey);
|
30
|
-
break;
|
31
|
-
}
|
32
|
-
return _body + "." + signature;
|
33
|
-
}
|
34
|
-
static async extract(input, opts = {}) {
|
35
|
-
const bits = input.split(".");
|
36
|
-
if (bits.length !== 3) {
|
37
|
-
throw new JwtError(`Invalid number of parts in JWT string. Expected 3 but got ${bits.length}`);
|
38
|
-
}
|
39
|
-
const header = JSON.parse(bits[0]);
|
40
|
-
if (!header || !header.typ || header.typ !== "JWT") {
|
41
|
-
throw new JwtError("Header invalid or type is not JWT");
|
42
|
-
}
|
43
|
-
const payload = JSON.parse(bits[1]);
|
44
|
-
if (!payload || !payload.jti) {
|
45
|
-
throw new JwtError("Payload invalid or missing jti value");
|
46
|
-
}
|
47
|
-
const requiredProps = opts.requiredProps || ["jti", "iss", "iat"];
|
48
|
-
for (const prop in requiredProps) {
|
49
|
-
if (!payload[prop]) {
|
50
|
-
throw new JwtError(`Payload missing ${prop} value`);
|
51
|
-
}
|
52
|
-
}
|
53
|
-
return {
|
54
|
-
header: header,
|
55
|
-
payload: payload,
|
56
|
-
signature: bits[2]
|
57
|
-
};
|
58
|
-
}
|
59
|
-
static async verify(input, opts) {
|
60
|
-
const extracted = await this.extract(input);
|
61
|
-
const secretKey = await opts.getSecretKey(extracted.payload.jti);
|
62
|
-
if (!secretKey) {
|
63
|
-
throw new JwtError(`Public key not found`);
|
64
|
-
}
|
65
|
-
let verify = false;
|
66
|
-
const data = `${btoa(JSON.stringify(extracted.header))}.${btoa(JSON.stringify(extracted.payload))}`;
|
67
|
-
switch (extracted.header.alg) {
|
68
|
-
case 'HS256':
|
69
|
-
verify = await HmacSha256.verify(data, extracted.signature, secretKey);
|
70
|
-
break;
|
71
|
-
case 'HS512':
|
72
|
-
verify = await HmacSha512.verify(data, extracted.signature, secretKey);
|
73
|
-
break;
|
74
|
-
default:
|
75
|
-
throw new JwtError(`Unsupported algorithm`);
|
76
|
-
}
|
77
|
-
if (!verify) {
|
78
|
-
throw new JwtError(`Signature not verified`);
|
79
|
-
}
|
80
|
-
return verify;
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
export { JWT, JwtError };
|
85
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/JwtError.ts","../src/JWT.ts"],"sourcesContent":["\r\n\r\nexport class JwtError extends Error {\r\n type: \"@payello/module-jwt#JwtError\" = \"@payello/module-jwt#JwtError\";\r\n\r\n constructor(message: string, options?: ErrorOptions) {\r\n super(message, options)\r\n }\r\n}\r\n","import { HmacSha256, HmacSha512 } from \"@payello-module/encryption\"\r\nimport { JwtHeader } from \"./JwtHeader\"\r\nimport { JwtSignOpts } from \"./JwtSignOpts\"\r\nimport { JwtError } from \"./JwtError\"\r\nimport { JwtExtract } from \"./JwtExtract\"\r\nimport { JwtExtractOpts } from \"./JwtExtractOpts\"\r\n\r\nexport class JWT {\r\n public static async sign(payload: any, options: JwtSignOpts = { privKey: '', pubKey: '', algorithm: 'HS512' }): Promise<string> {\r\n const _header: JwtHeader = {\r\n typ: 'JWT',\r\n alg: options.algorithm\r\n }\r\n\r\n const _payload = {\r\n jti: `jti_${Date.now().valueOf()}`,\r\n iat: Math.floor(Date.now().valueOf() / 1000),\r\n iss: options.pubKey,\r\n ...payload\r\n }\r\n\r\n const _body = btoa(JSON.stringify(_header)) + \".\" + btoa(JSON.stringify(_payload))\r\n\r\n let signature = \"\"\r\n switch (options.algorithm) {\r\n case 'HS256':\r\n signature = await HmacSha256.encrypt(_body, options.privKey)\r\n break\r\n\r\n case 'HS512':\r\n signature = await HmacSha512.encrypt(_body, options.privKey)\r\n break\r\n }\r\n\r\n return _body + \".\" + signature\r\n }\r\n\r\n public static async extract(input: string, opts: JwtExtractOpts = {}): Promise<JwtExtract> {\r\n const bits: string[] = input.split(\".\")\r\n if(bits.length !== 3) {\r\n throw new JwtError(`Invalid number of parts in JWT string. Expected 3 but got ${bits.length}`)\r\n }\r\n\r\n const header = JSON.parse(bits[0])\r\n\r\n if(!header || !header.typ || header.typ !== \"JWT\") {\r\n throw new JwtError(\"Header invalid or type is not JWT\")\r\n }\r\n\r\n const payload = JSON.parse(bits[1])\r\n if(!payload || !payload.jti) {\r\n throw new JwtError(\"Payload invalid or missing jti value\")\r\n }\r\n\r\n const requiredProps = opts.requiredProps || [\"jti\", \"iss\", \"iat\"];\r\n for(const prop in requiredProps) {\r\n if(!payload[prop]) {\r\n throw new JwtError(`Payload missing ${prop} value`)\r\n }\r\n }\r\n\r\n return {\r\n header: header,\r\n payload: payload,\r\n signature: bits[2]\r\n }\r\n }\r\n\r\n static async verify(input: string, opts: { getSecretKey(issuer: string): Promise<string> }) {\r\n const extracted = await this.extract(input);\r\n const secretKey = await opts.getSecretKey(extracted.payload.jti);\r\n\r\n if(!secretKey) {\r\n throw new JwtError(`Public key not found`)\r\n }\r\n\r\n let verify = false\r\n const data = `${btoa(JSON.stringify(extracted.header))}.${btoa(JSON.stringify(extracted.payload))}`\r\n\r\n switch(extracted.header.alg) {\r\n case 'HS256':\r\n verify = await HmacSha256.verify(data, extracted.signature, secretKey)\r\n break;\r\n\r\n case 'HS512':\r\n verify = await HmacSha512.verify(data, extracted.signature, secretKey)\r\n break;\r\n\r\n default:\r\n throw new JwtError(`Unsupported algorithm`)\r\n }\r\n\r\n if(!verify) {\r\n throw new JwtError(`Signature not verified`)\r\n }\r\n\r\n return verify\r\n }\r\n}\r\n\r\n"],"names":[],"mappings":"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"}
|
package/dist/types/JWT.d.ts
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
import { JwtSignOpts } from "./JwtSignOpts";
|
2
|
-
import { JwtExtract } from "./JwtExtract";
|
3
|
-
import { JwtExtractOpts } from "./JwtExtractOpts";
|
4
|
-
export declare class JWT {
|
5
|
-
static sign(payload: any, options?: JwtSignOpts): Promise<string>;
|
6
|
-
static extract(input: string, opts?: JwtExtractOpts): Promise<JwtExtract>;
|
7
|
-
static verify(input: string, opts: {
|
8
|
-
getSecretKey(issuer: string): Promise<string>;
|
9
|
-
}): Promise<true>;
|
10
|
-
}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|