@sourceregistry/node-jwt 1.0.0 → 1.2.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/dist/index.es.js CHANGED
@@ -1,100 +1,238 @@
1
- import { createVerify as o, createSign as d, createHmac as u } from "crypto";
2
- const f = {
1
+ import l, { sign as T, createSign as s, createHmac as c, verify as E, createVerify as d, timingSafeEqual as N } from "crypto";
2
+ const S = {
3
3
  encode: (e) => Buffer.from(e).toString("base64url"),
4
4
  decode: (e) => Buffer.from(e, "base64url").toString()
5
- }, l = {
5
+ }, h = (e, r) => e.length !== r.length ? !1 : N(Buffer.from(e), Buffer.from(r)), g = {
6
6
  // HMAC
7
7
  HS256: {
8
- sign: (e, r) => u("sha256", r).update(e).digest("base64url"),
9
- verify: (e, r, t) => u("sha256", r).update(e).digest("base64url") === t
8
+ sign: (e, r) => c("sha256", r).update(e).digest("base64url"),
9
+ verify: (e, r, t) => {
10
+ const n = c("sha256", r).update(e).digest("base64url");
11
+ return h(n, t);
12
+ }
10
13
  },
11
14
  HS384: {
12
- sign: (e, r) => u("sha384", r).update(e).digest("base64url"),
13
- verify: (e, r, t) => u("sha384", r).update(e).digest("base64url") === t
15
+ sign: (e, r) => c("sha384", r).update(e).digest("base64url"),
16
+ verify: (e, r, t) => {
17
+ const n = c("sha384", r).update(e).digest("base64url");
18
+ return h(n, t);
19
+ }
14
20
  },
15
21
  HS512: {
16
- sign: (e, r) => u("sha512", r).update(e).digest("base64url"),
17
- verify: (e, r, t) => u("sha512", r).update(e).digest("base64url") === t
22
+ sign: (e, r) => c("sha512", r).update(e).digest("base64url"),
23
+ verify: (e, r, t) => {
24
+ const n = c("sha512", r).update(e).digest("base64url");
25
+ return h(n, t);
26
+ }
18
27
  },
19
28
  // RSA (DER-encoded signatures, base64url)
20
29
  RS256: {
21
- sign: (e, r) => d("RSA-SHA256").update(e).end().sign(r).toString("base64url"),
22
- verify: (e, r, t) => o("RSA-SHA256").update(e).end().verify(r, Buffer.from(t, "base64url"))
30
+ sign: (e, r) => s("RSA-SHA256").update(e).end().sign(r).toString("base64url"),
31
+ verify: (e, r, t) => {
32
+ try {
33
+ return d("RSA-SHA256").update(e).end().verify(r, Buffer.from(t, "base64url"));
34
+ } catch {
35
+ return !1;
36
+ }
37
+ }
23
38
  },
24
39
  RS384: {
25
- sign: (e, r) => d("RSA-SHA384").update(e).end().sign(r).toString("base64url"),
26
- verify: (e, r, t) => o("RSA-SHA384").update(e).end().verify(r, Buffer.from(t, "base64url"))
40
+ sign: (e, r) => s("RSA-SHA384").update(e).end().sign(r).toString("base64url"),
41
+ verify: (e, r, t) => {
42
+ try {
43
+ return d("RSA-SHA384").update(e).end().verify(r, Buffer.from(t, "base64url"));
44
+ } catch {
45
+ return !1;
46
+ }
47
+ }
27
48
  },
28
49
  RS512: {
29
- sign: (e, r) => d("RSA-SHA512").update(e).end().sign(r).toString("base64url"),
30
- verify: (e, r, t) => o("RSA-SHA512").update(e).end().verify(r, Buffer.from(t, "base64url"))
50
+ sign: (e, r) => s("RSA-SHA512").update(e).end().sign(r).toString("base64url"),
51
+ verify: (e, r, t) => {
52
+ try {
53
+ return d("RSA-SHA512").update(e).end().verify(r, Buffer.from(t, "base64url"));
54
+ } catch {
55
+ return !1;
56
+ }
57
+ }
31
58
  },
32
59
  // ECDSA (DER-encoded by default — no dsaEncoding!)
33
60
  ES256: {
34
- sign: (e, r) => d("SHA256").update(e).end().sign(r).toString("base64url"),
35
- verify: (e, r, t) => o("SHA256").update(e).end().verify(r, Buffer.from(t, "base64url"))
61
+ sign: (e, r) => s("SHA256").update(e).end().sign(r).toString("base64url"),
62
+ verify: (e, r, t) => {
63
+ try {
64
+ return d("SHA256").update(e).end().verify(r, Buffer.from(t, "base64url"));
65
+ } catch {
66
+ return !1;
67
+ }
68
+ }
36
69
  },
37
70
  ES384: {
38
- sign: (e, r) => d("SHA384").update(e).end().sign(r).toString("base64url"),
39
- verify: (e, r, t) => o("SHA384").update(e).end().verify(r, Buffer.from(t, "base64url"))
71
+ sign: (e, r) => s("SHA384").update(e).end().sign(r).toString("base64url"),
72
+ verify: (e, r, t) => {
73
+ try {
74
+ return d("SHA384").update(e).end().verify(r, Buffer.from(t, "base64url"));
75
+ } catch {
76
+ return !1;
77
+ }
78
+ }
40
79
  },
41
80
  ES512: {
42
- sign: (e, r) => d("SHA512").update(e).end().sign(r).toString("base64url"),
43
- verify: (e, r, t) => o("SHA512").update(e).end().verify(r, Buffer.from(t, "base64url"))
81
+ sign: (e, r) => s("SHA512").update(e).end().sign(r).toString("base64url"),
82
+ verify: (e, r, t) => {
83
+ try {
84
+ return d("SHA512").update(e).end().verify(r, Buffer.from(t, "base64url"));
85
+ } catch {
86
+ return !1;
87
+ }
88
+ }
89
+ },
90
+ ES256K: {
91
+ sign: (e, r) => s("SHA256").update(e).end().sign(r).toString("base64url"),
92
+ verify: (e, r, t) => {
93
+ try {
94
+ return d("SHA256").update(e).end().verify(r, Buffer.from(t, "base64url"));
95
+ } catch {
96
+ return !1;
97
+ }
98
+ }
99
+ },
100
+ PS256: {
101
+ sign: (e, r) => s("RSA-SHA256").update(e).end().sign({
102
+ //@ts-ignore
103
+ key: r,
104
+ padding: l.constants.RSA_PKCS1_PSS_PADDING,
105
+ saltLength: 32
106
+ }).toString("base64url"),
107
+ verify: (e, r, t) => {
108
+ try {
109
+ return d("RSA-SHA256").update(e).end().verify({
110
+ //@ts-ignore
111
+ key: r,
112
+ padding: l.constants.RSA_PKCS1_PSS_PADDING,
113
+ saltLength: 32
114
+ }, Buffer.from(t, "base64url"));
115
+ } catch {
116
+ return !1;
117
+ }
118
+ }
119
+ },
120
+ PS384: {
121
+ sign: (e, r) => s("RSA-SHA384").update(e).end().sign({
122
+ //@ts-ignore
123
+ key: r,
124
+ padding: l.constants.RSA_PKCS1_PSS_PADDING,
125
+ saltLength: 48
126
+ }).toString("base64url"),
127
+ verify: (e, r, t) => {
128
+ try {
129
+ return d("RSA-SHA384").update(e).end().verify({
130
+ //@ts-ignore
131
+ key: r,
132
+ padding: l.constants.RSA_PKCS1_PSS_PADDING,
133
+ saltLength: 48
134
+ }, Buffer.from(t, "base64url"));
135
+ } catch {
136
+ return !1;
137
+ }
138
+ }
139
+ },
140
+ PS512: {
141
+ sign: (e, r) => s("RSA-SHA512").update(e).end().sign({
142
+ //@ts-ignore
143
+ key: r,
144
+ padding: l.constants.RSA_PKCS1_PSS_PADDING,
145
+ saltLength: 64
146
+ }).toString("base64url"),
147
+ verify: (e, r, t) => {
148
+ try {
149
+ return d("RSA-SHA512").update(e).end().verify({
150
+ //@ts-ignore
151
+ key: r,
152
+ padding: l.constants.RSA_PKCS1_PSS_PADDING,
153
+ saltLength: 64
154
+ }, Buffer.from(t, "base64url"));
155
+ } catch {
156
+ return !1;
157
+ }
158
+ }
159
+ },
160
+ EdDSA: {
161
+ sign: (e, r) => T(null, typeof e == "string" ? Buffer.from(e, "utf8") : e, r).toString("base64url"),
162
+ verify: (e, r, t) => {
163
+ try {
164
+ return E(
165
+ null,
166
+ typeof e == "string" ? Buffer.from(e, "utf8") : e,
167
+ r,
168
+ Buffer.from(t, "base64url")
169
+ );
170
+ } catch {
171
+ return !1;
172
+ }
173
+ }
44
174
  }
45
- }, E = Object.keys(l), v = (e) => {
175
+ }, P = Object.keys(g), I = (e) => {
46
176
  const r = e.split(".");
47
177
  if (r.length !== 3)
48
178
  throw new Error('Invalid JWT: must contain exactly 3 parts separated by "."');
49
- const [t, i, n] = r;
50
- if (!t || !i || !n)
179
+ const [t, n, i] = r;
180
+ if (!t || !n || !i)
51
181
  throw new Error("Invalid JWT: empty part detected");
52
182
  try {
53
- const a = JSON.parse(f.decode(t)), s = JSON.parse(f.decode(i));
54
- return { header: a, payload: s, signature: n };
183
+ const a = JSON.parse(S.decode(t)), o = JSON.parse(S.decode(n));
184
+ return { header: a, payload: o, signature: i };
55
185
  } catch (a) {
56
186
  throw new Error(`Invalid JWT: malformed header or payload (${a.message})`);
57
187
  }
58
- }, h = (e, r, t = {}) => {
59
- const i = t.alg ?? "HS256", n = t.typ ?? "JWT";
60
- if (!(i in l))
61
- throw new Error(`Unsupported algorithm: ${i}`);
62
- const a = { alg: i, typ: n };
188
+ }, k = (e, r, t = {}) => {
189
+ const n = t.alg ?? "HS256", i = t.typ ?? "JWT";
190
+ if (!(n in g))
191
+ throw new Error(`Unsupported algorithm: ${n}`);
192
+ const a = { alg: n, typ: i };
63
193
  t.kid && (a.kid = t.kid);
64
- const s = f.encode(JSON.stringify(a)), g = f.encode(JSON.stringify(e)), c = `${s}.${g}`, y = l[i].sign(c, r);
65
- return `${s}.${g}.${y}`;
66
- }, b = (e, r, t = {}) => {
67
- let i;
194
+ const o = S.encode(JSON.stringify(a)), f = S.encode(JSON.stringify(e)), A = `${o}.${f}`, m = g[n].sign(A, r);
195
+ return `${o}.${f}.${m}`;
196
+ }, D = (e, r, t = {}) => {
197
+ let n;
68
198
  try {
69
- i = v(e);
70
- } catch (A) {
199
+ n = I(e);
200
+ } catch (u) {
71
201
  return {
72
202
  valid: !1,
73
203
  error: {
74
- reason: A.message,
204
+ reason: u.message,
75
205
  code: "INVALID_TOKEN"
76
206
  }
77
207
  };
78
208
  }
79
- const { header: n, payload: a, signature: s } = i, g = n.alg;
80
- if (!(g in l))
209
+ const { header: i, payload: a, signature: o } = n, f = i.alg;
210
+ if (!(f in g))
81
211
  return {
82
212
  valid: !1,
83
213
  error: {
84
- reason: `Unsupported or unknown algorithm: ${n.alg}`,
214
+ reason: `Unsupported or unknown algorithm: ${i.alg}`,
85
215
  code: "INVALID_ALGORITHM"
86
216
  }
87
217
  };
88
- if (n.typ && n.typ !== "JWT")
218
+ if (t.algorithms && t.algorithms.length > 0 && !t.algorithms.includes(f))
219
+ return {
220
+ valid: !1,
221
+ error: {
222
+ reason: `Algorithm "${f}" is not in the allowed algorithms list`,
223
+ code: "ALGORITHM_NOT_ALLOWED"
224
+ }
225
+ };
226
+ if (i.typ !== void 0 && i.typ !== "JWT")
89
227
  return {
90
228
  valid: !1,
91
229
  error: {
92
- reason: `Invalid token type: expected 'JWT', got '${n.typ}'`,
230
+ reason: `Invalid token type: expected 'JWT', got '${i.typ}'`,
93
231
  code: "INVALID_TYPE"
94
232
  }
95
233
  };
96
- const c = `${f.encode(JSON.stringify(n))}.${f.encode(JSON.stringify(a))}`;
97
- if (!l[g].verify(c, r, s))
234
+ const A = `${S.encode(JSON.stringify(i))}.${S.encode(JSON.stringify(a))}`;
235
+ if (!g[f].verify(A, r, o))
98
236
  return {
99
237
  valid: !1,
100
238
  error: {
@@ -102,39 +240,130 @@ const f = {
102
240
  code: "INVALID_SIGNATURE"
103
241
  }
104
242
  };
105
- const S = Math.floor(Date.now() / 1e3), p = t.clockSkew ?? 0;
106
- return !t.ignoreExpiration && a.exp !== void 0 && S > a.exp + p ? {
107
- valid: !1,
108
- error: {
109
- reason: "Token expired",
110
- code: "TOKEN_EXPIRED"
111
- }
112
- } : a.nbf !== void 0 && S + p < a.nbf ? {
113
- valid: !1,
114
- error: {
115
- reason: "Token not yet valid",
116
- code: "TOKEN_NOT_ACTIVE"
117
- }
118
- } : a.iat !== void 0 && S + p < a.iat ? {
119
- valid: !1,
120
- error: {
121
- reason: "Token issued in the future",
122
- code: "TOKEN_FUTURE_ISSUED"
123
- }
124
- } : { valid: !0, header: n, payload: a, signature: s };
125
- }, T = {
126
- sign: h,
127
- verify: b,
128
- decode: v,
129
- algorithms: l
243
+ const y = Math.floor(Date.now() / 1e3), v = t.clockSkew ?? 0;
244
+ if (!t.ignoreExpiration && a.exp !== void 0 && y > a.exp + v)
245
+ return {
246
+ valid: !1,
247
+ error: {
248
+ reason: "Token expired",
249
+ code: "TOKEN_EXPIRED"
250
+ }
251
+ };
252
+ if (a.nbf !== void 0 && y + v < a.nbf)
253
+ return {
254
+ valid: !1,
255
+ error: {
256
+ reason: "Token not yet valid",
257
+ code: "TOKEN_NOT_ACTIVE"
258
+ }
259
+ };
260
+ if (a.iat !== void 0 && y + v < a.iat)
261
+ return {
262
+ valid: !1,
263
+ error: {
264
+ reason: "Token issued in the future",
265
+ code: "TOKEN_FUTURE_ISSUED"
266
+ }
267
+ };
268
+ if (t.maxTokenAge !== void 0 && a.iat !== void 0) {
269
+ const u = y - a.iat;
270
+ if (u > t.maxTokenAge)
271
+ return {
272
+ valid: !1,
273
+ error: {
274
+ reason: `Token age (${u}s) exceeds maximum allowed age (${t.maxTokenAge}s)`,
275
+ code: "TOKEN_TOO_OLD"
276
+ }
277
+ };
278
+ }
279
+ if (t.issuer !== void 0) {
280
+ if (a.iss === void 0)
281
+ return {
282
+ valid: !1,
283
+ error: {
284
+ reason: 'Token missing required issuer claim ("iss")',
285
+ code: "MISSING_ISSUER"
286
+ }
287
+ };
288
+ if (t.issuer !== a.iss)
289
+ return {
290
+ valid: !1,
291
+ error: {
292
+ reason: `Invalid token issuer: expected "${t.issuer}", got "${a.iss}"`,
293
+ code: "INVALID_ISSUER"
294
+ }
295
+ };
296
+ }
297
+ if (t.subject !== void 0) {
298
+ if (a.sub === void 0)
299
+ return {
300
+ valid: !1,
301
+ error: {
302
+ reason: 'Token missing required subject claim ("sub")',
303
+ code: "MISSING_SUBJECT"
304
+ }
305
+ };
306
+ if (t.subject !== a.sub)
307
+ return {
308
+ valid: !1,
309
+ error: {
310
+ reason: `Invalid token subject: expected "${t.subject}", got "${a.sub}"`,
311
+ code: "INVALID_SUBJECT"
312
+ }
313
+ };
314
+ }
315
+ if (t.audience !== void 0) {
316
+ const u = a.aud;
317
+ if (u === void 0)
318
+ return {
319
+ valid: !1,
320
+ error: {
321
+ reason: 'Token missing required audience claim ("aud")',
322
+ code: "MISSING_AUDIENCE"
323
+ }
324
+ };
325
+ const p = Array.isArray(t.audience) ? t.audience : [t.audience], b = Array.isArray(u) ? u : [u];
326
+ if (!p.some((_) => b.includes(_)))
327
+ return {
328
+ valid: !1,
329
+ error: {
330
+ reason: "Audience claim mismatch",
331
+ code: "INVALID_AUDIENCE"
332
+ }
333
+ };
334
+ }
335
+ if (t.jwtId !== void 0) {
336
+ if (a.jti === void 0)
337
+ return {
338
+ valid: !1,
339
+ error: {
340
+ reason: 'Token missing required JWT ID claim ("jti")',
341
+ code: "MISSING_JTI"
342
+ }
343
+ };
344
+ if (t.jwtId !== a.jti)
345
+ return {
346
+ valid: !1,
347
+ error: {
348
+ reason: `Invalid JWT ID: expected "${t.jwtId}", got "${a.jti}"`,
349
+ code: "INVALID_JTI"
350
+ }
351
+ };
352
+ }
353
+ return { valid: !0, header: i, payload: a, signature: o };
354
+ }, $ = {
355
+ sign: k,
356
+ verify: D,
357
+ decode: I,
358
+ algorithms: g
130
359
  };
131
360
  export {
132
- T as JWT,
133
- l as SignatureAlgorithm,
134
- E as SupportedAlgorithms,
135
- f as base64Url,
136
- v as decode,
137
- h as sign,
138
- b as verify
361
+ $ as JWT,
362
+ g as SignatureAlgorithm,
363
+ P as SupportedAlgorithms,
364
+ S as base64Url,
365
+ I as decode,
366
+ k as sign,
367
+ D as verify
139
368
  };
140
369
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/index.ts"],"sourcesContent":["import {\n createHmac,\n createSign,\n createVerify,\n type BinaryLike,\n type KeyLike\n} from 'crypto';\n\n// Base64URL helpers (padding-safe)\nexport const base64Url = {\n encode: (input: string | Buffer): string =>\n Buffer.from(input).toString('base64url'),\n\n decode: (input: string): string => {\n // Node.js Buffer handles unpadded base64url since v16, but we normalize for safety\n return Buffer.from(input, 'base64url').toString();\n }\n};\n\n// Standard JWT payload claims\nexport interface JWTPayload {\n /**\n * Issuer\n */\n iss?: string;\n /**\n * Subject\n */\n sub?: string;\n /**\n * Audience\n */\n aud?: string | string[];\n /**\n * Expiration Time (as UNIX timestamp)\n */\n exp?: number;\n /**\n * Not Before (as UNIX timestamp)\n */\n nbf?: number;\n /**\n * Issued At (as UNIX timestamp)\n */\n iat?: number;\n /**\n * JWT ID\n */\n jti?: string;\n /**\n * Session ID\n */\n sid?: string;\n /**\n * Custom claims\n */\n [key: string]: unknown;\n}\n\nexport interface JWTHeader {\n alg: string; // Allow unknown algs during decode\n typ?: string;\n kid?: string;\n}\n\nexport interface JWT {\n header: JWTHeader;\n payload: JWTPayload;\n signature: string;\n}\n\n// Signature algorithms\nexport const SignatureAlgorithm = {\n // HMAC\n HS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha256', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createHmac('sha256', secret).update(data).digest('base64url') === signature\n },\n HS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha384', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createHmac('sha384', secret).update(data).digest('base64url') === signature\n },\n HS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha512', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createHmac('sha512', secret).update(data).digest('base64url') === signature\n },\n\n // RSA (DER-encoded signatures, base64url)\n RS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createVerify('RSA-SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'))\n },\n RS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA384').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createVerify('RSA-SHA384')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'))\n },\n RS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA512').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createVerify('RSA-SHA512')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'))\n },\n\n // ECDSA (DER-encoded by default — no dsaEncoding!)\n ES256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createVerify('SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'))\n },\n ES384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA384').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createVerify('SHA384')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'))\n },\n ES512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA512').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) =>\n createVerify('SHA512')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'))\n }\n} as const;\n\nexport type SupportedAlgorithm = keyof typeof SignatureAlgorithm;\n\nexport const SupportedAlgorithms = Object.keys(SignatureAlgorithm) as Array<SupportedAlgorithm>;\n\n/**\n * Decode a JWT string into its parts (without verification)\n */\nexport const decode = (token: string): JWT => {\n const parts = token.split('.');\n if (parts.length !== 3) {\n throw new Error('Invalid JWT: must contain exactly 3 parts separated by \".\"');\n }\n\n const [headerPart, payloadPart, signature] = parts;\n\n if (!headerPart || !payloadPart || !signature) {\n throw new Error('Invalid JWT: empty part detected');\n }\n\n try {\n const header = JSON.parse(base64Url.decode(headerPart)) as JWTHeader;\n const payload = JSON.parse(base64Url.decode(payloadPart)) as JWTPayload;\n return { header, payload, signature };\n } catch (err) {\n throw new Error(`Invalid JWT: malformed header or payload (${(err as Error).message})`);\n }\n};\n\n/**\n * Sign a JWT\n */\nexport const sign = (\n payload: JWTPayload,\n secret: KeyLike,\n options: {\n alg?: SupportedAlgorithm;\n kid?: string;\n typ?: string;\n } = {}\n): string => {\n const alg = options.alg ?? 'HS256';\n const typ = options.typ ?? 'JWT';\n\n if (!(alg in SignatureAlgorithm)) {\n throw new Error(`Unsupported algorithm: ${alg}`);\n }\n\n const header: JWTHeader = { alg, typ };\n if (options.kid) header.kid = options.kid;\n\n const headerEncoded = base64Url.encode(JSON.stringify(header));\n const payloadEncoded = base64Url.encode(JSON.stringify(payload));\n\n const signingInput = `${headerEncoded}.${payloadEncoded}`;\n const signature = SignatureAlgorithm[alg].sign(signingInput, secret);\n\n return `${headerEncoded}.${payloadEncoded}.${signature}`;\n};\n\n/**\n * Verify and validate a JWT\n */\nexport const verify = (\n token: string,\n secret: KeyLike,\n options: {\n ignoreExpiration?: boolean;\n clockSkew?: number; // in seconds, default 0\n } = {}\n):\n | { valid: true; header: JWTHeader; payload: JWTPayload; signature: string }\n | { valid: false; error: { reason: string; code: string } } => {\n let decoded: JWT;\n try {\n decoded = decode(token);\n } catch (err) {\n return {\n valid: false,\n error: {\n reason: (err as Error).message,\n code: 'INVALID_TOKEN'\n }\n };\n }\n\n const { header, payload, signature } = decoded;\n\n // Validate algorithm\n const alg = header.alg as SupportedAlgorithm;\n if (!(alg in SignatureAlgorithm)) {\n return {\n valid: false,\n error: {\n reason: `Unsupported or unknown algorithm: ${header.alg}`,\n code: 'INVALID_ALGORITHM'\n }\n };\n }\n\n // Optional: validate 'typ' header\n if (header.typ && header.typ !== 'JWT') {\n return {\n valid: false,\n error: {\n reason: `Invalid token type: expected 'JWT', got '${header.typ}'`,\n code: 'INVALID_TYPE'\n }\n };\n }\n\n // Verify signature\n const signingInput = `${base64Url.encode(JSON.stringify(header))}.${base64Url.encode(JSON.stringify(payload))}`;\n const isValidSignature = SignatureAlgorithm[alg].verify(signingInput, secret, signature);\n\n if (!isValidSignature) {\n return {\n valid: false,\n error: {\n reason: \"Signature verification failed\",\n code: 'INVALID_SIGNATURE'\n }\n };\n }\n\n // Time validation\n const now = Math.floor(Date.now() / 1000);\n const skew = options.clockSkew ?? 0;\n\n if (!options.ignoreExpiration) {\n if (payload.exp !== undefined && now > payload.exp + skew) {\n return {\n valid: false,\n error: {\n reason: 'Token expired',\n code: 'TOKEN_EXPIRED'\n }\n };\n }\n }\n\n if (payload.nbf !== undefined && now + skew < payload.nbf) {\n return {\n valid: false,\n error: {\n reason: 'Token not yet valid',\n code: 'TOKEN_NOT_ACTIVE'\n }\n };\n }\n\n if (payload.iat !== undefined && now + skew < payload.iat) {\n return {\n valid: false,\n error: {\n reason: 'Token issued in the future',\n code: 'TOKEN_FUTURE_ISSUED'\n }\n };\n }\n\n return { valid: true, header, payload, signature };\n};\n\n// Optional: namespace export (not default)\nexport const JWT = {\n sign,\n verify,\n decode,\n algorithms: SignatureAlgorithm\n};\n"],"names":["base64Url","input","SignatureAlgorithm","data","secret","createHmac","signature","createSign","createVerify","SupportedAlgorithms","decode","token","parts","headerPart","payloadPart","header","payload","err","sign","options","alg","typ","headerEncoded","payloadEncoded","signingInput","verify","decoded","now","skew","JWT"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/index.ts"],"sourcesContent":["import crypto, {\n createHmac,\n createSign,\n createVerify,\n sign as cryptoSign,\n verify as cryptoVerify,\n timingSafeEqual,\n type BinaryLike,\n type KeyLike\n} from 'crypto';\n\n// Base64URL helpers (padding-safe)\nexport const base64Url = {\n encode: (input: string | Buffer): string =>\n Buffer.from(input).toString('base64url'),\n\n decode: (input: string): string => {\n // Node.js Buffer handles unpadded base64url since v16, but we normalize for safety\n return Buffer.from(input, 'base64url').toString();\n }\n};\n\n// Timing-safe string comparison to prevent timing attacks\nconst timingSafeCompare = (a: string, b: string): boolean => {\n if (a.length !== b.length) {\n return false;\n }\n return timingSafeEqual(Buffer.from(a), Buffer.from(b));\n};\n\n// Standard JWT payload claims\nexport interface JWTPayload {\n /**\n * Issuer\n */\n iss?: string;\n /**\n * Subject\n */\n sub?: string;\n /**\n * Audience\n */\n aud?: string | string[];\n /**\n * Expiration Time (as UNIX timestamp)\n */\n exp?: number;\n /**\n * Not Before (as UNIX timestamp)\n */\n nbf?: number;\n /**\n * Issued At (as UNIX timestamp)\n */\n iat?: number;\n /**\n * JWT ID\n */\n jti?: string;\n /**\n * Session ID\n */\n sid?: string;\n\n /**\n * Custom claims\n */\n [key: string]: unknown;\n}\n\nexport interface JWTHeader {\n alg: string; // Allow unknown algs during decode\n typ?: string;\n kid?: string;\n}\n\nexport interface JWT {\n header: JWTHeader;\n payload: JWTPayload;\n signature: string;\n}\n\n// Signature algorithms\nexport const SignatureAlgorithm = {\n // HMAC\n HS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha256', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n const expected = createHmac('sha256', secret).update(data).digest('base64url');\n return timingSafeCompare(expected, signature);\n }\n },\n HS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha384', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n const expected = createHmac('sha384', secret).update(data).digest('base64url');\n return timingSafeCompare(expected, signature);\n }\n },\n HS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createHmac('sha512', secret).update(data).digest('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n const expected = createHmac('sha512', secret).update(data).digest('base64url');\n return timingSafeCompare(expected, signature);\n }\n },\n\n // RSA (DER-encoded signatures, base64url)\n RS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n RS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA384').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA384')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n RS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA512').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA512')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n\n // ECDSA (DER-encoded by default — no dsaEncoding!)\n ES256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n ES384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA384').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA384')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n ES512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA512').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA512')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n ES256K: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('SHA256').update(data).end().sign(secret).toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('SHA256')\n .update(data)\n .end()\n .verify(secret, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n PS256: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA256')\n .update(data)\n .end()\n .sign({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 32\n })\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA256')\n .update(data)\n .end()\n .verify({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 32\n }, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n PS384: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA384')\n .update(data)\n .end()\n .sign({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 48\n })\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA384')\n .update(data)\n .end()\n .verify({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 48\n }, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n PS512: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n createSign('RSA-SHA512')\n .update(data)\n .end()\n .sign({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 64\n })\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return createVerify('RSA-SHA512')\n .update(data)\n .end()\n .verify({\n //@ts-ignore\n key: secret,\n padding: crypto.constants.RSA_PKCS1_PSS_PADDING,\n saltLength: 64\n }, Buffer.from(signature, 'base64url'));\n } catch {\n return false;\n }\n }\n },\n EdDSA: {\n sign: (data: BinaryLike, secret: KeyLike) =>\n cryptoSign(null, typeof data === 'string' ? Buffer.from(data, 'utf8') : data, secret)\n .toString('base64url'),\n verify: (data: BinaryLike, secret: KeyLike, signature: string) => {\n try {\n return cryptoVerify(\n null,\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data,\n secret,\n Buffer.from(signature, 'base64url')\n );\n } catch {\n return false;\n }\n }\n }\n} as const;\n\nexport type SupportedAlgorithm = keyof typeof SignatureAlgorithm;\n\nexport const SupportedAlgorithms = Object.keys(SignatureAlgorithm) as Array<SupportedAlgorithm>;\n\n/**\n * Decode a JWT string into its parts (without verification)\n */\nexport const decode = (token: string): JWT => {\n const parts = token.split('.');\n if (parts.length !== 3) {\n throw new Error('Invalid JWT: must contain exactly 3 parts separated by \".\"');\n }\n\n const [headerPart, payloadPart, signature] = parts;\n\n if (!headerPart || !payloadPart || !signature) {\n throw new Error('Invalid JWT: empty part detected');\n }\n\n try {\n const header = JSON.parse(base64Url.decode(headerPart)) as JWTHeader;\n const payload = JSON.parse(base64Url.decode(payloadPart)) as JWTPayload;\n return {header, payload, signature};\n } catch (err) {\n throw new Error(`Invalid JWT: malformed header or payload (${(err as Error).message})`);\n }\n};\n\n/**\n * Sign a JWT\n */\nexport const sign = (\n payload: JWTPayload,\n secret: KeyLike,\n options: {\n alg?: SupportedAlgorithm;\n kid?: string;\n typ?: string;\n } = {}\n): string => {\n const alg = options.alg ?? 'HS256';\n const typ = options.typ ?? 'JWT';\n\n if (!(alg in SignatureAlgorithm)) {\n throw new Error(`Unsupported algorithm: ${alg}`);\n }\n\n const header: JWTHeader = {alg, typ};\n if (options.kid) header.kid = options.kid;\n\n const headerEncoded = base64Url.encode(JSON.stringify(header));\n const payloadEncoded = base64Url.encode(JSON.stringify(payload));\n\n const signingInput = `${headerEncoded}.${payloadEncoded}`;\n const signature = SignatureAlgorithm[alg].sign(signingInput, secret);\n\n return `${headerEncoded}.${payloadEncoded}.${signature}`;\n};\n\n/**\n * Verify and validate a JWT\n */\nexport const verify = (\n token: string,\n secret: KeyLike,\n options: {\n algorithms?: SupportedAlgorithm[]; // Whitelist of allowed algorithms\n issuer?: string;\n subject?: string;\n audience?: string | string[];\n jwtId?: string;\n ignoreExpiration?: boolean;\n clockSkew?: number; // in seconds, default 0\n maxTokenAge?: number; // Maximum age in seconds\n } = {}\n):\n | { valid: true; header: JWTHeader; payload: JWTPayload; signature: string }\n | { valid: false; error: { reason: string; code: string } } => {\n let decoded: JWT;\n try {\n decoded = decode(token);\n } catch (err) {\n return {\n valid: false,\n error: {\n reason: (err as Error).message,\n code: 'INVALID_TOKEN'\n }\n };\n }\n\n const {header, payload, signature} = decoded;\n\n // Validate algorithm\n const alg = header.alg as SupportedAlgorithm;\n if (!(alg in SignatureAlgorithm)) {\n return {\n valid: false,\n error: {\n reason: `Unsupported or unknown algorithm: ${header.alg}`,\n code: 'INVALID_ALGORITHM'\n }\n };\n }\n\n // Algorithm whitelist validation (prevents algorithm confusion attacks)\n if (options.algorithms && options.algorithms.length > 0) {\n if (!options.algorithms.includes(alg)) {\n return {\n valid: false,\n error: {\n reason: `Algorithm \"${alg}\" is not in the allowed algorithms list`,\n code: 'ALGORITHM_NOT_ALLOWED'\n }\n };\n }\n }\n\n // Validate 'typ' header (must be 'JWT' if present)\n if (header.typ !== undefined && header.typ !== 'JWT') {\n return {\n valid: false,\n error: {\n reason: `Invalid token type: expected 'JWT', got '${header.typ}'`,\n code: 'INVALID_TYPE'\n }\n };\n }\n\n // Verify signature\n const signingInput = `${base64Url.encode(JSON.stringify(header))}.${base64Url.encode(JSON.stringify(payload))}`;\n const isValidSignature = SignatureAlgorithm[alg].verify(signingInput, secret, signature);\n\n if (!isValidSignature) {\n return {\n valid: false,\n error: {\n reason: \"Signature verification failed\",\n code: 'INVALID_SIGNATURE'\n }\n };\n }\n\n // Time validation\n const now = Math.floor(Date.now() / 1000);\n const skew = options.clockSkew ?? 0;\n\n if (!options.ignoreExpiration) {\n if (payload.exp !== undefined && now > payload.exp + skew) {\n return {\n valid: false,\n error: {\n reason: 'Token expired',\n code: 'TOKEN_EXPIRED'\n }\n };\n }\n }\n\n if (payload.nbf !== undefined && now + skew < payload.nbf) {\n return {\n valid: false,\n error: {\n reason: 'Token not yet valid',\n code: 'TOKEN_NOT_ACTIVE'\n }\n };\n }\n\n if (payload.iat !== undefined && now + skew < payload.iat) {\n return {\n valid: false,\n error: {\n reason: 'Token issued in the future',\n code: 'TOKEN_FUTURE_ISSUED'\n }\n };\n }\n\n // Maximum token age validation\n if (options.maxTokenAge !== undefined && payload.iat !== undefined) {\n const tokenAge = now - payload.iat;\n if (tokenAge > options.maxTokenAge) {\n return {\n valid: false,\n error: {\n reason: `Token age (${tokenAge}s) exceeds maximum allowed age (${options.maxTokenAge}s)`,\n code: 'TOKEN_TOO_OLD'\n }\n };\n }\n }\n\n // --- Claim validations (only if options provided) ---\n\n // Issuer (`iss`)\n if (options.issuer !== undefined) {\n if (payload.iss === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required issuer claim (\"iss\")',\n code: 'MISSING_ISSUER'\n }\n };\n }\n if (options.issuer !== payload.iss) {\n return {\n valid: false,\n error: {\n reason: `Invalid token issuer: expected \"${options.issuer}\", got \"${payload.iss}\"`,\n code: 'INVALID_ISSUER'\n }\n };\n }\n }\n\n // Subject (`sub`)\n if (options.subject !== undefined) {\n if (payload.sub === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required subject claim (\"sub\")',\n code: 'MISSING_SUBJECT'\n }\n };\n }\n if (options.subject !== payload.sub) {\n return {\n valid: false,\n error: {\n reason: `Invalid token subject: expected \"${options.subject}\", got \"${payload.sub}\"`,\n code: 'INVALID_SUBJECT'\n }\n };\n }\n }\n\n // Audience (`aud`)\n if (options.audience !== undefined) {\n const aud = payload.aud;\n if (aud === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required audience claim (\"aud\")',\n code: 'MISSING_AUDIENCE'\n }\n };\n }\n\n const expectedAud = Array.isArray(options.audience) ? options.audience : [options.audience];\n const tokenAud = Array.isArray(aud) ? aud : [aud];\n\n const hasMatch = expectedAud.some(a => tokenAud.includes(a));\n if (!hasMatch) {\n return {\n valid: false,\n error: {\n reason: 'Audience claim mismatch',\n code: 'INVALID_AUDIENCE'\n }\n };\n }\n }\n\n // JWT ID (`jti`)\n if (options.jwtId !== undefined) {\n if (payload.jti === undefined) {\n return {\n valid: false,\n error: {\n reason: 'Token missing required JWT ID claim (\"jti\")',\n code: 'MISSING_JTI'\n }\n };\n }\n if (options.jwtId !== payload.jti) {\n return {\n valid: false,\n error: {\n reason: `Invalid JWT ID: expected \"${options.jwtId}\", got \"${payload.jti}\"`,\n code: 'INVALID_JTI'\n }\n };\n }\n }\n\n return {valid: true, header, payload, signature};\n};\n\n// Optional: namespace export\nexport const JWT = {\n sign,\n verify,\n decode,\n algorithms: SignatureAlgorithm\n};\n"],"names":["base64Url","input","timingSafeCompare","a","b","timingSafeEqual","SignatureAlgorithm","data","secret","createHmac","signature","expected","createSign","createVerify","crypto","cryptoSign","cryptoVerify","SupportedAlgorithms","decode","token","parts","headerPart","payloadPart","header","payload","err","sign","options","alg","typ","headerEncoded","payloadEncoded","signingInput","verify","decoded","now","skew","tokenAge","aud","expectedAud","tokenAud","JWT"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index.cjs.js"),s=r=>Promise.resolve().then(()=>e.decode(r)),n=(r,o,t={})=>Promise.resolve().then(()=>e.sign(r,o,t)),g=(r,o,t={})=>Promise.resolve().then(()=>{const i=e.verify(r,o,t);if(!i.valid)throw i.error;const{header:l,payload:d,signature:c}=i;return{header:l,payload:d,signature:c}}),u={sign:n,verify:g,decode:s,algorithms:e.SignatureAlgorithm};exports.SignatureAlgorithm=e.SignatureAlgorithm;exports.SupportedAlgorithms=e.SupportedAlgorithms;exports.JWT=u;exports.decode=s;exports.sign=n;exports.verify=g;
2
+ //# sourceMappingURL=promises.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promises.cjs.js","sources":["../src/promises.ts"],"sourcesContent":["import type { KeyLike } from 'crypto';\nimport {\n type JWT as JSONWebToken,\n decode as decodeSync,\n sign as signSync,\n verify as verifySync,\n JWTPayload,\n type SupportedAlgorithm,\n JWTHeader,\n SignatureAlgorithm\n} from './index.js';\n\nexport { type SupportedAlgorithm, SupportedAlgorithms, SignatureAlgorithm, type JWTHeader, type JWTPayload } from './index.js';\n\n/**\n * Decode a JWT string into its parts (without verification)\n */\nexport const decode = (token: string): Promise<JSONWebToken> =>\n Promise.resolve().then(() => decodeSync(token));\n\n/**\n * Sign a JWT\n */\nexport const sign = (\n payload: JWTPayload,\n secret: KeyLike,\n options: {\n alg?: SupportedAlgorithm;\n kid?: string;\n typ?: string;\n } = {}\n): Promise<string> =>\n Promise.resolve().then(() => signSync(payload, secret, options));\n\n/**\n * Verify and validate a JWT\n *\n * @throws { { reason: string; code: string } } if invalid\n */\nexport const verify = (\n token: string,\n secret: KeyLike,\n options: {\n algorithms?: SupportedAlgorithm[]; // Whitelist of allowed algorithms\n issuer?: string;\n subject?: string;\n audience?: string | string[];\n jwtId?: string;\n ignoreExpiration?: boolean;\n clockSkew?: number; // in seconds, default 0\n maxTokenAge?: number; // Maximum age in seconds\n } = {}\n): Promise<{ header: JWTHeader; payload: JWTPayload; signature: string }> =>\n Promise.resolve().then(() => {\n const result = verifySync(token, secret, options);\n if (!result.valid) {\n throw result.error;\n }\n const { header, payload, signature } = result;\n return { header, payload, signature };\n });\n\nexport type JWT = JSONWebToken;\n\nexport const JWT = {\n sign,\n verify,\n decode,\n algorithms: SignatureAlgorithm\n};\n"],"names":["decode","token","decodeSync","sign","payload","secret","options","signSync","verify","result","verifySync","header","signature","JWT","SignatureAlgorithm"],"mappings":"kHAiBaA,EAAUC,GACnB,QAAQ,QAAA,EAAU,KAAK,IAAMC,EAAAA,OAAWD,CAAK,CAAC,EAKrCE,EAAO,CAChBC,EACAC,EACAC,EAII,CAAA,IAEJ,QAAQ,QAAA,EAAU,KAAK,IAAMC,EAAAA,KAASH,EAASC,EAAQC,CAAO,CAAC,EAOtDE,EAAS,CAClBP,EACAI,EACAC,EASI,CAAA,IAEJ,QAAQ,UAAU,KAAK,IAAM,CACzB,MAAMG,EAASC,EAAAA,OAAWT,EAAOI,EAAQC,CAAO,EAChD,GAAI,CAACG,EAAO,MACR,MAAMA,EAAO,MAEjB,KAAM,CAAE,OAAAE,EAAQ,QAAAP,EAAS,UAAAQ,CAAA,EAAcH,EACvC,MAAO,CAAE,OAAAE,EAAQ,QAAAP,EAAS,UAAAQ,CAAA,CAC9B,CAAC,EAIQC,EAAM,CACf,KAAAV,EACA,OAAAK,EACA,OAAAR,EACA,WAAYc,EAAAA,kBAChB"}