-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
155 lines (130 loc) · 6.12 KB
/
index.ts
File metadata and controls
155 lines (130 loc) · 6.12 KB
1
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import jwt from 'jsonwebtoken';
import { Cipher } from './utils';
import type {
DecodeOptions,
EncryptedData,
EncryptionOptions,
SignOptions,
Secret,
Jwt,
JwtPayload,
VerifyOptions,
VerifyCallback,
VerifyErrors,
} from './types';
export * from './types';
/**
* Encrypt jsonwebtoken (JWT)
*/
export default class JwtEncrypt {
/**
*
* Synchronously sign the given payload into an encrypted JSON Web Token string payload
*
* @param {string | object | Buffer} payload - The payload to sign, could be a literal, buffer or string
* @param {Secret} jwtSecretOrPrivateKey - Either the secret for HMAC algorithms, or the PEM encoded private key for RSA and ECDSA.
* @param {EncryptionOptions} encryptionOptions - Options for the encyption
* @property {string} encryptionOptions.key - a 16-bit, 24-bit, or 32-bit raw string used by the algorithms. The 16-bit string is used on algorithms that include 128. The 24-bit string is used on algorithms that include 192. The 32-bit string is used on algorithms that include 256
* @property {string} encryptionOptions.iv - a 16-bit raw string initialization vector (iv)
* @link https://en.wikipedia.org/wiki/Initialization_vector
* @property {EncryptionAlgorithm} encryptionOptions.algorithm - The cypher algorithm to be used to encrypt the payload
* @param {SignOptions | undefined} jwtOptions - Options for the signature
*
* @returns {string} - The JSON Web Token string
*
*/
static sign(
payload: string | object | Buffer,
jwtSecretOrPrivateKey: Secret,
encryptionOptions: EncryptionOptions,
jwtOptions?: SignOptions | undefined,
): string {
return jwt.sign(Cipher.encrypt(payload, encryptionOptions), jwtSecretOrPrivateKey, jwtOptions);
}
/**
* Returns the decoded payload from an token with encrypted data without verifying if the signature is valid.
*
* @param {string} token - JWT string to decode with encrypted information
* @param {EncryptionOptions} encryptionOptions - Options for the encyption
* @property {string} encryptionOptions.key - a 16-bit, 24-bit, or 32-bit raw string used by the algorithms. The 16-bit string is used on algorithms that include 128. The 24-bit string is used on algorithms that include 192. The 32-bit string is used on algorithms that include 256
* @property {string} encryptionOptions.iv - a 16-bit raw string initialization vector (iv)
* @link https://en.wikipedia.org/wiki/Initialization_vector
* @property {EncryptionAlgorithm} encryptionOptions.algorithm - The cypher algorithm to be used to encrypt the payload
* @param {DecodeOptions | undefined} jwtDecodeOptions - jwt options for decoding a jwt token.
*
* @returns {string | JwtPayload | null} - The decoded Token
*/
static decode(
token: string,
encryptionOptions: EncryptionOptions,
jwtDecodeOptions?: DecodeOptions,
): string | JwtPayload | null {
const decodedPayload = jwt.decode(token, jwtDecodeOptions);
if (!decodedPayload || typeof decodedPayload === 'string') return null;
if (jwtDecodeOptions?.complete) {
const { payload, ...restPayload } = decodedPayload;
const cipherPayload = Cipher.decrypt(payload.data, encryptionOptions);
return { payload: cipherPayload, ...restPayload };
}
const { data, ...restPayload } = decodedPayload;
const cipherPayload = Cipher.decrypt(data, encryptionOptions);
if (typeof cipherPayload === 'string') return cipherPayload;
return { ...cipherPayload, ...restPayload };
}
/**
*
* Synchronously verify given token with encrypted data using a secret or a public key to get a decoded token
*
* @param {string} token - JWT string to verify
* @param {Secret} jwtSecretOrPrivateKey - Either the secret for HMAC algorithms, or the PEM encoded public key for RSA and ECDSA.
* @param {EncryptionOptions} encryptionOptions - Options for the encyption
* @property {string} encryptionOptions.key - a 16-bit, 24-bit, or 32-bit raw string used by the algorithms. The 16-bit string is used on algorithms that include 128. The 24-bit string is used on algorithms that include 192. The 32-bit string is used on algorithms that include 256
* @property {string} encryptionOptions.iv - a 16-bit raw string initialization vector (iv)
* @link https://en.wikipedia.org/wiki/Initialization_vector
* @property {EncryptionAlgorithm} encryptionOptions.algorithm - The cypher algorithm to be used to encrypt the payload
* @param {VerifyOptions } jwtVerifyOptions - Options for the verification
* @param {VerifyCallback<string | JwtPayload | Jwt>} callback - A function which receives an error and verifiedPayload, can be used to perfom an action once the payload has been verified
*
* @returns {void}
*
*/
static verify(
token: string,
jwtSecretOrPrivateKey: Secret,
encryptionOptions: EncryptionOptions,
jwtVerifyOptions?: VerifyOptions,
callback?: VerifyCallback<string | JwtPayload | Jwt>,
): void {
let done: VerifyCallback<string | JwtPayload | Jwt>;
if (callback) {
done = callback;
} else {
done = function (err: VerifyErrors | null, data: string | JwtPayload | Jwt | undefined) {
if (err) throw err;
return data;
};
}
jwt.verify(
token,
jwtSecretOrPrivateKey,
jwtVerifyOptions,
(err: VerifyErrors | null, verifiedPayload?: string | JwtPayload | (Jwt & EncryptedData)) => {
if (err) {
return done(err, undefined);
}
if (!verifiedPayload || typeof verifiedPayload === 'string') {
return done(null, undefined);
}
if (jwtVerifyOptions?.complete) {
const { payload, ...restPayload } = verifiedPayload;
const cipherPayload = Cipher.decrypt(payload.data, encryptionOptions);
return done(null, { payload: cipherPayload, ...restPayload });
}
const { data, ...restPayload } = verifiedPayload;
const cipherPayload = Cipher.decrypt(data, encryptionOptions);
if (typeof cipherPayload === 'string') return done(null, cipherPayload);
return done(null, { ...cipherPayload, ...restPayload });
},
);
}
}