@payello-module/jwt 1.20240419.1629 → 1.20240419.1640

Sign up to get free protection for your applications and to get access to all the features.
package/dist/JWT.d.ts CHANGED
@@ -1,18 +1,29 @@
1
- import { JwtSignOpts } from "./JwtSignOpts";
1
+ import { JwtHeader } from "./JwtHeader";
2
2
  import { JwtExtract } from "./JwtExtract";
3
3
  import { JwtExtractOpts } from "./JwtExtractOpts";
4
+ import { JWTAlgorithm } from "./JWTAlgorithms";
5
+ import { JWTPayload } from "./JWTPayload";
6
+ import { JWTKeyPair } from "./JWTKeyPair";
4
7
  /**
5
8
  * Class representing JSON Web Tokens (JWT) functionalities, including signing, extracting components,
6
9
  * and verifying the signature of the token.
7
10
  */
8
11
  export declare class JWT {
12
+ private static algExportFormat;
13
+ /**
14
+ * Generates a new key pair for the given algorithm
15
+ * @param alg JWT algorithm to generate for
16
+ * @returns
17
+ */
18
+ static generateKeys(alg?: JWTAlgorithm): Promise<JWTKeyPair>;
9
19
  /**
10
20
  * Signs the given payload and returns a JWT string.
11
21
  * @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.
22
+ * @param alg - The algorithm for signing the JWT
23
+ * @param key - The key for signing the JWT
13
24
  * @returns A promise that resolves to the signed JWT string.
14
25
  */
15
- static sign(payload: any, options?: JwtSignOpts): Promise<string>;
26
+ static sign(payload: JWTPayload, alg: JWTAlgorithm, key: string | BufferSource): Promise<string>;
16
27
  /**
17
28
  * Extracts and returns the header, payload, and signature components from a JWT string.
18
29
  * @param input - The JWT string to be parsed.
@@ -22,11 +33,14 @@ export declare class JWT {
22
33
  static extract(input: string, opts?: JwtExtractOpts): Promise<JwtExtract>;
23
34
  /**
24
35
  * 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.
36
+ * @param token - The JWT to be verified.
37
+ * @param getVerifyKey - A function to retrieve the verification key based on the header & payload (BufferSource or base64-encoded string)
38
+ * @param throwErrors - If true then will throw JwtError if something fails or the token is not valid
27
39
  * @returns A promise that resolves to a boolean indicating whether the JWT has been verified successfully or not.
40
+ * @throws `JwtError | Error`
28
41
  */
29
- static verify(input: string, opts: {
30
- getSecretKey(issuer: string): Promise<string>;
31
- }): Promise<true>;
42
+ static verifySignature(token: string, getVerifyKey: (header: JwtHeader, payload: JWTPayload) => Promise<BufferSource | string> | BufferSource | string, throwErrors?: boolean): Promise<{
43
+ verified: boolean;
44
+ extracted: JwtExtract | null;
45
+ }>;
32
46
  }
package/dist/JWT.js CHANGED
@@ -1,41 +1,60 @@
1
- import { HmacSha256, HmacSha512 } from "@payello-module/encryption";
2
1
  import { JwtError } from "./JwtError";
2
+ import { base64_decode_buffer, base64_decode_urlsafe, base64_encode_buffer, base64_encode_urlsafe } from "./base64_encode_buffer";
3
+ import { JWTAlgorithms } from "./JWTAlgorithms";
3
4
  /**
4
5
  * Class representing JSON Web Tokens (JWT) functionalities, including signing, extracting components,
5
6
  * and verifying the signature of the token.
6
7
  */
7
8
  export class JWT {
9
+ static algExportFormat(alg, use) {
10
+ const algName = JWTAlgorithms[alg].name;
11
+ if (["RSASSA-PKCS1-v1_5", "ECDSA", "RSA-PSS"].indexOf(algName) > -1) {
12
+ return use == "sign" ? "pkcs8" : "spki";
13
+ }
14
+ return "raw";
15
+ }
16
+ /**
17
+ * Generates a new key pair for the given algorithm
18
+ * @param alg JWT algorithm to generate for
19
+ * @returns
20
+ */
21
+ static async generateKeys(alg = "HS256") {
22
+ if (alg == "HS256" || alg == "HS384" || alg == "HS512") {
23
+ const cryptoKey = await crypto.subtle.generateKey(JWTAlgorithms[alg], true, ["sign", "verify"]);
24
+ const privateKey = await crypto.subtle.exportKey("raw", cryptoKey);
25
+ const key = { raw: privateKey, base64: base64_encode_buffer(privateKey) };
26
+ return { sign: key, verify: key };
27
+ }
28
+ else if (alg == "RS256" || alg == "RS384" || alg == "RS512" || alg == "ES256" || alg == "ES384" || alg == "ES512" || alg == "PS256" || alg == "PS384" || alg == "PS512") {
29
+ const cryptoKey = await crypto.subtle.generateKey(JWTAlgorithms[alg], true, ["sign", "verify"]);
30
+ const privateKey = await crypto.subtle.exportKey(this.algExportFormat(alg, "sign"), cryptoKey.privateKey);
31
+ const publicKey = await crypto.subtle.exportKey(this.algExportFormat(alg, "verify"), cryptoKey.publicKey);
32
+ return { sign: { raw: privateKey, base64: base64_encode_buffer(privateKey) }, verify: { raw: publicKey, base64: base64_encode_buffer(publicKey) } };
33
+ }
34
+ throw new JwtError("Unknown algorithm: " + alg);
35
+ }
8
36
  /**
9
37
  * Signs the given payload and returns a JWT string.
10
38
  * @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.
39
+ * @param alg - The algorithm for signing the JWT
40
+ * @param key - The key for signing the JWT
12
41
  * @returns A promise that resolves to the signed JWT string.
13
42
  */
14
- static async sign(payload, options = { privKey: '', pubKey: '', algorithm: 'HS512' }) {
43
+ static async sign(payload, alg, key) {
44
+ if (typeof JWTAlgorithms[alg] == "undefined")
45
+ throw new JwtError("Unknown algorithm");
15
46
  const _header = {
16
47
  typ: 'JWT',
17
- alg: options.algorithm
18
- };
19
- // Create payload with unique identifier, issued-at time, and incorporate the public key if provided.
20
- const _payload = {
21
- jti: `jti_${Date.now().valueOf()}`,
22
- iat: Math.floor(Date.now().valueOf() / 1000),
23
- iss: options.pubKey,
24
- ...payload
48
+ alg: alg
25
49
  };
26
- const _body = btoa(JSON.stringify(_header)) + "." + btoa(JSON.stringify(_payload));
27
- let signature = "";
28
- // Create signature based on selected algorithm.
29
- switch (options.algorithm) {
30
- case 'HS256':
31
- signature = await HmacSha256.encrypt(_body, options.privKey);
32
- break;
33
- case 'HS512':
34
- signature = await HmacSha512.encrypt(_body, options.privKey);
35
- break;
36
- }
50
+ const body = base64_encode_urlsafe(JSON.stringify(_header)) +
51
+ "." +
52
+ base64_encode_urlsafe(JSON.stringify(payload));
53
+ const signingKey = typeof key == "string" ? new Uint8Array(base64_decode_buffer(key)) : key;
54
+ const importedKey = await crypto.subtle.importKey(this.algExportFormat(alg, "sign"), signingKey, JWTAlgorithms[alg], false, ['sign']);
55
+ const signed = await crypto.subtle.sign(JWTAlgorithms[alg], importedKey, new TextEncoder().encode(body));
37
56
  // Returns the final JWT token as a concatenation of header, payload, and signature
38
- return _body + "." + signature;
57
+ return body + "." + base64_encode_buffer(signed);
39
58
  }
40
59
  /**
41
60
  * Extracts and returns the header, payload, and signature components from a JWT string.
@@ -49,59 +68,104 @@ export class JWT {
49
68
  if (bits.length !== 3) {
50
69
  throw new JwtError(`Invalid number of parts in JWT string. Expected 3 but got ${bits.length}`);
51
70
  }
52
- const header = JSON.parse(bits[0]);
71
+ const header = JSON.parse(base64_decode_urlsafe(bits[0]));
53
72
  if (!header || !header.typ || header.typ !== "JWT") {
54
73
  throw new JwtError("Header invalid or type is not JWT");
55
74
  }
56
- const payload = JSON.parse(bits[1]);
57
- if (!payload || !payload.jti) {
58
- throw new JwtError("Payload invalid or missing jti value");
75
+ const payload = JSON.parse(base64_decode_urlsafe(bits[1]));
76
+ if (!payload || typeof payload !== "object") {
77
+ throw new JwtError("Payload invalid");
59
78
  }
60
79
  // Validates the present of required properties in the payload.
61
- const requiredProps = opts.requiredProps || ["jti", "iss", "iat"];
62
- for (const prop in requiredProps) {
80
+ const requiredProps = opts.requiredProps || [];
81
+ for (const prop of requiredProps) {
63
82
  if (!payload[prop]) {
64
83
  throw new JwtError(`Payload missing ${prop} value`);
65
84
  }
66
85
  }
86
+ const signature = base64_decode_buffer(bits[2]);
67
87
  // Returns an object containing the extracted components of the JWT.
68
88
  return {
69
89
  header: header,
90
+ headerRaw: bits[0],
70
91
  payload: payload,
71
- signature: bits[2]
92
+ payloadRaw: bits[1],
93
+ signature: signature,
94
+ signatureRaw: bits[2]
72
95
  };
73
96
  }
74
97
  /**
75
98
  * 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.
99
+ * @param token - The JWT to be verified.
100
+ * @param getVerifyKey - A function to retrieve the verification key based on the header & payload (BufferSource or base64-encoded string)
101
+ * @param throwErrors - If true then will throw JwtError if something fails or the token is not valid
78
102
  * @returns A promise that resolves to a boolean indicating whether the JWT has been verified successfully or not.
103
+ * @throws `JwtError | Error`
79
104
  */
80
- static async verify(input, opts) {
81
- const extracted = await this.extract(input);
105
+ static async verifySignature(token, getVerifyKey, throwErrors) {
106
+ const extracted = await this.extract(token).catch(e => {
107
+ if (throwErrors)
108
+ throw e;
109
+ });
110
+ if (!extracted) {
111
+ return { verified: false, extracted: null };
112
+ }
82
113
  // Fetches the secret key based on the issuer in the payload.
83
- const secretKey = await opts.getSecretKey(extracted.payload.jti);
84
- if (!secretKey) {
85
- throw new JwtError(`Public key not found`);
114
+ let verifyKey = await getVerifyKey(extracted.header, extracted.payload);
115
+ if (!verifyKey || (typeof verifyKey !== "string" && typeof verifyKey !== "object")) {
116
+ if (throwErrors)
117
+ throw new JwtError(`Verify key not found`);
118
+ return { verified: false, extracted: null };
119
+ }
120
+ if (typeof verifyKey == "string") {
121
+ try {
122
+ verifyKey = base64_decode_buffer(verifyKey);
123
+ }
124
+ catch (e) {
125
+ if (throwErrors)
126
+ throw e;
127
+ return { verified: false, extracted: null };
128
+ }
86
129
  }
87
- let verify = false;
130
+ let verified = false;
88
131
  // Preparation of the data to verify the signature.
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.
91
- switch (extracted.header.alg) {
92
- case 'HS256':
93
- verify = await HmacSha256.verify(data, extracted.signature, secretKey);
94
- break;
95
- case 'HS512':
96
- verify = await HmacSha512.verify(data, extracted.signature, secretKey);
97
- break;
98
- default:
99
- throw new JwtError(`Unsupported algorithm`);
132
+ const body = `${extracted.headerRaw}.${extracted.payloadRaw}`;
133
+ try {
134
+ // Verification of the signature based on the algorithm specified in the header.
135
+ switch (extracted.header.alg) {
136
+ case 'HS256':
137
+ case 'HS384':
138
+ case 'HS512':
139
+ const importedSignKey = await crypto.subtle.importKey(this.algExportFormat(extracted.header.alg, "verify"), verifyKey, JWTAlgorithms[extracted.header.alg], false, ['sign']);
140
+ const signed = await crypto.subtle.sign(JWTAlgorithms[extracted.header.alg], importedSignKey, new TextEncoder().encode(body));
141
+ verified = extracted.signatureRaw == base64_encode_buffer(signed);
142
+ break;
143
+ case 'ES256':
144
+ case 'ES384':
145
+ case 'ES512':
146
+ case 'PS256':
147
+ case 'PS384':
148
+ case 'PS512':
149
+ case 'RS256':
150
+ case 'RS384':
151
+ case 'RS512':
152
+ const importedVerifyKey = await crypto.subtle.importKey(this.algExportFormat(extracted.header.alg, "verify"), verifyKey, JWTAlgorithms[extracted.header.alg], false, ['verify']);
153
+ verified = await crypto.subtle.verify(JWTAlgorithms[extracted.header.alg], importedVerifyKey, extracted.signature, new TextEncoder().encode(body));
154
+ break;
155
+ default:
156
+ if (throwErrors)
157
+ throw new JwtError(`Unsupported algorithm`);
158
+ break;
159
+ }
100
160
  }
101
- if (!verify) {
102
- throw new JwtError(`Signature not verified`);
161
+ catch (e) {
162
+ if (throwErrors)
163
+ throw e;
103
164
  }
104
- // Returns the result of the verification process.
105
- return verify;
165
+ if (verified === true)
166
+ return { verified: true, extracted: extracted };
167
+ if (throwErrors)
168
+ throw new JwtError(`Signature not verified`);
169
+ return { verified: false, extracted: null };
106
170
  }
107
171
  }
@@ -1,6 +1,10 @@
1
+ import { JWTPayload } from "./JWTPayload";
1
2
  import { JwtHeader } from "./JwtHeader";
2
3
  export interface JwtExtract {
3
4
  header: JwtHeader;
4
- payload: any;
5
- signature: string;
5
+ headerRaw: string;
6
+ payload: JWTPayload;
7
+ payloadRaw: string;
8
+ signature: Uint8Array;
9
+ signatureRaw: string;
6
10
  }
@@ -1,4 +1,5 @@
1
+ import { JWTAlgorithm } from "./JWTAlgorithms";
1
2
  export interface JwtHeader {
2
3
  typ: 'JWT';
3
- alg: 'HS256' | 'HS512';
4
+ alg: JWTAlgorithm;
4
5
  }
@@ -1,5 +1,5 @@
1
+ import { JWTAlgorithm } from "./JWTAlgorithms";
1
2
  export interface JwtSignOpts {
2
- privKey: string;
3
- pubKey: string;
4
- algorithm: "HS256" | "HS512";
3
+ privateKey: string | ArrayBuffer | Uint8Array;
4
+ algorithm: JWTAlgorithm;
5
5
  }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
- export * from './JWT';
2
- export * from './JwtError';
3
- export * from './JwtExtract';
4
- export * from './JwtExtractOpts';
5
- export * from './JwtHeader';
6
1
  export * from './JwtSignOpts';
7
- export * from './example';
2
+ export * from './JWTPayload';
3
+ export * from './JWTKeyPair';
4
+ export * from './JwtHeader';
5
+ export * from './JwtExtractOpts';
6
+ export * from './JwtExtract';
7
+ export * from './JwtError';
8
+ export * from './JWTAlgorithms';
9
+ export * from './JWT';
10
+ export * from './base64_encode_buffer';
package/dist/index.js CHANGED
@@ -1,7 +1,10 @@
1
- export * from './JWT';
2
- export * from './JwtError';
3
- export * from './JwtExtract';
4
- export * from './JwtExtractOpts';
5
- export * from './JwtHeader';
6
1
  export * from './JwtSignOpts';
7
- export * from './example';
2
+ export * from './JWTPayload';
3
+ export * from './JWTKeyPair';
4
+ export * from './JwtHeader';
5
+ export * from './JwtExtractOpts';
6
+ export * from './JwtExtract';
7
+ export * from './JwtError';
8
+ export * from './JWTAlgorithms';
9
+ export * from './JWT';
10
+ export * from './base64_encode_buffer';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payello-module/jwt",
3
- "version": "1.20240419.1629",
3
+ "version": "1.20240419.1640",
4
4
  "author": "Payello <devsupport@payello.com> (https://payello.com/)",
5
5
  "displayName": "@payello-module/jwt",
6
6
  "description": "JSON Web Token Module",
package/dist/example.d.ts DELETED
@@ -1 +0,0 @@
1
- export {};
package/dist/example.js DELETED
@@ -1,13 +0,0 @@
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/src/JWT.d.ts DELETED
@@ -1,46 +0,0 @@
1
- import { JwtHeader } from "./JwtHeader";
2
- import { JwtExtract } from "./JwtExtract";
3
- import { JwtExtractOpts } from "./JwtExtractOpts";
4
- import { JWTAlgorithm } from "./JWTAlgorithms";
5
- import { JWTPayload } from "./JWTPayload";
6
- import { JWTKeyPair } from "./JWTKeyPair";
7
- /**
8
- * Class representing JSON Web Tokens (JWT) functionalities, including signing, extracting components,
9
- * and verifying the signature of the token.
10
- */
11
- export declare class JWT {
12
- private static algExportFormat;
13
- /**
14
- * Generates a new key pair for the given algorithm
15
- * @param alg JWT algorithm to generate for
16
- * @returns
17
- */
18
- static generateKeys(alg?: JWTAlgorithm): Promise<JWTKeyPair>;
19
- /**
20
- * Signs the given payload and returns a JWT string.
21
- * @param payload - The payload of the JWT which is the content that you want to protect.
22
- * @param alg - The algorithm for signing the JWT
23
- * @param key - The key for signing the JWT
24
- * @returns A promise that resolves to the signed JWT string.
25
- */
26
- static sign(payload: JWTPayload, alg: JWTAlgorithm, key: string | BufferSource): Promise<string>;
27
- /**
28
- * Extracts and returns the header, payload, and signature components from a JWT string.
29
- * @param input - The JWT string to be parsed.
30
- * @param opts - Optional parameters, including the requirements for the presence of required properties in the payload.
31
- * @returns A promise that resolves to an object containing the separated components of the JWT (header, payload, signature).
32
- */
33
- static extract(input: string, opts?: JwtExtractOpts): Promise<JwtExtract>;
34
- /**
35
- * Verifies the given JWT string using the secret key fetched by the given issuer.
36
- * @param token - The JWT to be verified.
37
- * @param getVerifyKey - A function to retrieve the verification key based on the header & payload (BufferSource or base64-encoded string)
38
- * @param throwErrors - If true then will throw JwtError if something fails or the token is not valid
39
- * @returns A promise that resolves to a boolean indicating whether the JWT has been verified successfully or not.
40
- * @throws `JwtError | Error`
41
- */
42
- static verifySignature(token: string, getVerifyKey: (header: JwtHeader, payload: JWTPayload) => Promise<BufferSource | string> | BufferSource | string, throwErrors?: boolean): Promise<{
43
- verified: boolean;
44
- extracted: JwtExtract | null;
45
- }>;
46
- }
package/dist/src/JWT.js DELETED
@@ -1,171 +0,0 @@
1
- import { JwtError } from "./JwtError";
2
- import { base64_decode_buffer, base64_decode_urlsafe, base64_encode_buffer, base64_encode_urlsafe } from "./base64_encode_buffer";
3
- import { JWTAlgorithms } from "./JWTAlgorithms";
4
- /**
5
- * Class representing JSON Web Tokens (JWT) functionalities, including signing, extracting components,
6
- * and verifying the signature of the token.
7
- */
8
- export class JWT {
9
- static algExportFormat(alg, use) {
10
- const algName = JWTAlgorithms[alg].name;
11
- if (["RSASSA-PKCS1-v1_5", "ECDSA", "RSA-PSS"].indexOf(algName) > -1) {
12
- return use == "sign" ? "pkcs8" : "spki";
13
- }
14
- return "raw";
15
- }
16
- /**
17
- * Generates a new key pair for the given algorithm
18
- * @param alg JWT algorithm to generate for
19
- * @returns
20
- */
21
- static async generateKeys(alg = "HS256") {
22
- if (alg == "HS256" || alg == "HS384" || alg == "HS512") {
23
- const cryptoKey = await crypto.subtle.generateKey(JWTAlgorithms[alg], true, ["sign", "verify"]);
24
- const privateKey = await crypto.subtle.exportKey("raw", cryptoKey);
25
- const key = { raw: privateKey, base64: base64_encode_buffer(privateKey) };
26
- return { sign: key, verify: key };
27
- }
28
- else if (alg == "RS256" || alg == "RS384" || alg == "RS512" || alg == "ES256" || alg == "ES384" || alg == "ES512" || alg == "PS256" || alg == "PS384" || alg == "PS512") {
29
- const cryptoKey = await crypto.subtle.generateKey(JWTAlgorithms[alg], true, ["sign", "verify"]);
30
- const privateKey = await crypto.subtle.exportKey(this.algExportFormat(alg, "sign"), cryptoKey.privateKey);
31
- const publicKey = await crypto.subtle.exportKey(this.algExportFormat(alg, "verify"), cryptoKey.publicKey);
32
- return { sign: { raw: privateKey, base64: base64_encode_buffer(privateKey) }, verify: { raw: publicKey, base64: base64_encode_buffer(publicKey) } };
33
- }
34
- throw new JwtError("Unknown algorithm: " + alg);
35
- }
36
- /**
37
- * Signs the given payload and returns a JWT string.
38
- * @param payload - The payload of the JWT which is the content that you want to protect.
39
- * @param alg - The algorithm for signing the JWT
40
- * @param key - The key for signing the JWT
41
- * @returns A promise that resolves to the signed JWT string.
42
- */
43
- static async sign(payload, alg, key) {
44
- if (typeof JWTAlgorithms[alg] == "undefined")
45
- throw new JwtError("Unknown algorithm");
46
- const _header = {
47
- typ: 'JWT',
48
- alg: alg
49
- };
50
- const body = base64_encode_urlsafe(JSON.stringify(_header)) +
51
- "." +
52
- base64_encode_urlsafe(JSON.stringify(payload));
53
- const signingKey = typeof key == "string" ? new Uint8Array(base64_decode_buffer(key)) : key;
54
- const importedKey = await crypto.subtle.importKey(this.algExportFormat(alg, "sign"), signingKey, JWTAlgorithms[alg], false, ['sign']);
55
- const signed = await crypto.subtle.sign(JWTAlgorithms[alg], importedKey, new TextEncoder().encode(body));
56
- // Returns the final JWT token as a concatenation of header, payload, and signature
57
- return body + "." + base64_encode_buffer(signed);
58
- }
59
- /**
60
- * Extracts and returns the header, payload, and signature components from a JWT string.
61
- * @param input - The JWT string to be parsed.
62
- * @param opts - Optional parameters, including the requirements for the presence of required properties in the payload.
63
- * @returns A promise that resolves to an object containing the separated components of the JWT (header, payload, signature).
64
- */
65
- static async extract(input, opts = {}) {
66
- const bits = input.split(".");
67
- // Ensures that the JWT string has three parts: header, payload, and signature.
68
- if (bits.length !== 3) {
69
- throw new JwtError(`Invalid number of parts in JWT string. Expected 3 but got ${bits.length}`);
70
- }
71
- const header = JSON.parse(base64_decode_urlsafe(bits[0]));
72
- if (!header || !header.typ || header.typ !== "JWT") {
73
- throw new JwtError("Header invalid or type is not JWT");
74
- }
75
- const payload = JSON.parse(base64_decode_urlsafe(bits[1]));
76
- if (!payload || typeof payload !== "object") {
77
- throw new JwtError("Payload invalid");
78
- }
79
- // Validates the present of required properties in the payload.
80
- const requiredProps = opts.requiredProps || [];
81
- for (const prop of requiredProps) {
82
- if (!payload[prop]) {
83
- throw new JwtError(`Payload missing ${prop} value`);
84
- }
85
- }
86
- const signature = base64_decode_buffer(bits[2]);
87
- // Returns an object containing the extracted components of the JWT.
88
- return {
89
- header: header,
90
- headerRaw: bits[0],
91
- payload: payload,
92
- payloadRaw: bits[1],
93
- signature: signature,
94
- signatureRaw: bits[2]
95
- };
96
- }
97
- /**
98
- * Verifies the given JWT string using the secret key fetched by the given issuer.
99
- * @param token - The JWT to be verified.
100
- * @param getVerifyKey - A function to retrieve the verification key based on the header & payload (BufferSource or base64-encoded string)
101
- * @param throwErrors - If true then will throw JwtError if something fails or the token is not valid
102
- * @returns A promise that resolves to a boolean indicating whether the JWT has been verified successfully or not.
103
- * @throws `JwtError | Error`
104
- */
105
- static async verifySignature(token, getVerifyKey, throwErrors) {
106
- const extracted = await this.extract(token).catch(e => {
107
- if (throwErrors)
108
- throw e;
109
- });
110
- if (!extracted) {
111
- return { verified: false, extracted: null };
112
- }
113
- // Fetches the secret key based on the issuer in the payload.
114
- let verifyKey = await getVerifyKey(extracted.header, extracted.payload);
115
- if (!verifyKey || (typeof verifyKey !== "string" && typeof verifyKey !== "object")) {
116
- if (throwErrors)
117
- throw new JwtError(`Verify key not found`);
118
- return { verified: false, extracted: null };
119
- }
120
- if (typeof verifyKey == "string") {
121
- try {
122
- verifyKey = base64_decode_buffer(verifyKey);
123
- }
124
- catch (e) {
125
- if (throwErrors)
126
- throw e;
127
- return { verified: false, extracted: null };
128
- }
129
- }
130
- let verified = false;
131
- // Preparation of the data to verify the signature.
132
- const body = `${extracted.headerRaw}.${extracted.payloadRaw}`;
133
- try {
134
- // Verification of the signature based on the algorithm specified in the header.
135
- switch (extracted.header.alg) {
136
- case 'HS256':
137
- case 'HS384':
138
- case 'HS512':
139
- const importedSignKey = await crypto.subtle.importKey(this.algExportFormat(extracted.header.alg, "verify"), verifyKey, JWTAlgorithms[extracted.header.alg], false, ['sign']);
140
- const signed = await crypto.subtle.sign(JWTAlgorithms[extracted.header.alg], importedSignKey, new TextEncoder().encode(body));
141
- verified = extracted.signatureRaw == base64_encode_buffer(signed);
142
- break;
143
- case 'ES256':
144
- case 'ES384':
145
- case 'ES512':
146
- case 'PS256':
147
- case 'PS384':
148
- case 'PS512':
149
- case 'RS256':
150
- case 'RS384':
151
- case 'RS512':
152
- const importedVerifyKey = await crypto.subtle.importKey(this.algExportFormat(extracted.header.alg, "verify"), verifyKey, JWTAlgorithms[extracted.header.alg], false, ['verify']);
153
- verified = await crypto.subtle.verify(JWTAlgorithms[extracted.header.alg], importedVerifyKey, extracted.signature, new TextEncoder().encode(body));
154
- break;
155
- default:
156
- if (throwErrors)
157
- throw new JwtError(`Unsupported algorithm`);
158
- break;
159
- }
160
- }
161
- catch (e) {
162
- if (throwErrors)
163
- throw e;
164
- }
165
- if (verified === true)
166
- return { verified: true, extracted: extracted };
167
- if (throwErrors)
168
- throw new JwtError(`Signature not verified`);
169
- return { verified: false, extracted: null };
170
- }
171
- }
@@ -1,4 +0,0 @@
1
- export declare class JwtError extends Error {
2
- type: "@payello/module-jwt#JwtError";
3
- constructor(message: string, options?: ErrorOptions);
4
- }
@@ -1,6 +0,0 @@
1
- export class JwtError extends Error {
2
- type = "@payello/module-jwt#JwtError";
3
- constructor(message, options) {
4
- super(message, options);
5
- }
6
- }
@@ -1,10 +0,0 @@
1
- import { JWTPayload } from "./JWTPayload";
2
- import { JwtHeader } from "./JwtHeader";
3
- export interface JwtExtract {
4
- header: JwtHeader;
5
- headerRaw: string;
6
- payload: JWTPayload;
7
- payloadRaw: string;
8
- signature: Uint8Array;
9
- signatureRaw: string;
10
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,3 +0,0 @@
1
- export interface JwtExtractOpts {
2
- requiredProps?: string[];
3
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- import { JWTAlgorithm } from "./JWTAlgorithms";
2
- export interface JwtHeader {
3
- typ: 'JWT';
4
- alg: JWTAlgorithm;
5
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- import { JWTAlgorithm } from "./JWTAlgorithms";
2
- export interface JwtSignOpts {
3
- privateKey: string | ArrayBuffer | Uint8Array;
4
- algorithm: JWTAlgorithm;
5
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,10 +0,0 @@
1
- export * from './JwtSignOpts';
2
- export * from './JWTPayload';
3
- export * from './JWTKeyPair';
4
- export * from './JwtHeader';
5
- export * from './JwtExtractOpts';
6
- export * from './JwtExtract';
7
- export * from './JwtError';
8
- export * from './JWTAlgorithms';
9
- export * from './JWT';
10
- export * from './base64_encode_buffer';
package/dist/src/index.js DELETED
@@ -1,10 +0,0 @@
1
- export * from './JwtSignOpts';
2
- export * from './JWTPayload';
3
- export * from './JWTKeyPair';
4
- export * from './JwtHeader';
5
- export * from './JwtExtractOpts';
6
- export * from './JwtExtract';
7
- export * from './JwtError';
8
- export * from './JWTAlgorithms';
9
- export * from './JWT';
10
- export * from './base64_encode_buffer';
@@ -1 +0,0 @@
1
- export {};
package/dist/test/test.js DELETED
@@ -1,46 +0,0 @@
1
- import { JWT } from "../src/JWT";
2
- import { JWTAlgorithms } from "../src/JWTAlgorithms";
3
- /**
4
- * Ensures that verification works for all algorithms
5
- */
6
- async function Test1() {
7
- for (let key of Object.keys(JWTAlgorithms)) {
8
- console.log("ALG: ", key);
9
- const keys = await JWT.generateKeys(key);
10
- console.log("KEYS: ", keys);
11
- const signed = await JWT.sign({ iss: "Hello" }, key, keys.sign.base64);
12
- console.log("SIGNED: ", signed);
13
- const verify = await JWT.verifySignature(signed, () => { return keys.verify.base64; });
14
- console.log("VERIFIED: ", verify);
15
- if (!verify.verified) {
16
- throw new Error("Not verified!");
17
- }
18
- console.log("----");
19
- }
20
- }
21
- /**
22
- * Ensures that signature manipulation fails for all algorithms
23
- */
24
- async function Test2() {
25
- for (let key of Object.keys(JWTAlgorithms)) {
26
- console.log("ALG: ", key);
27
- const keys = await JWT.generateKeys(key);
28
- console.log("KEYS: ", keys);
29
- const signed = await JWT.sign({ iss: "Hello" }, key, keys.sign.base64);
30
- console.log("SIGNED: ", signed);
31
- const signed2 = await JWT.sign({ iss: "Hello there" }, key, keys.sign.base64);
32
- console.log("SIGNED2: ", signed);
33
- const token = signed.split('.').map(x => (val, index) => {
34
- if (index == 2)
35
- return signed2.split('.')[index];
36
- return val;
37
- }).join('.');
38
- const verify = await JWT.verifySignature(token, () => { return keys.verify.base64; });
39
- console.log("VERIFIED: ", verify);
40
- if (verify.verified) {
41
- throw new Error("Somehow verified (shouldn't be)");
42
- }
43
- console.log("----");
44
- }
45
- }
46
- Test1();
File without changes
File without changes
File without changes
File without changes
File without changes