@openid4vc/oauth2 0.3.0-alpha-20250322171044 → 0.3.0-alpha-20250324183425

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.js CHANGED
@@ -309,7 +309,9 @@ var zJwtPayload = import_zod5.default.object({
309
309
  jti: import_zod5.default.string().optional(),
310
310
  cnf: zJwtConfirmationPayload.optional(),
311
311
  // Reserved for status parameters
312
- status: import_zod5.default.record(import_zod5.default.string(), import_zod5.default.any()).optional()
312
+ status: import_zod5.default.record(import_zod5.default.string(), import_zod5.default.any()).optional(),
313
+ // Reserved for OpenID Federation
314
+ trust_chain: import_zod5.default.array(import_zod5.default.string()).nonempty().optional()
313
315
  }).passthrough();
314
316
  var zJwtHeader = import_zod5.default.object({
315
317
  alg: zAlgValueNotNone,
@@ -317,7 +319,8 @@ var zJwtHeader = import_zod5.default.object({
317
319
  kid: import_zod5.default.string().optional(),
318
320
  jwk: zJwk.optional(),
319
321
  x5c: import_zod5.default.array(import_zod5.default.string()).optional(),
320
- trust_chain: import_zod5.default.array(import_zod5.default.string()).optional()
322
+ // Reserved for OpenID Federation
323
+ trust_chain: import_zod5.default.array(import_zod5.default.string()).nonempty().optional()
321
324
  }).passthrough();
322
325
 
323
326
  // src/common/jwt/decode-jwt-header.ts
@@ -371,7 +374,7 @@ function jwtHeaderFromJwtSigner(signer) {
371
374
  kid: signer.didUrl
372
375
  };
373
376
  }
374
- if (signer.method === "trustChain") {
377
+ if (signer.method === "federation") {
375
378
  return {
376
379
  alg: signer.alg,
377
380
  kid: signer.kid,
@@ -395,56 +398,101 @@ function jwtHeaderFromJwtSigner(signer) {
395
398
  alg: signer.alg
396
399
  };
397
400
  }
398
- function jwtSignerFromJwt({ header, payload }) {
401
+ function jwtSignerFromJwt({
402
+ header,
403
+ payload,
404
+ allowedSignerMethods
405
+ }) {
406
+ const found = [];
399
407
  if (header.x5c) {
400
- return {
401
- alg: header.alg,
408
+ found.push({
402
409
  method: "x5c",
403
- x5c: header.x5c
404
- };
410
+ valid: true,
411
+ signer: {
412
+ alg: header.alg,
413
+ method: "x5c",
414
+ x5c: header.x5c
415
+ }
416
+ });
405
417
  }
406
418
  if (header.trust_chain) {
407
419
  if (!header.kid) {
408
- throw new Error(`When 'trust_chain' is used in jwt header, the 'kid' parameter is required.`);
420
+ found.push({
421
+ method: "federation",
422
+ valid: false,
423
+ error: `When 'trust_chain' is used in jwt header, the 'kid' parameter is required.`
424
+ });
425
+ } else {
426
+ found.push({
427
+ method: "federation",
428
+ valid: true,
429
+ signer: {
430
+ alg: header.alg,
431
+ trustChain: header.trust_chain,
432
+ kid: header.kid,
433
+ method: "federation"
434
+ }
435
+ });
409
436
  }
410
- return {
411
- method: "trustChain",
412
- alg: header.alg,
413
- trustChain: header.trust_chain,
414
- kid: header.kid
415
- };
416
437
  }
417
- if (header.kid) {
418
- if (header.kid.startsWith("did:")) {
419
- if (payload.iss && header.kid.startsWith(payload.iss)) {
420
- }
421
- if (!header.kid.includes("#")) {
422
- }
423
- return {
438
+ if (header.kid?.startsWith("did:") || payload.iss?.startsWith("did:")) {
439
+ if (payload.iss && header.kid?.startsWith("did:") && !header.kid.startsWith(payload.iss)) {
440
+ found.push({
424
441
  method: "did",
425
- didUrl: header.kid,
426
- alg: header.alg
427
- };
428
- }
429
- if (header.kid.startsWith("#") && payload.iss?.startsWith("did:")) {
430
- return {
442
+ valid: false,
443
+ error: `kid in header starst with did that is different from did value in 'iss'`
444
+ });
445
+ } else if (!header.kid?.startsWith("did:") && !header.kid?.startsWith("#")) {
446
+ found.push({
431
447
  method: "did",
432
- didUrl: `${payload.iss}${header.kid}`,
433
- alg: header.alg
434
- };
448
+ valid: false,
449
+ error: `kid in header must start with either 'did:' or '#' when 'iss' value is a did`
450
+ });
451
+ } else {
452
+ found.push({
453
+ method: "did",
454
+ valid: true,
455
+ signer: {
456
+ method: "did",
457
+ alg: header.alg,
458
+ didUrl: header.kid.startsWith("did:") ? header.kid : `${payload.iss}${header.kid}`
459
+ }
460
+ });
435
461
  }
436
462
  }
437
463
  if (header.jwk) {
438
- return {
439
- alg: header.alg,
464
+ found.push({
440
465
  method: "jwk",
441
- publicJwk: header.jwk
466
+ signer: { alg: header.alg, method: "jwk", publicJwk: header.jwk },
467
+ valid: true
468
+ });
469
+ }
470
+ const allowedFoundMethods = found.filter((f) => !allowedSignerMethods || allowedSignerMethods?.includes(f.method));
471
+ const allowedValidMethods = allowedFoundMethods.filter((f) => f.valid);
472
+ if (allowedValidMethods.length > 0) {
473
+ return allowedValidMethods[0].signer;
474
+ }
475
+ if (allowedFoundMethods.length > 0) {
476
+ throw new Oauth2Error(
477
+ `Unable to extract signer method from jwt. Found ${allowedFoundMethods.length} allowed signer method(s) but contained invalid configuration:
478
+ ${allowedFoundMethods.map((m) => m.valid ? "" : `FAILED: method ${m.method} - ${m.error}`).join("\n")}`
479
+ );
480
+ }
481
+ if (found.length > 0) {
482
+ throw new Oauth2Error(
483
+ `Unable to extract signer method from jwt. Found ${found.length} signer method(s) that are not allowed:
484
+ ${found.map((m) => m.valid ? `SUCCEEDED: method ${m.method}` : `FAILED: method ${m.method} - ${m.error}`).join("\n")}`
485
+ );
486
+ }
487
+ if (!allowedSignerMethods || allowedSignerMethods.includes("custom")) {
488
+ return {
489
+ method: "custom",
490
+ alg: header.alg
442
491
  };
443
492
  }
444
- return {
445
- method: "custom",
446
- alg: header.alg
447
- };
493
+ throw new Oauth2Error(
494
+ `Unable to extract signer method from jwt. Found no signer methods and 'custom' signer method is not allowed.`
495
+ );
448
496
  }
449
497
 
450
498
  // src/common/jwt/z-jwe.ts