@payello-module/jwt 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|