@naturalcycles/nodejs-lib 15.116.1 → 15.116.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/jwt.service2.d.ts +12 -0
- package/dist/jwt/jwt.service2.js +38 -16
- package/package.json +1 -1
- package/src/jwt/jwt.service2.ts +44 -20
|
@@ -78,6 +78,10 @@ export interface JWTSignOptions<T extends AnyObject = AnyObject> {
|
|
|
78
78
|
* By default `iat` is NOT set (same as legacy JWTService with its `noTimestamp: true` default).
|
|
79
79
|
*/
|
|
80
80
|
issuedAt?: UnixTimestamp;
|
|
81
|
+
/**
|
|
82
|
+
* Sets the `kid` (key id) header, required by some APIs (e.g Apple App Store Connect).
|
|
83
|
+
*/
|
|
84
|
+
kid?: string;
|
|
81
85
|
/**
|
|
82
86
|
* Overrides cfg.schema for this call.
|
|
83
87
|
*/
|
|
@@ -170,6 +174,14 @@ export declare class JWTService2<T extends AnyObject = AnyObject> {
|
|
|
170
174
|
*/
|
|
171
175
|
private normalizeError;
|
|
172
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* Decodes a JWT without verifying its signature (no key needed) - never trust the result.
|
|
179
|
+
* Standalone version of JWTService2.decode, for when there's no service instance at hand
|
|
180
|
+
* (no schema validation, no errorData extension).
|
|
181
|
+
*
|
|
182
|
+
* Throws JWTError with code JWT_INVALID if the token cannot be decoded.
|
|
183
|
+
*/
|
|
184
|
+
export declare function jwtDecode<T extends AnyObject>(token: JWTString): JWTDecoded<T>;
|
|
173
185
|
export type JWTErrorCode = 'JWT_EXPIRED' | 'JWT_NOT_YET_VALID' | 'JWT_INVALID';
|
|
174
186
|
export interface JWTErrorData extends ErrorData {
|
|
175
187
|
code: JWTErrorCode;
|
package/dist/jwt/jwt.service2.js
CHANGED
|
@@ -38,12 +38,17 @@ export class JWTService2 {
|
|
|
38
38
|
}
|
|
39
39
|
async sign(payload, opt) {
|
|
40
40
|
_assert(this.privateKey, 'JWTService2: privateKey is required to be able to sign, but not provided', this.cfg.errorData);
|
|
41
|
-
const { expiresAt, notBefore, issuer, audience, subject, jwtid, issuedAt, schema } = {
|
|
41
|
+
const { expiresAt, notBefore, issuer, audience, subject, jwtid, issuedAt, kid, schema } = {
|
|
42
42
|
...this.cfg.signOptions,
|
|
43
43
|
...opt,
|
|
44
44
|
};
|
|
45
45
|
(schema || this.cfg.schema)?.validate(payload);
|
|
46
|
-
|
|
46
|
+
// `kid: undefined` is dropped by JSON serialization, keeping the header unchanged when not set
|
|
47
|
+
const jwt = new SignJWT(payload).setProtectedHeader({
|
|
48
|
+
alg: this.cfg.algorithm,
|
|
49
|
+
typ: 'JWT',
|
|
50
|
+
kid,
|
|
51
|
+
});
|
|
47
52
|
if (expiresAt !== null)
|
|
48
53
|
jwt.setExpirationTime(expiresAt);
|
|
49
54
|
if (notBefore !== undefined)
|
|
@@ -83,24 +88,18 @@ export class JWTService2 {
|
|
|
83
88
|
return data;
|
|
84
89
|
}
|
|
85
90
|
decode(token, opt = {}) {
|
|
86
|
-
let
|
|
87
|
-
let payload;
|
|
91
|
+
let decoded;
|
|
88
92
|
try {
|
|
89
|
-
|
|
90
|
-
payload = decodeJwt(token);
|
|
93
|
+
decoded = jwtDecode(token);
|
|
91
94
|
}
|
|
92
95
|
catch (err) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
if (this.cfg.errorData) {
|
|
97
|
+
_errorDataAppend(err, this.cfg.errorData);
|
|
98
|
+
}
|
|
99
|
+
throw err;
|
|
97
100
|
}
|
|
98
|
-
this.validate(payload, opt.schema);
|
|
99
|
-
return
|
|
100
|
-
header,
|
|
101
|
-
payload,
|
|
102
|
-
signature: token.split('.')[2],
|
|
103
|
-
};
|
|
101
|
+
this.validate(decoded.payload, opt.schema);
|
|
102
|
+
return decoded;
|
|
104
103
|
}
|
|
105
104
|
/**
|
|
106
105
|
* Schema-validation errors on Verify/Decode are extended with cfg.errorData:
|
|
@@ -145,6 +144,29 @@ export class JWTService2 {
|
|
|
145
144
|
}, { cause: err });
|
|
146
145
|
}
|
|
147
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Decodes a JWT without verifying its signature (no key needed) - never trust the result.
|
|
149
|
+
* Standalone version of JWTService2.decode, for when there's no service instance at hand
|
|
150
|
+
* (no schema validation, no errorData extension).
|
|
151
|
+
*
|
|
152
|
+
* Throws JWTError with code JWT_INVALID if the token cannot be decoded.
|
|
153
|
+
*/
|
|
154
|
+
export function jwtDecode(token) {
|
|
155
|
+
let header;
|
|
156
|
+
let payload;
|
|
157
|
+
try {
|
|
158
|
+
header = decodeProtectedHeader(token);
|
|
159
|
+
payload = decodeJwt(token);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
throw new JWTError('invalid token, unable to decode', { code: 'JWT_INVALID' }, { cause: err });
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
header,
|
|
166
|
+
payload,
|
|
167
|
+
signature: token.split('.')[2],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
148
170
|
/**
|
|
149
171
|
* Thrown by JWTService2 on any Verify/Decode failure.
|
|
150
172
|
*
|
package/package.json
CHANGED
package/src/jwt/jwt.service2.ts
CHANGED
|
@@ -105,6 +105,10 @@ export interface JWTSignOptions<T extends AnyObject = AnyObject> {
|
|
|
105
105
|
* By default `iat` is NOT set (same as legacy JWTService with its `noTimestamp: true` default).
|
|
106
106
|
*/
|
|
107
107
|
issuedAt?: UnixTimestamp
|
|
108
|
+
/**
|
|
109
|
+
* Sets the `kid` (key id) header, required by some APIs (e.g Apple App Store Connect).
|
|
110
|
+
*/
|
|
111
|
+
kid?: string
|
|
108
112
|
/**
|
|
109
113
|
* Overrides cfg.schema for this call.
|
|
110
114
|
*/
|
|
@@ -198,14 +202,19 @@ export class JWTService2<T extends AnyObject = AnyObject> {
|
|
|
198
202
|
this.cfg.errorData,
|
|
199
203
|
)
|
|
200
204
|
|
|
201
|
-
const { expiresAt, notBefore, issuer, audience, subject, jwtid, issuedAt, schema } = {
|
|
205
|
+
const { expiresAt, notBefore, issuer, audience, subject, jwtid, issuedAt, kid, schema } = {
|
|
202
206
|
...this.cfg.signOptions,
|
|
203
207
|
...opt,
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
;(schema || this.cfg.schema)?.validate(payload)
|
|
207
211
|
|
|
208
|
-
|
|
212
|
+
// `kid: undefined` is dropped by JSON serialization, keeping the header unchanged when not set
|
|
213
|
+
const jwt = new SignJWT(payload).setProtectedHeader({
|
|
214
|
+
alg: this.cfg.algorithm,
|
|
215
|
+
typ: 'JWT',
|
|
216
|
+
kid,
|
|
217
|
+
})
|
|
209
218
|
if (expiresAt !== null) jwt.setExpirationTime(expiresAt)
|
|
210
219
|
if (notBefore !== undefined) jwt.setNotBefore(notBefore)
|
|
211
220
|
if (issuer) jwt.setIssuer(issuer)
|
|
@@ -249,30 +258,20 @@ export class JWTService2<T extends AnyObject = AnyObject> {
|
|
|
249
258
|
}
|
|
250
259
|
|
|
251
260
|
decode<TT extends T = T>(token: JWTString, opt: JWTDecodeOptions<TT> = {}): JWTDecoded<TT> {
|
|
252
|
-
let
|
|
253
|
-
let payload: TT
|
|
261
|
+
let decoded: JWTDecoded<TT>
|
|
254
262
|
|
|
255
263
|
try {
|
|
256
|
-
|
|
257
|
-
payload = decodeJwt(token) as TT
|
|
264
|
+
decoded = jwtDecode<TT>(token)
|
|
258
265
|
} catch (err) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
code: 'JWT_INVALID',
|
|
264
|
-
},
|
|
265
|
-
{ cause: err },
|
|
266
|
-
)
|
|
266
|
+
if (this.cfg.errorData) {
|
|
267
|
+
_errorDataAppend(err, this.cfg.errorData)
|
|
268
|
+
}
|
|
269
|
+
throw err
|
|
267
270
|
}
|
|
268
271
|
|
|
269
|
-
this.validate(payload, opt.schema)
|
|
272
|
+
this.validate(decoded.payload, opt.schema)
|
|
270
273
|
|
|
271
|
-
return
|
|
272
|
-
header,
|
|
273
|
-
payload,
|
|
274
|
-
signature: token.split('.')[2]!,
|
|
275
|
-
}
|
|
274
|
+
return decoded
|
|
276
275
|
}
|
|
277
276
|
|
|
278
277
|
/**
|
|
@@ -321,6 +320,31 @@ export class JWTService2<T extends AnyObject = AnyObject> {
|
|
|
321
320
|
}
|
|
322
321
|
}
|
|
323
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Decodes a JWT without verifying its signature (no key needed) - never trust the result.
|
|
325
|
+
* Standalone version of JWTService2.decode, for when there's no service instance at hand
|
|
326
|
+
* (no schema validation, no errorData extension).
|
|
327
|
+
*
|
|
328
|
+
* Throws JWTError with code JWT_INVALID if the token cannot be decoded.
|
|
329
|
+
*/
|
|
330
|
+
export function jwtDecode<T extends AnyObject>(token: JWTString): JWTDecoded<T> {
|
|
331
|
+
let header: JWTHeader
|
|
332
|
+
let payload: T
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
header = decodeProtectedHeader(token) as JWTHeader
|
|
336
|
+
payload = decodeJwt(token) as T
|
|
337
|
+
} catch (err) {
|
|
338
|
+
throw new JWTError('invalid token, unable to decode', { code: 'JWT_INVALID' }, { cause: err })
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return {
|
|
342
|
+
header,
|
|
343
|
+
payload,
|
|
344
|
+
signature: token.split('.')[2]!,
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
324
348
|
export type JWTErrorCode = 'JWT_EXPIRED' | 'JWT_NOT_YET_VALID' | 'JWT_INVALID'
|
|
325
349
|
|
|
326
350
|
export interface JWTErrorData extends ErrorData {
|