@navios/jwt 1.0.0-alpha.2 → 1.0.0
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/CHANGELOG.md +25 -0
- package/README.md +6 -8
- package/dist/src/__tests__/jwt.service.spec.d.mts +2 -0
- package/dist/src/__tests__/jwt.service.spec.d.mts.map +1 -0
- package/dist/src/jwt-service.provider.d.mts +1 -1
- package/dist/src/jwt.service.d.mts +6 -14
- package/dist/src/jwt.service.d.mts.map +1 -1
- package/dist/src/options/jwt-service.options.d.mts +2 -7
- package/dist/src/options/jwt-service.options.d.mts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/index.cjs +29 -34
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +9 -22
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +9 -22
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +29 -34
- package/lib/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/jwt.service.spec.mts +453 -0
- package/src/jwt-service.provider.mts +1 -1
- package/src/jwt.service.mts +64 -105
- package/src/options/jwt-service.options.mts +1 -1
package/src/jwt.service.mts
CHANGED
|
@@ -78,7 +78,6 @@ export class JwtService {
|
|
|
78
78
|
* @param payload - The payload to sign. Can be a string, Buffer, or object.
|
|
79
79
|
* @param options - Signing options. When payload is a string, only `secret` and `privateKey` are allowed.
|
|
80
80
|
* @returns The signed JWT token as a string
|
|
81
|
-
* @throws {Error} If `secretOrKeyProvider` returns a Promise (use `signAsync` instead)
|
|
82
81
|
* @throws {Error} If payload is a string and invalid options are provided
|
|
83
82
|
*
|
|
84
83
|
* @example
|
|
@@ -109,45 +108,14 @@ export class JwtService {
|
|
|
109
108
|
payload: string | Buffer | object,
|
|
110
109
|
options: JwtSignOptions = {},
|
|
111
110
|
): string {
|
|
112
|
-
const signOptions = this.
|
|
113
|
-
{ ...options },
|
|
114
|
-
'signOptions',
|
|
115
|
-
) as jwt.SignOptions
|
|
116
|
-
const secret = this.getSecretKey(
|
|
117
|
-
payload,
|
|
118
|
-
options,
|
|
119
|
-
'privateKey',
|
|
120
|
-
RequestType.Sign,
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
if (secret instanceof Promise) {
|
|
124
|
-
secret.catch(() => {}) // suppress rejection from async provider
|
|
125
|
-
this.logger.warn(
|
|
126
|
-
'For async version of "secretOrKeyProvider", please use "signAsync".',
|
|
127
|
-
)
|
|
128
|
-
throw new Error()
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const allowedSignOptKeys = ['secret', 'privateKey']
|
|
132
|
-
const signOptKeys = Object.keys(signOptions)
|
|
133
|
-
if (
|
|
134
|
-
typeof payload === 'string' &&
|
|
135
|
-
signOptKeys.some((k) => !allowedSignOptKeys.includes(k))
|
|
136
|
-
) {
|
|
137
|
-
throw new Error(
|
|
138
|
-
'Payload as string is not allowed with the following sign options: ' +
|
|
139
|
-
signOptKeys.join(', '),
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
|
|
111
|
+
const { signOptions, secret } = this.prepareSign(payload, options)
|
|
143
112
|
return jwt.sign(payload, secret, signOptions)
|
|
144
113
|
}
|
|
145
114
|
|
|
146
115
|
/**
|
|
147
116
|
* Signs a JWT payload asynchronously.
|
|
148
117
|
*
|
|
149
|
-
*
|
|
150
|
-
* to handle async key resolution. Supports the same payload types and options as `sign()`.
|
|
118
|
+
* Supports the same payload types and options as `sign()`.
|
|
151
119
|
*
|
|
152
120
|
* @param payload - The payload to sign. Can be a string, Buffer, or object.
|
|
153
121
|
* @param options - Signing options. When payload is a string, only `secret` and `privateKey` are allowed.
|
|
@@ -156,7 +124,6 @@ export class JwtService {
|
|
|
156
124
|
*
|
|
157
125
|
* @example
|
|
158
126
|
* ```ts
|
|
159
|
-
* // Sign with async key provider
|
|
160
127
|
* const token = await jwtService.signAsync(
|
|
161
128
|
* { userId: '123' },
|
|
162
129
|
* { expiresIn: '1h' }
|
|
@@ -179,38 +146,12 @@ export class JwtService {
|
|
|
179
146
|
payload: string | Buffer | object,
|
|
180
147
|
options: JwtSignOptions = {},
|
|
181
148
|
): Promise<string> {
|
|
182
|
-
const signOptions = this.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const secret = this.getSecretKey(
|
|
187
|
-
payload,
|
|
188
|
-
options,
|
|
189
|
-
'privateKey',
|
|
190
|
-
RequestType.Sign,
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
const allowedSignOptKeys = ['secret', 'privateKey']
|
|
194
|
-
const signOptKeys = Object.keys(signOptions)
|
|
195
|
-
if (
|
|
196
|
-
typeof payload === 'string' &&
|
|
197
|
-
signOptKeys.some((k) => !allowedSignOptKeys.includes(k))
|
|
198
|
-
) {
|
|
199
|
-
throw new Error(
|
|
200
|
-
'Payload as string is not allowed with the following sign options: ' +
|
|
201
|
-
signOptKeys.join(', '),
|
|
149
|
+
const { signOptions, secret } = this.prepareSign(payload, options)
|
|
150
|
+
return new Promise((resolve, reject) => {
|
|
151
|
+
jwt.sign(payload, secret, signOptions, (err, encoded) =>
|
|
152
|
+
err ? reject(err) : resolve(encoded as string),
|
|
202
153
|
)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return new Promise((resolve, reject) =>
|
|
206
|
-
Promise.resolve()
|
|
207
|
-
.then(() => secret)
|
|
208
|
-
.then((scrt: GetSecretKeyResult) => {
|
|
209
|
-
jwt.sign(payload, scrt, signOptions, (err, encoded) =>
|
|
210
|
-
err ? reject(err) : resolve(encoded as string),
|
|
211
|
-
)
|
|
212
|
-
}),
|
|
213
|
-
)
|
|
154
|
+
})
|
|
214
155
|
}
|
|
215
156
|
|
|
216
157
|
/**
|
|
@@ -226,7 +167,6 @@ export class JwtService {
|
|
|
226
167
|
* @throws {TokenExpiredError} If the token has expired
|
|
227
168
|
* @throws {NotBeforeError} If the token is not yet valid (nbf claim)
|
|
228
169
|
* @throws {JsonWebTokenError} If the token is invalid or malformed
|
|
229
|
-
* @throws {Error} If `secretOrKeyProvider` returns a Promise (use `verifyAsync` instead)
|
|
230
170
|
*
|
|
231
171
|
* @example
|
|
232
172
|
* ```ts
|
|
@@ -244,22 +184,7 @@ export class JwtService {
|
|
|
244
184
|
token: string,
|
|
245
185
|
options: JwtVerifyOptions = {},
|
|
246
186
|
): T {
|
|
247
|
-
const verifyOptions = this.
|
|
248
|
-
const secret = this.getSecretKey(
|
|
249
|
-
token,
|
|
250
|
-
options,
|
|
251
|
-
'publicKey',
|
|
252
|
-
RequestType.Verify,
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
if (secret instanceof Promise) {
|
|
256
|
-
secret.catch(() => {}) // suppress rejection from async provider
|
|
257
|
-
this.logger.warn(
|
|
258
|
-
'For async version of "secretOrKeyProvider", please use "verifyAsync".',
|
|
259
|
-
)
|
|
260
|
-
throw new Error()
|
|
261
|
-
}
|
|
262
|
-
|
|
187
|
+
const { verifyOptions, secret } = this.prepareVerify(token, options)
|
|
263
188
|
// @ts-expect-error We check it
|
|
264
189
|
return jwt.verify(token, secret, verifyOptions) as unknown as T
|
|
265
190
|
}
|
|
@@ -267,8 +192,7 @@ export class JwtService {
|
|
|
267
192
|
/**
|
|
268
193
|
* Verifies and decodes a JWT token asynchronously.
|
|
269
194
|
*
|
|
270
|
-
*
|
|
271
|
-
* to handle async key resolution. Provides the same validation as `verify()`.
|
|
195
|
+
* Provides the same validation as `verify()`.
|
|
272
196
|
*
|
|
273
197
|
* @template T - The expected type of the decoded payload
|
|
274
198
|
* @param token - The JWT token string to verify
|
|
@@ -294,25 +218,13 @@ export class JwtService {
|
|
|
294
218
|
token: string,
|
|
295
219
|
options: JwtVerifyOptions = {},
|
|
296
220
|
): Promise<T> {
|
|
297
|
-
const verifyOptions = this.
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
return new Promise((resolve, reject) =>
|
|
306
|
-
Promise.resolve()
|
|
307
|
-
.then(() => secret)
|
|
308
|
-
.then((scrt: GetSecretKeyResult) => {
|
|
309
|
-
// @ts-expect-error We check it
|
|
310
|
-
jwt.verify(token, scrt, verifyOptions, (err, decoded) =>
|
|
311
|
-
err ? reject(err) : resolve(decoded as T),
|
|
312
|
-
)
|
|
313
|
-
})
|
|
314
|
-
.catch(reject),
|
|
315
|
-
)
|
|
221
|
+
const { verifyOptions, secret } = this.prepareVerify(token, options)
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
// @ts-expect-error We check it
|
|
224
|
+
jwt.verify(token, secret, verifyOptions, (err, decoded) =>
|
|
225
|
+
err ? reject(err) : resolve(decoded as T),
|
|
226
|
+
)
|
|
227
|
+
})
|
|
316
228
|
}
|
|
317
229
|
|
|
318
230
|
/**
|
|
@@ -340,6 +252,53 @@ export class JwtService {
|
|
|
340
252
|
return jwt.decode(token, options) as T
|
|
341
253
|
}
|
|
342
254
|
|
|
255
|
+
private prepareSign(
|
|
256
|
+
payload: string | Buffer | object,
|
|
257
|
+
options: JwtSignOptions,
|
|
258
|
+
): { signOptions: jwt.SignOptions; secret: GetSecretKeyResult } {
|
|
259
|
+
const signOptions = this.mergeJwtOptions(
|
|
260
|
+
{ ...options },
|
|
261
|
+
'signOptions',
|
|
262
|
+
) as jwt.SignOptions
|
|
263
|
+
const secret = this.getSecretKey(
|
|
264
|
+
payload,
|
|
265
|
+
options,
|
|
266
|
+
'privateKey',
|
|
267
|
+
RequestType.Sign,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
const allowedSignOptKeys = ['secret', 'privateKey']
|
|
271
|
+
const signOptKeys = Object.keys(signOptions)
|
|
272
|
+
if (
|
|
273
|
+
typeof payload === 'string' &&
|
|
274
|
+
signOptKeys.some((k) => !allowedSignOptKeys.includes(k))
|
|
275
|
+
) {
|
|
276
|
+
throw new Error(
|
|
277
|
+
'Payload as string is not allowed with the following sign options: ' +
|
|
278
|
+
signOptKeys.join(', '),
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return { signOptions, secret }
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private prepareVerify(
|
|
286
|
+
token: string,
|
|
287
|
+
options: JwtVerifyOptions,
|
|
288
|
+
): {
|
|
289
|
+
verifyOptions: VerifyOptions | SignOptions
|
|
290
|
+
secret: GetSecretKeyResult
|
|
291
|
+
} {
|
|
292
|
+
const verifyOptions = this.mergeJwtOptions({ ...options }, 'verifyOptions')
|
|
293
|
+
const secret = this.getSecretKey(
|
|
294
|
+
token,
|
|
295
|
+
options,
|
|
296
|
+
'publicKey',
|
|
297
|
+
RequestType.Verify,
|
|
298
|
+
)
|
|
299
|
+
return { verifyOptions, secret }
|
|
300
|
+
}
|
|
301
|
+
|
|
343
302
|
private mergeJwtOptions(
|
|
344
303
|
options: JwtVerifyOptions | JwtSignOptions,
|
|
345
304
|
key: 'verifyOptions' | 'signOptions',
|
|
@@ -364,7 +323,7 @@ export class JwtService {
|
|
|
364
323
|
options: JwtVerifyOptions | JwtSignOptions,
|
|
365
324
|
key: 'publicKey' | 'privateKey',
|
|
366
325
|
secretRequestType: RequestType,
|
|
367
|
-
): GetSecretKeyResult
|
|
326
|
+
): GetSecretKeyResult {
|
|
368
327
|
const secret = this.options.secretOrKeyProvider
|
|
369
328
|
? this.options.secretOrKeyProvider(secretRequestType, token, options)
|
|
370
329
|
: options?.secret ||
|
|
@@ -171,7 +171,7 @@ export const JwtServiceOptionsSchema = z.object({
|
|
|
171
171
|
z.any(),
|
|
172
172
|
z.union([SignOptionsSchema, VerifyOptionsSchema]).optional(),
|
|
173
173
|
],
|
|
174
|
-
output:
|
|
174
|
+
output: SecretSchema,
|
|
175
175
|
})
|
|
176
176
|
.optional(),
|
|
177
177
|
})
|