@pagopa/io-wallet-oid4vci 1.4.2 → 1.5.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.js CHANGED
@@ -59,8 +59,14 @@ __export(index_exports, {
59
59
  verifyAuthorizationResponseFormPostJWT: () => verifyAuthorizationResponseFormPostJWT,
60
60
  verifyCredentialRequestJwtProof: () => verifyCredentialRequestJwtProof,
61
61
  verifyKeyAttestationJwt: () => verifyKeyAttestationJwt,
62
+ zAuthorizationCodeGrantV1_3: () => zAuthorizationCodeGrantV1_3,
63
+ zAuthorizationCodeGrantV1_4: () => zAuthorizationCodeGrantV1_4,
62
64
  zAuthorizationResponse: () => zAuthorizationResponse,
63
65
  zCredentialObject: () => zCredentialObject,
66
+ zCredentialOfferGrantsV1_3: () => zCredentialOfferGrantsV1_3,
67
+ zCredentialOfferGrantsV1_4: () => zCredentialOfferGrantsV1_4,
68
+ zCredentialOfferV1_3: () => zCredentialOfferV1_3,
69
+ zCredentialOfferV1_4: () => zCredentialOfferV1_4,
64
70
  zCredentialRequestV1_0: () => zCredentialRequestV1_0,
65
71
  zCredentialRequestV1_3: () => zCredentialRequestV1_3,
66
72
  zCredentialResponseEncryption: () => zCredentialResponseEncryption,
@@ -272,7 +278,8 @@ async function sendAuthorizationResponseAndExtractCode(options) {
272
278
  }
273
279
 
274
280
  // src/credential-offer/extract-grant-details.ts
275
- function extractGrantDetails(credentialOffer) {
281
+ var import_io_wallet_utils2 = require("@pagopa/io-wallet-utils");
282
+ function requireAuthorizationCodeGrant(credentialOffer) {
276
283
  if (!credentialOffer.grants) {
277
284
  throw new CredentialOfferError("No grants found in credential offer");
278
285
  }
@@ -280,6 +287,10 @@ function extractGrantDetails(credentialOffer) {
280
287
  if (!authCodeGrant) {
281
288
  throw new CredentialOfferError("authorization_code grant not found");
282
289
  }
290
+ return authCodeGrant;
291
+ }
292
+ function extractGrantDetailsV1_3(options) {
293
+ const authCodeGrant = requireAuthorizationCodeGrant(options.credentialOffer);
283
294
  return {
284
295
  authorizationCodeGrant: {
285
296
  authorizationServer: authCodeGrant.authorization_server,
@@ -289,10 +300,37 @@ function extractGrantDetails(credentialOffer) {
289
300
  grantType: "authorization_code"
290
301
  };
291
302
  }
303
+ function extractGrantDetailsV1_4(options) {
304
+ const authCodeGrant = requireAuthorizationCodeGrant(options.credentialOffer);
305
+ return {
306
+ authorizationCodeGrant: {
307
+ authorizationServer: authCodeGrant.authorization_server,
308
+ issuerState: authCodeGrant.issuer_state
309
+ },
310
+ grantType: "authorization_code"
311
+ };
312
+ }
313
+ var dispatchExtractGrantDetails = (0, import_io_wallet_utils2.createVersionDispatcher)({
314
+ [import_io_wallet_utils2.ItWalletSpecsVersion.V1_0]: () => {
315
+ throw new import_io_wallet_utils2.ItWalletSpecsVersionError(
316
+ "extractGrantDetails",
317
+ import_io_wallet_utils2.ItWalletSpecsVersion.V1_0,
318
+ [import_io_wallet_utils2.ItWalletSpecsVersion.V1_3, import_io_wallet_utils2.ItWalletSpecsVersion.V1_4]
319
+ );
320
+ },
321
+ [import_io_wallet_utils2.ItWalletSpecsVersion.V1_3]: (o) => extractGrantDetailsV1_3(o),
322
+ [import_io_wallet_utils2.ItWalletSpecsVersion.V1_4]: (o) => extractGrantDetailsV1_4(o)
323
+ });
324
+ function extractGrantDetails(options) {
325
+ return dispatchExtractGrantDetails(options);
326
+ }
292
327
 
293
328
  // src/credential-offer/z-credential-offer.ts
329
+ var import_zod4 = require("zod");
330
+
331
+ // src/credential-offer/v1.3/z-credential-offer.ts
294
332
  var import_zod2 = require("zod");
295
- var zAuthorizationCodeGrant = import_zod2.z.object({
333
+ var zAuthorizationCodeGrantV1_3 = import_zod2.z.object({
296
334
  /**
297
335
  * CONDITIONALLY REQUIRED. HTTPS URL of the Authorization Server.
298
336
  * REQUIRED only when the Credential Issuer uses multiple Authorization Servers.
@@ -310,14 +348,14 @@ var zAuthorizationCodeGrant = import_zod2.z.object({
310
348
  */
311
349
  scope: import_zod2.z.string()
312
350
  });
313
- var zCredentialOfferGrants = import_zod2.z.object({
351
+ var zCredentialOfferGrantsV1_3 = import_zod2.z.object({
314
352
  /**
315
353
  * REQUIRED. Authorization Code grant details.
316
354
  * IT-Wallet v1.3 only supports authorization_code grant.
317
355
  */
318
- authorization_code: zAuthorizationCodeGrant
356
+ authorization_code: zAuthorizationCodeGrantV1_3
319
357
  });
320
- var zCredentialOffer = import_zod2.z.object({
358
+ var zCredentialOfferV1_3 = import_zod2.z.object({
321
359
  /**
322
360
  * REQUIRED. Array of credential configuration identifiers.
323
361
  * References the types of credentials offered as defined in the Credential Issuer metadata.
@@ -332,24 +370,66 @@ var zCredentialOffer = import_zod2.z.object({
332
370
  * REQUIRED. Grant information for the credential offer.
333
371
  * IT-Wallet v1.3 requires authorization_code grant.
334
372
  */
335
- grants: zCredentialOfferGrants
373
+ grants: zCredentialOfferGrantsV1_3
374
+ });
375
+
376
+ // src/credential-offer/v1.4/z-credential-offer.ts
377
+ var import_zod3 = require("zod");
378
+ var zAuthorizationCodeGrantV1_4 = import_zod3.z.object({
379
+ /**
380
+ * CONDITIONALLY REQUIRED. HTTPS URL of the Authorization Server.
381
+ * REQUIRED only when the Credential Issuer uses multiple Authorization Servers.
382
+ * If present, MUST match one of the authorization_servers in the Credential Issuer metadata.
383
+ */
384
+ authorization_server: import_zod3.z.url().optional(),
385
+ /**
386
+ * OPTIONAL. String value representing the issuer state.
387
+ * Used to correlate the authorization request with the credential offer.
388
+ */
389
+ issuer_state: import_zod3.z.string().optional()
390
+ });
391
+ var zCredentialOfferGrantsV1_4 = import_zod3.z.object({
392
+ /**
393
+ * REQUIRED. Authorization Code grant details.
394
+ * IT-Wallet v1.4 only supports authorization_code grant.
395
+ */
396
+ authorization_code: zAuthorizationCodeGrantV1_4
397
+ });
398
+ var zCredentialOfferV1_4 = import_zod3.z.object({
399
+ /**
400
+ * REQUIRED. Array of credential configuration identifiers.
401
+ * References the types of credentials offered as defined in the Credential Issuer metadata.
402
+ */
403
+ credential_configuration_ids: import_zod3.z.array(import_zod3.z.string()).min(1),
404
+ /**
405
+ * REQUIRED. HTTPS URL of the Credential Issuer.
406
+ * The Credential Issuer from which the wallet will request credentials.
407
+ */
408
+ credential_issuer: import_zod3.z.url(),
409
+ /**
410
+ * REQUIRED. Grant information for the credential offer.
411
+ * IT-Wallet v1.4 requires authorization_code grant.
412
+ */
413
+ grants: zCredentialOfferGrantsV1_4
336
414
  });
337
- var zCredentialOfferUri = import_zod2.z.object({
415
+
416
+ // src/credential-offer/z-credential-offer.ts
417
+ var zCredentialOfferUri = import_zod4.z.object({
338
418
  /**
339
419
  * OPTIONAL. Inline credential offer JSON (by value).
340
420
  * URL-encoded JSON string containing the credential offer.
341
421
  */
342
- credential_offer: import_zod2.z.string().optional(),
422
+ credential_offer: import_zod4.z.string().optional(),
343
423
  /**
344
424
  * OPTIONAL. URL pointing to the credential offer JSON (by reference).
345
425
  * HTTPS URL where the credential offer can be fetched.
346
426
  */
347
- credential_offer_uri: import_zod2.z.url().optional(),
427
+ credential_offer_uri: import_zod4.z.url().optional(),
348
428
  /**
349
429
  * URL scheme used for the credential offer.
350
430
  * Determines the invocation method.
351
431
  */
352
- scheme: import_zod2.z.enum(["openid-credential-offer", "haip-vci", "https"])
432
+ scheme: import_zod4.z.enum(["openid-credential-offer", "haip-vci", "https"])
353
433
  }).refine((data) => data.credential_offer || data.credential_offer_uri, {
354
434
  message: "Either credential_offer or credential_offer_uri must be present"
355
435
  });
@@ -387,34 +467,48 @@ async function parseCredentialOfferUri(options) {
387
467
  }
388
468
 
389
469
  // src/credential-offer/resolve-credential-offer.ts
390
- var import_io_wallet_utils2 = require("@pagopa/io-wallet-utils");
470
+ var import_io_wallet_utils3 = require("@pagopa/io-wallet-utils");
471
+ function parseCredentialOfferForVersion(config, data) {
472
+ switch (config.itWalletSpecsVersion) {
473
+ case import_io_wallet_utils3.ItWalletSpecsVersion.V1_3:
474
+ return zCredentialOfferV1_3.parse(data);
475
+ case import_io_wallet_utils3.ItWalletSpecsVersion.V1_4:
476
+ return zCredentialOfferV1_4.parse(data);
477
+ default:
478
+ throw new import_io_wallet_utils3.ItWalletSpecsVersionError(
479
+ "resolveCredentialOffer",
480
+ config.itWalletSpecsVersion,
481
+ [import_io_wallet_utils3.ItWalletSpecsVersion.V1_3, import_io_wallet_utils3.ItWalletSpecsVersion.V1_4]
482
+ );
483
+ }
484
+ }
391
485
  async function resolveCredentialOffer(options) {
392
- const { callbacks, credentialOffer } = options;
486
+ const { callbacks, config, credentialOffer } = options;
393
487
  try {
394
488
  if (credentialOffer.startsWith("openid-credential-offer://") || credentialOffer.startsWith("haip-vci://") || credentialOffer.startsWith("https://")) {
395
489
  const parsed = await parseCredentialOfferUri({ uri: credentialOffer });
396
490
  if (parsed.credential_offer) {
397
491
  const decoded = decodeURIComponent(parsed.credential_offer);
398
492
  const offerJson2 = JSON.parse(decoded);
399
- return zCredentialOffer.parse(offerJson2);
493
+ return parseCredentialOfferForVersion(config, offerJson2);
400
494
  }
401
495
  if (parsed.credential_offer_uri) {
402
- const fetch = (0, import_io_wallet_utils2.createFetcher)(callbacks.fetch);
496
+ const fetch = (0, import_io_wallet_utils3.createFetcher)(callbacks.fetch);
403
497
  const response = await fetch(parsed.credential_offer_uri, {
404
498
  headers: {
405
499
  Accept: "application/json"
406
500
  },
407
501
  method: "GET"
408
502
  });
409
- await (0, import_io_wallet_utils2.hasStatusOrThrow)(200, import_io_wallet_utils2.UnexpectedStatusCodeError)(response);
503
+ await (0, import_io_wallet_utils3.hasStatusOrThrow)(200, import_io_wallet_utils3.UnexpectedStatusCodeError)(response);
410
504
  const offerJson2 = await response.json();
411
- return zCredentialOffer.parse(offerJson2);
505
+ return parseCredentialOfferForVersion(config, offerJson2);
412
506
  }
413
507
  }
414
508
  const offerJson = JSON.parse(credentialOffer);
415
- return zCredentialOffer.parse(offerJson);
509
+ return parseCredentialOfferForVersion(config, offerJson);
416
510
  } catch (error) {
417
- if (error instanceof CredentialOfferError || error instanceof import_io_wallet_utils2.UnexpectedStatusCodeError) {
511
+ if (error instanceof CredentialOfferError || error instanceof import_io_wallet_utils3.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils3.ItWalletSpecsVersionError) {
418
512
  throw error;
419
513
  }
420
514
  throw new CredentialOfferError(
@@ -424,8 +518,34 @@ async function resolveCredentialOffer(options) {
424
518
  }
425
519
 
426
520
  // src/credential-offer/validate-credential-offer.ts
427
- async function validateCredentialOffer(options) {
428
- const { credentialIssuerMetadata, credentialOffer } = options;
521
+ var import_io_wallet_utils4 = require("@pagopa/io-wallet-utils");
522
+ function assertAuthorizationServerAllowed(authorizationServer, authorizationServers) {
523
+ if (!authorizationServer) {
524
+ if (authorizationServers && authorizationServers.length > 1) {
525
+ throw new CredentialOfferError(
526
+ "authorization_server is REQUIRED when Credential Issuer uses multiple Authorization Servers"
527
+ );
528
+ }
529
+ return;
530
+ }
531
+ if (!authorizationServers) {
532
+ throw new CredentialOfferError(
533
+ "credential offer specified an `authorization_server` but issuer metadata doesn't contain `authorization_servers`"
534
+ );
535
+ }
536
+ if (authorizationServers.length === 1) {
537
+ throw new CredentialOfferError(
538
+ "credential offer specified an `authorization_server` but issuer metadata's `authorization_servers` contains only an element"
539
+ );
540
+ }
541
+ if (!authorizationServers.includes(authorizationServer)) {
542
+ throw new CredentialOfferError(
543
+ `authorization_server '${authorizationServer}' does not match Credential Issuer metadata. Valid servers: ${authorizationServers.join(", ")}`
544
+ );
545
+ }
546
+ }
547
+ function validateBaseCredentialOffer(options) {
548
+ const { credentialIssuerMetadata, credentialOffer, versionLabel } = options;
429
549
  if (!credentialOffer.credential_issuer.startsWith("https://")) {
430
550
  throw new CredentialOfferError("credential_issuer must be an HTTPS URL");
431
551
  }
@@ -435,53 +555,72 @@ async function validateCredentialOffer(options) {
435
555
  );
436
556
  }
437
557
  if (!credentialOffer.grants) {
438
- throw new CredentialOfferError("grants is REQUIRED for IT-Wallet v1.3");
558
+ throw new CredentialOfferError(
559
+ `grants is REQUIRED for IT-Wallet ${versionLabel}`
560
+ );
439
561
  }
440
562
  const authCodeGrant = credentialOffer.grants.authorization_code;
441
563
  if (!authCodeGrant) {
442
564
  throw new CredentialOfferError(
443
- "authorization_code grant is REQUIRED for IT-Wallet v1.3"
565
+ `authorization_code grant is REQUIRED for IT-Wallet ${versionLabel}`
444
566
  );
445
567
  }
446
- if (!authCodeGrant.scope) {
568
+ assertAuthorizationServerAllowed(
569
+ authCodeGrant.authorization_server,
570
+ credentialIssuerMetadata?.authorization_servers
571
+ );
572
+ }
573
+ async function validateCredentialOfferV1_3(options) {
574
+ validateBaseCredentialOffer({
575
+ credentialIssuerMetadata: options.credentialIssuerMetadata,
576
+ credentialOffer: options.credentialOffer,
577
+ versionLabel: "v1.3"
578
+ });
579
+ if (!options.credentialOffer.grants.authorization_code.scope) {
447
580
  throw new CredentialOfferError("authorization_code.scope is REQUIRED");
448
581
  }
449
- if (credentialIssuerMetadata?.authorization_servers) {
450
- const authServers = credentialIssuerMetadata.authorization_servers;
451
- if (authServers.length > 1 && !authCodeGrant.authorization_server) {
452
- throw new CredentialOfferError(
453
- "authorization_server is REQUIRED when Credential Issuer uses multiple Authorization Servers"
454
- );
455
- }
456
- if (authCodeGrant.authorization_server) {
457
- if (!authServers.includes(authCodeGrant.authorization_server)) {
458
- throw new CredentialOfferError(
459
- `authorization_server '${authCodeGrant.authorization_server}' does not match Credential Issuer metadata. Valid servers: ${authServers.join(", ")}`
460
- );
461
- }
462
- }
463
- }
582
+ }
583
+ async function validateCredentialOfferV1_4(options) {
584
+ validateBaseCredentialOffer({
585
+ credentialIssuerMetadata: options.credentialIssuerMetadata,
586
+ credentialOffer: options.credentialOffer,
587
+ versionLabel: "v1.4"
588
+ });
589
+ }
590
+ var dispatchValidateCredentialOffer = (0, import_io_wallet_utils4.createVersionDispatcher)({
591
+ [import_io_wallet_utils4.ItWalletSpecsVersion.V1_0]: () => {
592
+ throw new import_io_wallet_utils4.ItWalletSpecsVersionError(
593
+ "validateCredentialOffer",
594
+ import_io_wallet_utils4.ItWalletSpecsVersion.V1_0,
595
+ [import_io_wallet_utils4.ItWalletSpecsVersion.V1_3, import_io_wallet_utils4.ItWalletSpecsVersion.V1_4]
596
+ );
597
+ },
598
+ [import_io_wallet_utils4.ItWalletSpecsVersion.V1_3]: (o) => validateCredentialOfferV1_3(o),
599
+ [import_io_wallet_utils4.ItWalletSpecsVersion.V1_4]: (o) => validateCredentialOfferV1_4(o)
600
+ });
601
+ async function validateCredentialOffer(options) {
602
+ return dispatchValidateCredentialOffer(options);
464
603
  }
465
604
 
466
605
  // src/credential-request/create-credential-request.ts
467
- var import_io_wallet_utils5 = require("@pagopa/io-wallet-utils");
606
+ var import_io_wallet_utils7 = require("@pagopa/io-wallet-utils");
468
607
 
469
608
  // src/credential-request/v1.0/create-credential-request.ts
470
- var import_io_wallet_utils3 = require("@pagopa/io-wallet-utils");
609
+ var import_io_wallet_utils5 = require("@pagopa/io-wallet-utils");
471
610
 
472
611
  // src/credential-request/v1.0/z-credential.ts
473
- var import_zod4 = require("zod");
612
+ var import_zod6 = require("zod");
474
613
 
475
614
  // src/credential-request/z-base-credential-request.ts
476
- var import_zod3 = require("zod");
477
- var zBaseCredentialRequest = import_zod3.z.object({
478
- credential_configuration_id: import_zod3.z.string().optional().describe(
615
+ var import_zod5 = require("zod");
616
+ var zBaseCredentialRequest = import_zod5.z.object({
617
+ credential_configuration_id: import_zod5.z.string().optional().describe(
479
618
  "REQUIRED if credential_identifier param is absent. MUST NOT be used otherwise."
480
619
  ),
481
- credential_identifier: import_zod3.z.string().optional().describe(
620
+ credential_identifier: import_zod5.z.string().optional().describe(
482
621
  "REQUIRED when Authorization Details of type openid_credential was returned. MUST NOT be used if credential_configuration_id is present."
483
622
  ),
484
- transaction_id: import_zod3.z.string().optional().describe(
623
+ transaction_id: import_zod5.z.string().optional().describe(
485
624
  "REQUIRED only in case of deferred flow. MUST NOT be present in immediate flow."
486
625
  )
487
626
  });
@@ -503,9 +642,9 @@ function credentialRequestRefiner(data, ctx) {
503
642
  }
504
643
 
505
644
  // src/credential-request/v1.0/z-credential.ts
506
- var zCredentialRequestProof = import_zod4.z.object({
507
- jwt: import_zod4.z.string().min(1, "JWT must not be empty"),
508
- proof_type: import_zod4.z.literal("jwt")
645
+ var zCredentialRequestProof = import_zod6.z.object({
646
+ jwt: import_zod6.z.string().min(1, "JWT must not be empty"),
647
+ proof_type: import_zod6.z.literal("jwt")
509
648
  // MUST be "jwt"
510
649
  });
511
650
  var zCredentialRequestV1_0 = zBaseCredentialRequest.extend({
@@ -528,12 +667,12 @@ var createCredentialRequest = async (options) => {
528
667
  },
529
668
  payload: {
530
669
  aud: options.issuerIdentifier,
531
- iat: (0, import_io_wallet_utils3.dateToSeconds)(/* @__PURE__ */ new Date()),
670
+ iat: (0, import_io_wallet_utils5.dateToSeconds)(/* @__PURE__ */ new Date()),
532
671
  iss: options.clientId,
533
672
  nonce: options.nonce
534
673
  }
535
674
  });
536
- return (0, import_io_wallet_utils3.parseWithErrorHandling)(zCredentialRequestV1_0, {
675
+ return (0, import_io_wallet_utils5.parseWithErrorHandling)(zCredentialRequestV1_0, {
537
676
  credential_identifier: options.credential_identifier,
538
677
  proof: {
539
678
  jwt: proofJwt.jwt,
@@ -541,7 +680,7 @@ var createCredentialRequest = async (options) => {
541
680
  }
542
681
  });
543
682
  } catch (error) {
544
- if (error instanceof import_io_wallet_utils3.ValidationError) {
683
+ if (error instanceof import_io_wallet_utils5.ValidationError) {
545
684
  throw error;
546
685
  }
547
686
  throw new Oid4vciError(
@@ -552,13 +691,13 @@ var createCredentialRequest = async (options) => {
552
691
 
553
692
  // src/credential-request/v1.3/create-credential-request.ts
554
693
  var import_oauth22 = require("@openid4vc/oauth2");
555
- var import_io_wallet_utils4 = require("@pagopa/io-wallet-utils");
694
+ var import_io_wallet_utils6 = require("@pagopa/io-wallet-utils");
556
695
 
557
696
  // src/credential-request/v1.3/z-credential.ts
558
- var import_zod5 = require("zod");
559
- var zCredentialRequestProofJwt = import_zod5.z.string().min(1, "JWT must not be empty in credential request proofs array");
560
- var zCredentialRequestProofs = import_zod5.z.object({
561
- jwt: import_zod5.z.tuple([zCredentialRequestProofJwt], zCredentialRequestProofJwt)
697
+ var import_zod7 = require("zod");
698
+ var zCredentialRequestProofJwt = import_zod7.z.string().min(1, "JWT must not be empty in credential request proofs array");
699
+ var zCredentialRequestProofs = import_zod7.z.object({
700
+ jwt: import_zod7.z.tuple([zCredentialRequestProofJwt], zCredentialRequestProofJwt)
562
701
  });
563
702
  var zCredentialRequestV1_3 = zBaseCredentialRequest.extend({
564
703
  proofs: zCredentialRequestProofs.describe(
@@ -574,16 +713,16 @@ var createCredentialRequest2 = async (options) => {
574
713
  const { maxBatchSize, signers } = options;
575
714
  const [firstSigner, ...otherSigners] = signers;
576
715
  if (!firstSigner) {
577
- throw new import_io_wallet_utils4.ValidationError("At least one signer is required");
716
+ throw new import_io_wallet_utils6.ValidationError("At least one signer is required");
578
717
  }
579
718
  if (maxBatchSize !== void 0) {
580
719
  if (!Number.isInteger(maxBatchSize) || maxBatchSize <= 0) {
581
- throw new import_io_wallet_utils4.ValidationError(
720
+ throw new import_io_wallet_utils6.ValidationError(
582
721
  "Invalid maxBatchSize: it must be a positive integer"
583
722
  );
584
723
  }
585
724
  if (signers.length > maxBatchSize) {
586
- throw new import_io_wallet_utils4.ValidationError(
725
+ throw new import_io_wallet_utils6.ValidationError(
587
726
  "The number of provided signers exceeds the maximum batch size allowed"
588
727
  );
589
728
  }
@@ -601,7 +740,7 @@ var createCredentialRequest2 = async (options) => {
601
740
  );
602
741
  const uniqueThumbprints = new Set(allThumbprints);
603
742
  if (uniqueThumbprints.size !== allThumbprints.length) {
604
- throw new import_io_wallet_utils4.ValidationError(
743
+ throw new import_io_wallet_utils6.ValidationError(
605
744
  "Found multiple signers with the same JWK: each JWT proof must be unique and linked to a different credential key pair"
606
745
  );
607
746
  }
@@ -615,7 +754,7 @@ var createCredentialRequest2 = async (options) => {
615
754
  },
616
755
  payload: {
617
756
  aud: options.issuerIdentifier,
618
- iat: (0, import_io_wallet_utils4.dateToSeconds)(/* @__PURE__ */ new Date()),
757
+ iat: (0, import_io_wallet_utils6.dateToSeconds)(/* @__PURE__ */ new Date()),
619
758
  iss: options.clientId,
620
759
  nonce: options.nonce
621
760
  }
@@ -624,14 +763,14 @@ var createCredentialRequest2 = async (options) => {
624
763
  createProofJwt(firstSigner),
625
764
  ...otherSigners.map(createProofJwt)
626
765
  ]);
627
- return (0, import_io_wallet_utils4.parseWithErrorHandling)(zCredentialRequestV1_3, {
766
+ return (0, import_io_wallet_utils6.parseWithErrorHandling)(zCredentialRequestV1_3, {
628
767
  credential_identifier: options.credential_identifier,
629
768
  proofs: {
630
769
  jwt: proofJwts
631
770
  }
632
771
  });
633
772
  } catch (error) {
634
- if (error instanceof import_io_wallet_utils4.ValidationError) {
773
+ if (error instanceof import_io_wallet_utils6.ValidationError) {
635
774
  throw error;
636
775
  }
637
776
  throw new Oid4vciError(
@@ -641,10 +780,10 @@ var createCredentialRequest2 = async (options) => {
641
780
  };
642
781
 
643
782
  // src/credential-request/create-credential-request.ts
644
- var dispatchCreateCredentialRequest = (0, import_io_wallet_utils5.createVersionDispatcher)({
645
- [import_io_wallet_utils5.ItWalletSpecsVersion.V1_0]: (o) => createCredentialRequest(o),
646
- [import_io_wallet_utils5.ItWalletSpecsVersion.V1_3]: (o) => createCredentialRequest2(o),
647
- [import_io_wallet_utils5.ItWalletSpecsVersion.V1_4]: (o) => (
783
+ var dispatchCreateCredentialRequest = (0, import_io_wallet_utils7.createVersionDispatcher)({
784
+ [import_io_wallet_utils7.ItWalletSpecsVersion.V1_0]: (o) => createCredentialRequest(o),
785
+ [import_io_wallet_utils7.ItWalletSpecsVersion.V1_3]: (o) => createCredentialRequest2(o),
786
+ [import_io_wallet_utils7.ItWalletSpecsVersion.V1_4]: (o) => (
648
787
  // V1_4 reuses V1_3 credential request schema — no breaking changes between versions.
649
788
  // Verified against compare/1.3.3...1.4.1: credential request parameters (format, proofs, key_attestation) identical.
650
789
  createCredentialRequest2(o)
@@ -656,25 +795,25 @@ async function createCredentialRequest3(options) {
656
795
 
657
796
  // src/credential-request/parse-credential-request.ts
658
797
  var import_io_wallet_oauth23 = require("@pagopa/io-wallet-oauth2");
659
- var import_io_wallet_utils6 = require("@pagopa/io-wallet-utils");
798
+ var import_io_wallet_utils8 = require("@pagopa/io-wallet-utils");
660
799
 
661
800
  // src/credential-request/z-proof-jwt.ts
662
801
  var import_io_wallet_oauth22 = require("@pagopa/io-wallet-oauth2");
663
- var import_zod6 = require("zod");
664
- var zBaseProofJwtHeader = import_zod6.z.object({
665
- alg: import_zod6.z.string().min(1),
802
+ var import_zod8 = require("zod");
803
+ var zBaseProofJwtHeader = import_zod8.z.object({
804
+ alg: import_zod8.z.string().min(1),
666
805
  jwk: import_io_wallet_oauth22.zJwk,
667
- typ: import_zod6.z.literal("openid4vci-proof+jwt")
806
+ typ: import_zod8.z.literal("openid4vci-proof+jwt")
668
807
  });
669
808
  var zProofJwtHeaderV1_0 = zBaseProofJwtHeader.loose();
670
809
  var zProofJwtHeaderV1_3 = zBaseProofJwtHeader.extend({
671
- key_attestation: import_zod6.z.string().min(1)
810
+ key_attestation: import_zod8.z.string().min(1)
672
811
  }).loose();
673
- var zProofJwtPayload = import_zod6.z.looseObject({
674
- aud: import_zod6.z.string().min(1),
675
- iat: import_zod6.z.number(),
676
- iss: import_zod6.z.string().min(1).optional(),
677
- nonce: import_zod6.z.string().min(1)
812
+ var zProofJwtPayload = import_zod8.z.looseObject({
813
+ aud: import_zod8.z.string().min(1),
814
+ iat: import_zod8.z.number(),
815
+ iss: import_zod8.z.string().min(1).optional(),
816
+ nonce: import_zod8.z.string().min(1)
678
817
  });
679
818
 
680
819
  // src/credential-request/parse-credential-request.ts
@@ -683,12 +822,12 @@ function validateExpectedValues(credentialRequest, expected) {
683
822
  return;
684
823
  }
685
824
  if (expected.credential_identifier && credentialRequest.credential_identifier !== expected.credential_identifier) {
686
- throw new import_io_wallet_utils6.ValidationError(
825
+ throw new import_io_wallet_utils8.ValidationError(
687
826
  "credential_identifier does not match expected value"
688
827
  );
689
828
  }
690
829
  if (expected.credential_configuration_id && credentialRequest.credential_configuration_id !== expected.credential_configuration_id) {
691
- throw new import_io_wallet_utils6.ValidationError(
830
+ throw new import_io_wallet_utils8.ValidationError(
692
831
  "credential_configuration_id does not match expected value"
693
832
  );
694
833
  }
@@ -696,12 +835,12 @@ function validateExpectedValues(credentialRequest, expected) {
696
835
  function validateTransactionContext(options) {
697
836
  const { credentialRequest, isDeferredFlow } = options;
698
837
  if (isDeferredFlow && !credentialRequest.transaction_id) {
699
- throw new import_io_wallet_utils6.ValidationError(
838
+ throw new import_io_wallet_utils8.ValidationError(
700
839
  "transaction_id is required for deferred credential issuance"
701
840
  );
702
841
  }
703
842
  if (!isDeferredFlow && credentialRequest.transaction_id) {
704
- throw new import_io_wallet_utils6.ValidationError(
843
+ throw new import_io_wallet_utils8.ValidationError(
705
844
  "transaction_id must not be present in immediate credential issuance flow"
706
845
  );
707
846
  }
@@ -709,27 +848,27 @@ function validateTransactionContext(options) {
709
848
  function validateProofPayloadSemantics(options) {
710
849
  const { expected, grantType, payload } = options;
711
850
  if (grantType === "authorization_code" && !payload.iss) {
712
- throw new import_io_wallet_utils6.ValidationError(
851
+ throw new import_io_wallet_utils8.ValidationError(
713
852
  "Credential proof JWT payload must include iss for authorization_code grant"
714
853
  );
715
854
  }
716
855
  if (expected?.audience && payload.aud !== expected.audience) {
717
- throw new import_io_wallet_utils6.ValidationError(
856
+ throw new import_io_wallet_utils8.ValidationError(
718
857
  "Credential proof JWT aud does not match expected audience"
719
858
  );
720
859
  }
721
860
  if (expected?.nonce && payload.nonce !== expected.nonce) {
722
- throw new import_io_wallet_utils6.ValidationError(
861
+ throw new import_io_wallet_utils8.ValidationError(
723
862
  "Credential proof JWT nonce does not match expected nonce"
724
863
  );
725
864
  }
726
865
  if (expected?.issuer && payload.iss && payload.iss !== expected.issuer) {
727
- throw new import_io_wallet_utils6.ValidationError(
866
+ throw new import_io_wallet_utils8.ValidationError(
728
867
  "Credential proof JWT iss does not match expected issuer"
729
868
  );
730
869
  }
731
870
  if (grantType === "authorization_code" && expected?.issuer && !payload.iss) {
732
- throw new import_io_wallet_utils6.ValidationError(
871
+ throw new import_io_wallet_utils8.ValidationError(
733
872
  "Credential proof JWT payload is missing expected issuer (iss)"
734
873
  );
735
874
  }
@@ -739,15 +878,15 @@ function parseProofJwt(options) {
739
878
  errorMessagePrefix: "Error decoding credential request proof JWT:",
740
879
  jwt: options.jwt
741
880
  });
742
- const headerValidation = options.itWalletSpecsVersion === import_io_wallet_utils6.ItWalletSpecsVersion.V1_3 || options.itWalletSpecsVersion === import_io_wallet_utils6.ItWalletSpecsVersion.V1_4 ? zProofJwtHeaderV1_3.safeParse(decoded.header) : zProofJwtHeaderV1_0.safeParse(decoded.header);
881
+ const headerValidation = options.itWalletSpecsVersion === import_io_wallet_utils8.ItWalletSpecsVersion.V1_3 || options.itWalletSpecsVersion === import_io_wallet_utils8.ItWalletSpecsVersion.V1_4 ? zProofJwtHeaderV1_3.safeParse(decoded.header) : zProofJwtHeaderV1_0.safeParse(decoded.header);
743
882
  if (!headerValidation.success) {
744
- throw new import_io_wallet_utils6.ValidationError(
883
+ throw new import_io_wallet_utils8.ValidationError(
745
884
  "Credential proof JWT header is invalid or missing required claims"
746
885
  );
747
886
  }
748
887
  const payloadValidation = zProofJwtPayload.safeParse(decoded.payload);
749
888
  if (!payloadValidation.success) {
750
- throw new import_io_wallet_utils6.ValidationError(
889
+ throw new import_io_wallet_utils8.ValidationError(
751
890
  "Credential proof JWT payload is invalid or missing required claims"
752
891
  );
753
892
  }
@@ -764,7 +903,27 @@ function parseProofJwt(options) {
764
903
  proofType: "jwt"
765
904
  };
766
905
  }
767
- function normalizeProofs(options) {
906
+ async function validateProofJwkUniqueness(options) {
907
+ if (options.proofs.length <= 1) {
908
+ return;
909
+ }
910
+ const thumbprints = await Promise.all(
911
+ options.proofs.map(
912
+ (proof) => (0, import_io_wallet_utils8.calculateJwkThumbprint)({
913
+ hashAlgorithm: import_io_wallet_utils8.HashAlgorithm.Sha256,
914
+ hashCallback: options.callbacks.hash,
915
+ jwk: proof.header.jwk
916
+ })
917
+ )
918
+ );
919
+ const uniqueThumbprints = new Set(thumbprints);
920
+ if (uniqueThumbprints.size !== thumbprints.length) {
921
+ throw new import_io_wallet_utils8.ValidationError(
922
+ "Credential request proofs must use unique jwk header values"
923
+ );
924
+ }
925
+ }
926
+ async function normalizeProofs(options) {
768
927
  if ("proof" in options.credentialRequest) {
769
928
  return [
770
929
  parseProofJwt({
@@ -775,7 +934,7 @@ function normalizeProofs(options) {
775
934
  })
776
935
  ];
777
936
  }
778
- return options.credentialRequest.proofs.jwt.map(
937
+ const proofs = options.credentialRequest.proofs.jwt.map(
779
938
  (jwt) => parseProofJwt({
780
939
  expected: options.expected,
781
940
  grantType: options.grantType,
@@ -783,14 +942,20 @@ function normalizeProofs(options) {
783
942
  jwt
784
943
  })
785
944
  );
945
+ await validateProofJwkUniqueness({
946
+ callbacks: options.callbacks,
947
+ proofs
948
+ });
949
+ return proofs;
786
950
  }
787
- function toResult(options) {
951
+ async function toResult(options) {
788
952
  validateExpectedValues(options.credentialRequest, options.expected);
789
953
  validateTransactionContext({
790
954
  credentialRequest: options.credentialRequest,
791
955
  isDeferredFlow: options.isDeferredFlow
792
956
  });
793
- const proofs = normalizeProofs({
957
+ const proofs = await normalizeProofs({
958
+ callbacks: options.callbacks,
794
959
  credentialRequest: options.credentialRequest,
795
960
  expected: options.expected,
796
961
  grantType: options.grantType,
@@ -813,7 +978,7 @@ function toResult(options) {
813
978
  };
814
979
  }
815
980
  function parseAuthorizationHeader(headers) {
816
- const authorizationHeader = headers.get(import_io_wallet_utils6.HEADERS.AUTHORIZATION)?.trim();
981
+ const authorizationHeader = headers.get(import_io_wallet_utils8.HEADERS.AUTHORIZATION)?.trim();
817
982
  if (!authorizationHeader) {
818
983
  throw new CredentialAuthorizationHeaderError(
819
984
  "Credential request is missing required 'Authorization' header with DPoP scheme"
@@ -842,66 +1007,69 @@ function parseDpopProof(headers) {
842
1007
  return extracted.dpopJwt;
843
1008
  }
844
1009
  function parseCredentialRequestV1_0(options) {
845
- const credentialRequest = (0, import_io_wallet_utils6.parseWithErrorHandling)(
1010
+ const credentialRequest = (0, import_io_wallet_utils8.parseWithErrorHandling)(
846
1011
  zCredentialRequestV1_0,
847
1012
  options.credentialRequest,
848
1013
  "Invalid credential request format for ItWalletSpecsVersion 1.0"
849
1014
  );
850
1015
  return toResult({
851
1016
  accessToken: options.accessToken,
1017
+ callbacks: options.callbacks,
852
1018
  credentialRequest,
853
1019
  dpopProof: options.dpopProof,
854
1020
  expected: options.expected,
855
1021
  grantType: options.grantType,
856
1022
  isDeferredFlow: options.isDeferredFlow,
857
- itWalletSpecsVersion: import_io_wallet_utils6.ItWalletSpecsVersion.V1_0
1023
+ itWalletSpecsVersion: import_io_wallet_utils8.ItWalletSpecsVersion.V1_0
858
1024
  });
859
1025
  }
860
1026
  function parseCredentialRequestV1_3(options) {
861
- const credentialRequest = (0, import_io_wallet_utils6.parseWithErrorHandling)(
1027
+ const credentialRequest = (0, import_io_wallet_utils8.parseWithErrorHandling)(
862
1028
  zCredentialRequestV1_3,
863
1029
  options.credentialRequest,
864
1030
  "Invalid credential request format for ItWalletSpecsVersion 1.3"
865
1031
  );
866
1032
  return toResult({
867
1033
  accessToken: options.accessToken,
1034
+ callbacks: options.callbacks,
868
1035
  credentialRequest,
869
1036
  dpopProof: options.dpopProof,
870
1037
  expected: options.expected,
871
1038
  grantType: options.grantType,
872
1039
  isDeferredFlow: options.isDeferredFlow,
873
- itWalletSpecsVersion: import_io_wallet_utils6.ItWalletSpecsVersion.V1_3
1040
+ itWalletSpecsVersion: import_io_wallet_utils8.ItWalletSpecsVersion.V1_3
874
1041
  });
875
1042
  }
876
1043
  function parseCredentialRequestV1_4(options) {
877
- const credentialRequest = (0, import_io_wallet_utils6.parseWithErrorHandling)(
1044
+ const credentialRequest = (0, import_io_wallet_utils8.parseWithErrorHandling)(
878
1045
  zCredentialRequestV1_3,
879
1046
  options.credentialRequest,
880
1047
  "Invalid credential request format for ItWalletSpecsVersion 1.4"
881
1048
  );
882
1049
  return toResult({
883
1050
  accessToken: options.accessToken,
1051
+ callbacks: options.callbacks,
884
1052
  credentialRequest,
885
1053
  dpopProof: options.dpopProof,
886
1054
  expected: options.expected,
887
1055
  grantType: options.grantType,
888
1056
  isDeferredFlow: options.isDeferredFlow,
889
- itWalletSpecsVersion: import_io_wallet_utils6.ItWalletSpecsVersion.V1_4
1057
+ itWalletSpecsVersion: import_io_wallet_utils8.ItWalletSpecsVersion.V1_4
890
1058
  // V1_4 reuses V1_3 proof schema
891
1059
  });
892
1060
  }
893
- var dispatchParseCredentialRequest = (0, import_io_wallet_utils6.createVersionDispatcher)({
894
- [import_io_wallet_utils6.ItWalletSpecsVersion.V1_0]: parseCredentialRequestV1_0,
895
- [import_io_wallet_utils6.ItWalletSpecsVersion.V1_3]: parseCredentialRequestV1_3,
896
- [import_io_wallet_utils6.ItWalletSpecsVersion.V1_4]: parseCredentialRequestV1_4
1061
+ var dispatchParseCredentialRequest = (0, import_io_wallet_utils8.createVersionDispatcher)({
1062
+ [import_io_wallet_utils8.ItWalletSpecsVersion.V1_0]: parseCredentialRequestV1_0,
1063
+ [import_io_wallet_utils8.ItWalletSpecsVersion.V1_3]: parseCredentialRequestV1_3,
1064
+ [import_io_wallet_utils8.ItWalletSpecsVersion.V1_4]: parseCredentialRequestV1_4
897
1065
  });
898
- function parseCredentialRequest(options) {
1066
+ async function parseCredentialRequest(options) {
899
1067
  const grantType = options.grantType ?? "authorization_code";
900
1068
  const isDeferredFlow = options.isDeferredFlow ?? false;
901
1069
  try {
902
1070
  const accessToken = parseAuthorizationHeader(options.headers);
903
1071
  const dpopProof = parseDpopProof(options.headers);
904
- return dispatchParseCredentialRequest({
1072
+ return await dispatchParseCredentialRequest({
905
1073
  ...options,
906
1074
  accessToken,
907
1075
  dpopProof,
@@ -909,7 +1077,7 @@ function parseCredentialRequest(options) {
909
1077
  isDeferredFlow
910
1078
  });
911
1079
  } catch (error) {
912
- if (error instanceof import_io_wallet_utils6.ItWalletSpecsVersionError || error instanceof import_io_wallet_oauth23.Oauth2JwtParseError || error instanceof import_io_wallet_utils6.ValidationError || error instanceof CredentialAuthorizationHeaderError || error instanceof MissingDpopProofError) {
1080
+ if (error instanceof import_io_wallet_utils8.ItWalletSpecsVersionError || error instanceof import_io_wallet_oauth23.Oauth2JwtParseError || error instanceof import_io_wallet_utils8.ValidationError || error instanceof CredentialAuthorizationHeaderError || error instanceof MissingDpopProofError) {
913
1081
  throw error;
914
1082
  }
915
1083
  throw new ParseCredentialRequestError(
@@ -922,44 +1090,44 @@ function parseCredentialRequest(options) {
922
1090
  // src/credential-request/verify-credential-request-jwt-proof.ts
923
1091
  var import_oauth24 = require("@openid4vc/oauth2");
924
1092
  var import_io_wallet_oauth26 = require("@pagopa/io-wallet-oauth2");
925
- var import_io_wallet_utils9 = require("@pagopa/io-wallet-utils");
1093
+ var import_io_wallet_utils11 = require("@pagopa/io-wallet-utils");
926
1094
 
927
1095
  // src/credential-request/verify-key-attestation-jwt.ts
928
1096
  var import_oauth23 = require("@openid4vc/oauth2");
929
1097
  var import_io_wallet_oauth25 = require("@pagopa/io-wallet-oauth2");
930
- var import_io_wallet_utils8 = require("@pagopa/io-wallet-utils");
1098
+ var import_io_wallet_utils10 = require("@pagopa/io-wallet-utils");
931
1099
 
932
1100
  // src/wallet-provider/z-key-attestation.ts
933
1101
  var import_io_wallet_oauth24 = require("@pagopa/io-wallet-oauth2");
934
1102
  var import_io_wallet_oid_federation = require("@pagopa/io-wallet-oid-federation");
935
- var import_io_wallet_utils7 = require("@pagopa/io-wallet-utils");
936
- var import_zod7 = require("zod");
937
- var zStatusList = import_zod7.z.object({
938
- idx: import_zod7.z.number(),
939
- uri: import_zod7.z.url()
1103
+ var import_io_wallet_utils9 = require("@pagopa/io-wallet-utils");
1104
+ var import_zod9 = require("zod");
1105
+ var zStatusList = import_zod9.z.object({
1106
+ idx: import_zod9.z.number(),
1107
+ uri: import_zod9.z.url()
940
1108
  });
941
- var zKeyAttestationStatus = import_zod7.z.object({
1109
+ var zKeyAttestationStatus = import_zod9.z.object({
942
1110
  status_list: zStatusList
943
1111
  });
944
- var zKeyAttestationAlg = import_io_wallet_utils7.zItwSupportedSignatureAlg;
945
- var zKeyAttestationHeader = import_zod7.z.object({
1112
+ var zKeyAttestationAlg = import_io_wallet_utils9.zItwSupportedSignatureAlg;
1113
+ var zKeyAttestationHeader = import_zod9.z.object({
946
1114
  alg: zKeyAttestationAlg,
947
- kid: import_zod7.z.string(),
1115
+ kid: import_zod9.z.string(),
948
1116
  trust_chain: import_io_wallet_oauth24.zTrustChain.optional(),
949
- typ: import_zod7.z.literal("key-attestation+jwt"),
1117
+ typ: import_zod9.z.literal("key-attestation+jwt"),
950
1118
  x5c: import_io_wallet_oauth24.zCertificateChain
951
1119
  });
952
- var zKeyAttestationPayload = import_zod7.z.object({
953
- attested_keys: import_zod7.z.array(import_io_wallet_oauth24.zJwk).nonempty(),
954
- certification: import_zod7.z.string().optional(),
955
- exp: import_zod7.z.number(),
956
- iat: import_zod7.z.number(),
957
- iss: import_zod7.z.string(),
958
- key_storage: import_zod7.z.array(import_io_wallet_oid_federation.zKeyStorageLevelV1_3).nonempty(),
1120
+ var zKeyAttestationPayload = import_zod9.z.object({
1121
+ attested_keys: import_zod9.z.array(import_io_wallet_oauth24.zJwk).nonempty(),
1122
+ certification: import_zod9.z.string().optional(),
1123
+ exp: import_zod9.z.number(),
1124
+ iat: import_zod9.z.number(),
1125
+ iss: import_zod9.z.string(),
1126
+ key_storage: import_zod9.z.array(import_io_wallet_oid_federation.zKeyStorageLevelV1_3).nonempty(),
959
1127
  status: zKeyAttestationStatus,
960
- user_authentication: import_zod7.z.array(import_io_wallet_oid_federation.zKeyStorageLevelV1_3).nonempty()
1128
+ user_authentication: import_zod9.z.array(import_io_wallet_oid_federation.zKeyStorageLevelV1_3).nonempty()
961
1129
  });
962
- var zKeyAttestationTypeHeader = import_zod7.z.literal("key-attestation+jwt");
1130
+ var zKeyAttestationTypeHeader = import_zod9.z.literal("key-attestation+jwt");
963
1131
  var keyAttestationTypeHeader = zKeyAttestationTypeHeader.value;
964
1132
 
965
1133
  // src/credential-request/verify-key-attestation-jwt.ts
@@ -994,7 +1162,7 @@ async function verifyKeyAttestationJwt(options) {
994
1162
  }
995
1163
  return { header, payload, signer };
996
1164
  } catch (error) {
997
- if (error instanceof VerifyKeyAttestationJwtError || error instanceof import_io_wallet_utils8.ValidationError || error instanceof import_oauth23.Oauth2JwtParseError) {
1165
+ if (error instanceof VerifyKeyAttestationJwtError || error instanceof import_io_wallet_utils10.ValidationError || error instanceof import_oauth23.Oauth2JwtParseError) {
998
1166
  throw error;
999
1167
  }
1000
1168
  throw new VerifyKeyAttestationJwtError(
@@ -1024,7 +1192,7 @@ async function isJwkInSet(options) {
1024
1192
  }
1025
1193
  function verifyProofJwtIatOrThrow(options) {
1026
1194
  try {
1027
- (0, import_io_wallet_utils9.verifyJwtIatOrThrow)({
1195
+ (0, import_io_wallet_utils11.verifyJwtIatOrThrow)({
1028
1196
  iat: options.payload.iat,
1029
1197
  now: options.now
1030
1198
  });
@@ -1109,10 +1277,10 @@ async function verifyProofV1_3(options) {
1109
1277
  }
1110
1278
  return { header, keyAttestation: keyAttestationResult, payload, signer };
1111
1279
  }
1112
- var dispatchVerifyProof = (0, import_io_wallet_utils9.createVersionDispatcher)({
1113
- [import_io_wallet_utils9.ItWalletSpecsVersion.V1_0]: (o) => verifyProofV1_0(o),
1114
- [import_io_wallet_utils9.ItWalletSpecsVersion.V1_3]: (o) => verifyProofV1_3(o),
1115
- [import_io_wallet_utils9.ItWalletSpecsVersion.V1_4]: (o) => verifyProofV1_3(o)
1280
+ var dispatchVerifyProof = (0, import_io_wallet_utils11.createVersionDispatcher)({
1281
+ [import_io_wallet_utils11.ItWalletSpecsVersion.V1_0]: (o) => verifyProofV1_0(o),
1282
+ [import_io_wallet_utils11.ItWalletSpecsVersion.V1_3]: (o) => verifyProofV1_3(o),
1283
+ [import_io_wallet_utils11.ItWalletSpecsVersion.V1_4]: (o) => verifyProofV1_3(o)
1116
1284
  });
1117
1285
  async function verifyCredentialRequestJwtProof(options) {
1118
1286
  try {
@@ -1124,7 +1292,7 @@ async function verifyCredentialRequestJwtProof(options) {
1124
1292
  }
1125
1293
  return await dispatchVerifyProof({ ...options, now });
1126
1294
  } catch (error) {
1127
- if (error instanceof VerifyCredentialRequestJwtProofError || error instanceof VerifyKeyAttestationJwtError || error instanceof import_io_wallet_utils9.ItWalletSpecsVersionError || error instanceof import_io_wallet_utils9.ValidationError || error instanceof import_io_wallet_oauth26.Oauth2JwtParseError) {
1295
+ if (error instanceof VerifyCredentialRequestJwtProofError || error instanceof VerifyKeyAttestationJwtError || error instanceof import_io_wallet_utils11.ItWalletSpecsVersionError || error instanceof import_io_wallet_utils11.ValidationError || error instanceof import_io_wallet_oauth26.Oauth2JwtParseError) {
1128
1296
  throw error;
1129
1297
  }
1130
1298
  throw new VerifyCredentialRequestJwtProofError(
@@ -1135,36 +1303,36 @@ async function verifyCredentialRequestJwtProof(options) {
1135
1303
  }
1136
1304
 
1137
1305
  // src/credential-response/create-credential-response.ts
1138
- var import_io_wallet_utils12 = require("@pagopa/io-wallet-utils");
1306
+ var import_io_wallet_utils14 = require("@pagopa/io-wallet-utils");
1139
1307
 
1140
1308
  // src/credential-response/v1.0/create-credential-response.ts
1141
- var import_io_wallet_utils10 = require("@pagopa/io-wallet-utils");
1309
+ var import_io_wallet_utils12 = require("@pagopa/io-wallet-utils");
1142
1310
 
1143
1311
  // src/credential-response/v1.0/z-credential-response.ts
1144
- var import_zod9 = require("zod");
1312
+ var import_zod11 = require("zod");
1145
1313
 
1146
1314
  // src/credential-response/z-immediate-credential-response.ts
1147
- var import_zod8 = require("zod");
1148
- var zCredentialObject = import_zod8.z.object({
1149
- credential: import_zod8.z.string()
1315
+ var import_zod10 = require("zod");
1316
+ var zCredentialObject = import_zod10.z.object({
1317
+ credential: import_zod10.z.string()
1150
1318
  });
1151
- var zImmediateCredentialResponse = import_zod8.z.strictObject({
1152
- credentials: import_zod8.z.array(zCredentialObject).nonempty().describe(
1319
+ var zImmediateCredentialResponse = import_zod10.z.strictObject({
1320
+ credentials: import_zod10.z.array(zCredentialObject).nonempty().describe(
1153
1321
  "Conditional. Array of issued Digital Credentials as JSON objects with `credential` member containing encoded credential string. Present for immediate issuance (HTTP 200)."
1154
1322
  ),
1155
- notification_id: import_zod8.z.string().optional().describe(
1323
+ notification_id: import_zod10.z.string().optional().describe(
1156
1324
  "OPTIONAL. Identifier for notification requests. Only present with credentials parameter."
1157
1325
  )
1158
1326
  });
1159
1327
 
1160
1328
  // src/credential-response/v1.0/z-credential-response.ts
1161
- var zDeferredCredentialResponseV1_0 = import_zod9.z.strictObject({
1162
- lead_time: import_zod9.z.number().int().positive().describe(
1329
+ var zDeferredCredentialResponseV1_0 = import_zod11.z.strictObject({
1330
+ lead_time: import_zod11.z.number().int().positive().describe(
1163
1331
  "REQUIRED if credentials is not present, otherwise it MUST NOT be present. The amount of time (in seconds) required before making a Deferred Credential Request."
1164
1332
  ),
1165
- transaction_id: import_zod9.z.string().nonempty()
1333
+ transaction_id: import_zod11.z.string().nonempty()
1166
1334
  });
1167
- var zCredentialResponseV1_0 = import_zod9.z.union([
1335
+ var zCredentialResponseV1_0 = import_zod11.z.union([
1168
1336
  zImmediateCredentialResponse,
1169
1337
  zDeferredCredentialResponseV1_0
1170
1338
  ]);
@@ -1172,7 +1340,7 @@ var zCredentialResponseV1_0 = import_zod9.z.union([
1172
1340
  // src/credential-response/v1.0/create-credential-response.ts
1173
1341
  function createCredentialResponseV1_0(flow) {
1174
1342
  if ("credentials" in flow) {
1175
- return (0, import_io_wallet_utils10.parseWithErrorHandling)(
1343
+ return (0, import_io_wallet_utils12.parseWithErrorHandling)(
1176
1344
  zCredentialResponseV1_0,
1177
1345
  {
1178
1346
  credentials: flow.credentials,
@@ -1183,7 +1351,7 @@ function createCredentialResponseV1_0(flow) {
1183
1351
  "Invalid credential response for ItWalletSpecsVersion 1.0"
1184
1352
  );
1185
1353
  }
1186
- return (0, import_io_wallet_utils10.parseWithErrorHandling)(
1354
+ return (0, import_io_wallet_utils12.parseWithErrorHandling)(
1187
1355
  zCredentialResponseV1_0,
1188
1356
  {
1189
1357
  lead_time: flow.leadTime,
@@ -1194,17 +1362,17 @@ function createCredentialResponseV1_0(flow) {
1194
1362
  }
1195
1363
 
1196
1364
  // src/credential-response/v1.3/create-credential-response.ts
1197
- var import_io_wallet_utils11 = require("@pagopa/io-wallet-utils");
1365
+ var import_io_wallet_utils13 = require("@pagopa/io-wallet-utils");
1198
1366
 
1199
1367
  // src/credential-response/v1.3/z-credential-response.ts
1200
- var import_zod10 = require("zod");
1201
- var zDeferredCredentialResponseV1_3 = import_zod10.z.strictObject({
1202
- interval: import_zod10.z.number().int().positive().describe(
1368
+ var import_zod12 = require("zod");
1369
+ var zDeferredCredentialResponseV1_3 = import_zod12.z.strictObject({
1370
+ interval: import_zod12.z.number().int().positive().describe(
1203
1371
  "REQUIRED if transaction_id is present, otherwise it MUST NOT be present. The amount of time (in seconds) required before making a Deferred Credential Request"
1204
1372
  ),
1205
- transaction_id: import_zod10.z.string().nonempty()
1373
+ transaction_id: import_zod12.z.string().nonempty()
1206
1374
  });
1207
- var zCredentialResponseV1_3 = import_zod10.z.union([
1375
+ var zCredentialResponseV1_3 = import_zod12.z.union([
1208
1376
  zImmediateCredentialResponse,
1209
1377
  zDeferredCredentialResponseV1_3
1210
1378
  ]);
@@ -1212,7 +1380,7 @@ var zCredentialResponseV1_3 = import_zod10.z.union([
1212
1380
  // src/credential-response/v1.3/create-credential-response.ts
1213
1381
  function createCredentialResponseV1_3(flow) {
1214
1382
  if ("credentials" in flow) {
1215
- return (0, import_io_wallet_utils11.parseWithErrorHandling)(
1383
+ return (0, import_io_wallet_utils13.parseWithErrorHandling)(
1216
1384
  zCredentialResponseV1_3,
1217
1385
  {
1218
1386
  credentials: flow.credentials,
@@ -1223,7 +1391,7 @@ function createCredentialResponseV1_3(flow) {
1223
1391
  "Invalid credential response for ItWalletSpecsVersion 1.3"
1224
1392
  );
1225
1393
  }
1226
- return (0, import_io_wallet_utils11.parseWithErrorHandling)(
1394
+ return (0, import_io_wallet_utils13.parseWithErrorHandling)(
1227
1395
  zCredentialResponseV1_3,
1228
1396
  {
1229
1397
  interval: flow.interval,
@@ -1234,14 +1402,14 @@ function createCredentialResponseV1_3(flow) {
1234
1402
  }
1235
1403
 
1236
1404
  // src/credential-response/create-credential-response.ts
1237
- var dispatchBuildVersionedResponse = (0, import_io_wallet_utils12.createVersionDispatcher)({
1238
- [import_io_wallet_utils12.ItWalletSpecsVersion.V1_0]: (o) => createCredentialResponseV1_0(
1405
+ var dispatchBuildVersionedResponse = (0, import_io_wallet_utils14.createVersionDispatcher)({
1406
+ [import_io_wallet_utils14.ItWalletSpecsVersion.V1_0]: (o) => createCredentialResponseV1_0(
1239
1407
  o.flow
1240
1408
  ),
1241
- [import_io_wallet_utils12.ItWalletSpecsVersion.V1_3]: (o) => createCredentialResponseV1_3(
1409
+ [import_io_wallet_utils14.ItWalletSpecsVersion.V1_3]: (o) => createCredentialResponseV1_3(
1242
1410
  o.flow
1243
1411
  ),
1244
- [import_io_wallet_utils12.ItWalletSpecsVersion.V1_4]: (o) => createCredentialResponseV1_3(
1412
+ [import_io_wallet_utils14.ItWalletSpecsVersion.V1_4]: (o) => createCredentialResponseV1_3(
1245
1413
  o.flow
1246
1414
  // V1_4 reuses V1_3 credential response schema — no breaking changes between versions.
1247
1415
  // Verified against compare/1.3.3...1.4.1: credential response parameters identical.
@@ -1266,7 +1434,7 @@ async function createCredentialResponse(options) {
1266
1434
  }
1267
1435
  return { credentialResponse, credentialResponseJwt };
1268
1436
  } catch (error) {
1269
- if (error instanceof import_io_wallet_utils12.ValidationError || error instanceof Oid4vciError) {
1437
+ if (error instanceof import_io_wallet_utils14.ValidationError || error instanceof Oid4vciError) {
1270
1438
  throw error;
1271
1439
  }
1272
1440
  throw new CreateCredentialResponseError(
@@ -1290,49 +1458,49 @@ async function encryptResponse(credentialResponse, credentialResponseEncryption,
1290
1458
  }
1291
1459
 
1292
1460
  // src/credential-response/fetch-credential-response.ts
1293
- var import_io_wallet_utils13 = require("@pagopa/io-wallet-utils");
1461
+ var import_io_wallet_utils15 = require("@pagopa/io-wallet-utils");
1294
1462
 
1295
1463
  // src/credential-response/z-credential-response.ts
1296
1464
  var import_io_wallet_oauth27 = require("@pagopa/io-wallet-oauth2");
1297
- var import_zod11 = require("zod");
1298
- var zCredentialResponseEncryption = import_zod11.z.looseObject({
1465
+ var import_zod13 = require("zod");
1466
+ var zCredentialResponseEncryption = import_zod13.z.looseObject({
1299
1467
  alg: import_io_wallet_oauth27.zAlgValueNotNone,
1300
- enc: import_zod11.z.string(),
1468
+ enc: import_zod13.z.string(),
1301
1469
  jwk: import_io_wallet_oauth27.zJwk
1302
1470
  });
1303
1471
 
1304
1472
  // src/credential-response/fetch-credential-response.ts
1305
1473
  async function fetchCredentialResponse(options) {
1306
1474
  try {
1307
- const fetch = (0, import_io_wallet_utils13.createFetcher)(options.callbacks.fetch);
1475
+ const fetch = (0, import_io_wallet_utils15.createFetcher)(options.callbacks.fetch);
1308
1476
  const credentialResponse = await fetch(options.credentialEndpoint, {
1309
1477
  body: JSON.stringify(options.credentialRequest),
1310
1478
  headers: {
1311
- [import_io_wallet_utils13.HEADERS.AUTHORIZATION]: `DPoP ${options.accessToken}`,
1312
- [import_io_wallet_utils13.HEADERS.CONTENT_TYPE]: import_io_wallet_utils13.CONTENT_TYPES.JSON,
1313
- [import_io_wallet_utils13.HEADERS.DPOP]: options.dPoP
1479
+ [import_io_wallet_utils15.HEADERS.AUTHORIZATION]: `DPoP ${options.accessToken}`,
1480
+ [import_io_wallet_utils15.HEADERS.CONTENT_TYPE]: import_io_wallet_utils15.CONTENT_TYPES.JSON,
1481
+ [import_io_wallet_utils15.HEADERS.DPOP]: options.dPoP
1314
1482
  },
1315
1483
  method: "POST"
1316
1484
  });
1317
- await (0, import_io_wallet_utils13.hasStatusOrThrow)(
1485
+ await (0, import_io_wallet_utils15.hasStatusOrThrow)(
1318
1486
  [200, 202],
1319
- import_io_wallet_utils13.UnexpectedStatusCodeError
1487
+ import_io_wallet_utils15.UnexpectedStatusCodeError
1320
1488
  )(credentialResponse);
1321
1489
  const credentialResponseJson = await credentialResponse.json();
1322
1490
  if ("proof" in options.credentialRequest) {
1323
- return (0, import_io_wallet_utils13.parseWithErrorHandling)(
1491
+ return (0, import_io_wallet_utils15.parseWithErrorHandling)(
1324
1492
  zCredentialResponseV1_0,
1325
1493
  credentialResponseJson,
1326
1494
  `Failed to parse credential response (v1.0)`
1327
1495
  );
1328
1496
  }
1329
- return (0, import_io_wallet_utils13.parseWithErrorHandling)(
1497
+ return (0, import_io_wallet_utils15.parseWithErrorHandling)(
1330
1498
  zCredentialResponseV1_3,
1331
1499
  credentialResponseJson,
1332
1500
  `Failed to parse credential response (v1.3)`
1333
1501
  );
1334
1502
  } catch (error) {
1335
- if (error instanceof import_io_wallet_utils13.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils13.ValidationError) {
1503
+ if (error instanceof import_io_wallet_utils15.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils15.ValidationError) {
1336
1504
  throw error;
1337
1505
  }
1338
1506
  throw new FetchCredentialResponseError(
@@ -1344,28 +1512,34 @@ async function fetchCredentialResponse(options) {
1344
1512
  // src/metadata/fetch-metadata.ts
1345
1513
  var import_io_wallet_oauth28 = require("@pagopa/io-wallet-oauth2");
1346
1514
  var import_io_wallet_oid_federation3 = require("@pagopa/io-wallet-oid-federation");
1347
- var import_io_wallet_utils14 = require("@pagopa/io-wallet-utils");
1348
- var import_zod13 = __toESM(require("zod"));
1515
+ var import_io_wallet_utils16 = require("@pagopa/io-wallet-utils");
1516
+ var import_zod15 = __toESM(require("zod"));
1349
1517
 
1350
1518
  // src/metadata/z-metadata-response.ts
1351
1519
  var import_io_wallet_oid_federation2 = require("@pagopa/io-wallet-oid-federation");
1352
- var import_zod12 = require("zod");
1353
- var zMetadataResponseV1_0 = import_zod12.z.object({
1354
- discoveredVia: import_zod12.z.enum(["federation"]),
1520
+ var import_zod14 = require("zod");
1521
+ var zMetadataResponseV1_0 = import_zod14.z.object({
1522
+ discoveredVia: import_zod14.z.enum(["federation"]),
1355
1523
  metadata: import_io_wallet_oid_federation2.itWalletMetadataV1_0,
1356
1524
  openid_federation_claims: import_io_wallet_oid_federation2.itWalletEntityStatementClaimsSchema
1357
1525
  });
1358
- var zMetadataResponseV1_3 = import_zod12.z.object({
1359
- discoveredVia: import_zod12.z.enum(["federation", "oid4vci"]),
1526
+ var zMetadataResponseV1_3 = import_zod14.z.object({
1527
+ /**
1528
+ * Entity statement claims of the Authorization Server, present only when the
1529
+ * selected authorization server was resolved through a federation entity
1530
+ * distinct from the Credential Issuer.
1531
+ */
1532
+ authorization_server_federation_claims: import_io_wallet_oid_federation2.itWalletEntityStatementClaimsSchema.optional(),
1533
+ discoveredVia: import_zod14.z.enum(["federation", "oid4vci"]),
1360
1534
  metadata: import_io_wallet_oid_federation2.itWalletMetadataV1_3,
1361
1535
  openid_federation_claims: import_io_wallet_oid_federation2.itWalletEntityStatementClaimsSchema.optional()
1362
1536
  });
1363
- var zMetadataResponse = import_zod12.z.union([
1537
+ var zMetadataResponse = import_zod14.z.union([
1364
1538
  zMetadataResponseV1_0,
1365
1539
  zMetadataResponseV1_3
1366
1540
  ]);
1367
- var zPartialIssuerMetadata = import_zod12.z.looseObject({
1368
- authorization_servers: import_zod12.z.array(import_zod12.z.string()).optional()
1541
+ var zPartialIssuerMetadata = import_zod14.z.looseObject({
1542
+ authorization_servers: import_zod14.z.tuple([import_zod14.z.url()], import_zod14.z.url()).optional()
1369
1543
  });
1370
1544
 
1371
1545
  // src/metadata/fetch-metadata.ts
@@ -1400,7 +1574,7 @@ async function tryFederationDiscovery(fetch, baseUrl, verifyJwt4) {
1400
1574
  payload
1401
1575
  });
1402
1576
  if (!result.verified) {
1403
- throw new import_io_wallet_utils14.ValidationError(
1577
+ throw new import_io_wallet_utils16.ValidationError(
1404
1578
  "Entity statement signature verification failed"
1405
1579
  );
1406
1580
  }
@@ -1411,31 +1585,74 @@ async function tryFederationDiscovery(fetch, baseUrl, verifyJwt4) {
1411
1585
  openid_federation_claims: payload
1412
1586
  };
1413
1587
  } catch (error) {
1414
- if (error instanceof import_io_wallet_utils14.ValidationError) {
1588
+ if (error instanceof import_io_wallet_utils16.ValidationError) {
1415
1589
  throw error;
1416
1590
  }
1417
1591
  return void 0;
1418
1592
  }
1419
1593
  }
1420
- async function fallbackDiscovery(fetch, baseUrl) {
1594
+ async function applyFederationAuthorizationServerSelection(fetch, federationResult, authorizationServer, verifyJwt4) {
1595
+ const credentialIssuer = federationResult.metadata?.openid_credential_issuer?.credential_issuer;
1596
+ const authorizationServers = federationResult.metadata?.openid_credential_issuer?.authorization_servers;
1597
+ let selectedAuthorizationServer;
1598
+ if (authorizationServer) {
1599
+ assertAuthorizationServerAllowed(authorizationServer, authorizationServers);
1600
+ selectedAuthorizationServer = authorizationServer;
1601
+ } else if (authorizationServers && authorizationServers.length > 0) {
1602
+ selectedAuthorizationServer = credentialIssuer && authorizationServers.includes(credentialIssuer) ? credentialIssuer : authorizationServers[0];
1603
+ } else {
1604
+ selectedAuthorizationServer = credentialIssuer;
1605
+ }
1606
+ if (!selectedAuthorizationServer || selectedAuthorizationServer === credentialIssuer) {
1607
+ return federationResult;
1608
+ }
1609
+ const parsedSelectedAuthorizationServer = import_zod15.default.url().safeParse(selectedAuthorizationServer);
1610
+ if (!parsedSelectedAuthorizationServer.success || !parsedSelectedAuthorizationServer.data.startsWith("https://")) {
1611
+ throw new import_io_wallet_utils16.ValidationError(
1612
+ "selected authorization server is not a valid HTTPS URL"
1613
+ );
1614
+ }
1615
+ const authorizationServerResult = await tryFederationDiscovery(
1616
+ fetch,
1617
+ parsedSelectedAuthorizationServer.data,
1618
+ verifyJwt4
1619
+ );
1620
+ const resolvedAuthorizationServer = authorizationServerResult?.metadata?.oauth_authorization_server;
1621
+ if (!resolvedAuthorizationServer) {
1622
+ throw new import_io_wallet_utils16.ValidationError(
1623
+ `Federation discovery did not yield oauth_authorization_server metadata for authorization server '${selectedAuthorizationServer}'`
1624
+ );
1625
+ }
1626
+ return {
1627
+ ...federationResult,
1628
+ authorization_server_federation_claims: authorizationServerResult.openid_federation_claims,
1629
+ metadata: {
1630
+ ...federationResult.metadata,
1631
+ oauth_authorization_server: resolvedAuthorizationServer
1632
+ }
1633
+ };
1634
+ }
1635
+ async function fallbackDiscovery(fetch, baseUrl, authorizationServer) {
1421
1636
  const issuerUrl = new URL(
1422
1637
  ".well-known/openid-credential-issuer",
1423
1638
  ensureTrailingSlash(baseUrl)
1424
1639
  ).toString();
1425
1640
  const issuerResponse = await fetch(issuerUrl);
1426
- await (0, import_io_wallet_utils14.hasStatusOrThrow)(200, import_io_wallet_utils14.UnexpectedStatusCodeError)(issuerResponse);
1427
- const issuerJson = (0, import_io_wallet_utils14.parseWithErrorHandling)(
1641
+ await (0, import_io_wallet_utils16.hasStatusOrThrow)(200, import_io_wallet_utils16.UnexpectedStatusCodeError)(issuerResponse);
1642
+ const issuerJson = (0, import_io_wallet_utils16.parseWithErrorHandling)(
1428
1643
  zPartialIssuerMetadata,
1429
1644
  await issuerResponse.json(),
1430
1645
  "Failed to parse credential issuer metadata"
1431
1646
  );
1432
1647
  const authorizationServers = issuerJson.authorization_servers;
1648
+ assertAuthorizationServerAllowed(authorizationServer, authorizationServers);
1433
1649
  let oauthAuthorizationServer;
1434
1650
  if (authorizationServers && authorizationServers.length > 0) {
1435
- const parsedUrl = import_zod13.default.url().safeParse(authorizationServers[0]);
1651
+ const selectedAuthorizationServer = authorizationServer ?? authorizationServers[0];
1652
+ const parsedUrl = import_zod15.default.url().safeParse(selectedAuthorizationServer);
1436
1653
  if (!parsedUrl.success || !parsedUrl.data.startsWith("https://")) {
1437
- throw new import_io_wallet_utils14.ValidationError(
1438
- "authorization_servers[0] is not a valid HTTPS URL"
1654
+ throw new import_io_wallet_utils16.ValidationError(
1655
+ "selected authorization server is not a valid HTTPS URL"
1439
1656
  );
1440
1657
  }
1441
1658
  const authServerUrl = new URL(
@@ -1443,7 +1660,7 @@ async function fallbackDiscovery(fetch, baseUrl) {
1443
1660
  ensureTrailingSlash(parsedUrl.data)
1444
1661
  ).toString();
1445
1662
  const authServerResponse = await fetch(authServerUrl);
1446
- await (0, import_io_wallet_utils14.hasStatusOrThrow)(200, import_io_wallet_utils14.UnexpectedStatusCodeError)(authServerResponse);
1663
+ await (0, import_io_wallet_utils16.hasStatusOrThrow)(200, import_io_wallet_utils16.UnexpectedStatusCodeError)(authServerResponse);
1447
1664
  oauthAuthorizationServer = await authServerResponse.json();
1448
1665
  } else {
1449
1666
  oauthAuthorizationServer = issuerJson;
@@ -1457,7 +1674,7 @@ async function fallbackDiscovery(fetch, baseUrl) {
1457
1674
  };
1458
1675
  }
1459
1676
  async function fetchMetadataV1_0(options) {
1460
- const fetch = (0, import_io_wallet_utils14.createFetcher)(options.callbacks.fetch);
1677
+ const fetch = (0, import_io_wallet_utils16.createFetcher)(options.callbacks.fetch);
1461
1678
  const federationResult = await tryFederationDiscovery(
1462
1679
  fetch,
1463
1680
  options.credentialIssuerUrl,
@@ -1468,43 +1685,52 @@ async function fetchMetadataV1_0(options) {
1468
1685
  `Federation discovery failed for IT Wallet v1.0; no fallback available for credentialIssuerUrl ${options.credentialIssuerUrl}`
1469
1686
  );
1470
1687
  }
1471
- return (0, import_io_wallet_utils14.parseWithErrorHandling)(
1688
+ return (0, import_io_wallet_utils16.parseWithErrorHandling)(
1472
1689
  zMetadataResponseV1_0,
1473
1690
  federationResult,
1474
1691
  "Failed to parse v1.0 metadata response"
1475
1692
  );
1476
1693
  }
1477
1694
  async function fetchMetadataV1_3(options) {
1478
- const fetch = (0, import_io_wallet_utils14.createFetcher)(options.callbacks.fetch);
1695
+ const fetch = (0, import_io_wallet_utils16.createFetcher)(options.callbacks.fetch);
1479
1696
  const federationResult = await tryFederationDiscovery(
1480
1697
  fetch,
1481
1698
  options.credentialIssuerUrl,
1482
1699
  options.callbacks.verifyJwt
1483
1700
  );
1484
- const raw = federationResult ?? await fallbackDiscovery(fetch, options.credentialIssuerUrl);
1485
- return (0, import_io_wallet_utils14.parseWithErrorHandling)(
1701
+ const raw = federationResult ? await applyFederationAuthorizationServerSelection(
1702
+ fetch,
1703
+ federationResult,
1704
+ options.authorizationServer,
1705
+ options.callbacks.verifyJwt
1706
+ ) : await fallbackDiscovery(
1707
+ fetch,
1708
+ options.credentialIssuerUrl,
1709
+ options.authorizationServer
1710
+ );
1711
+ return (0, import_io_wallet_utils16.parseWithErrorHandling)(
1486
1712
  zMetadataResponseV1_3,
1487
1713
  raw,
1488
1714
  "Failed to parse v1.3 metadata response"
1489
1715
  );
1490
1716
  }
1491
- var dispatchFetchMetadata = (0, import_io_wallet_utils14.createVersionDispatcher)({
1492
- [import_io_wallet_utils14.ItWalletSpecsVersion.V1_0]: (o) => fetchMetadataV1_0(o),
1493
- [import_io_wallet_utils14.ItWalletSpecsVersion.V1_3]: (o) => fetchMetadataV1_3(o),
1717
+ var dispatchFetchMetadata = (0, import_io_wallet_utils16.createVersionDispatcher)({
1718
+ [import_io_wallet_utils16.ItWalletSpecsVersion.V1_0]: (o) => fetchMetadataV1_0(o),
1719
+ [import_io_wallet_utils16.ItWalletSpecsVersion.V1_3]: (o) => fetchMetadataV1_3(o),
1494
1720
  // V1_4 reuses V1_3 metadata schema — no breaking changes between versions.
1495
- [import_io_wallet_utils14.ItWalletSpecsVersion.V1_4]: (o) => fetchMetadataV1_3(o)
1721
+ [import_io_wallet_utils16.ItWalletSpecsVersion.V1_4]: (o) => fetchMetadataV1_3(o)
1496
1722
  });
1497
1723
  async function fetchMetadata(options) {
1498
1724
  try {
1499
- const urlValidation = import_zod13.default.url().safeParse(options.credentialIssuerUrl);
1725
+ const urlValidation = import_zod15.default.url().safeParse(options.credentialIssuerUrl);
1500
1726
  if (!urlValidation.success || !urlValidation.data.startsWith("https://")) {
1501
- throw new import_io_wallet_utils14.ValidationError(
1727
+ throw new import_io_wallet_utils16.ValidationError(
1502
1728
  "credentialIssuerUrl must be a valid HTTPS URL"
1503
1729
  );
1504
1730
  }
1505
1731
  return await dispatchFetchMetadata(options);
1506
1732
  } catch (error) {
1507
- if (error instanceof import_io_wallet_utils14.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils14.ValidationError || error instanceof import_io_wallet_utils14.ItWalletSpecsVersionError || error instanceof FetchMetadataError) {
1733
+ if (error instanceof import_io_wallet_utils16.UnexpectedStatusCodeError || error instanceof import_io_wallet_utils16.ValidationError || error instanceof import_io_wallet_utils16.ItWalletSpecsVersionError || error instanceof CredentialOfferError || error instanceof FetchMetadataError) {
1508
1734
  throw error;
1509
1735
  }
1510
1736
  throw new FetchMetadataError("Unexpected error during metadata fetch", {
@@ -1515,7 +1741,7 @@ async function fetchMetadata(options) {
1515
1741
 
1516
1742
  // src/wallet-provider/WalletProvider.ts
1517
1743
  var import_io_wallet_oauth29 = require("@pagopa/io-wallet-oauth2");
1518
- var import_io_wallet_utils15 = require("@pagopa/io-wallet-utils");
1744
+ var import_io_wallet_utils17 = require("@pagopa/io-wallet-utils");
1519
1745
  function assertV1_0Options(options) {
1520
1746
  if (options.signer.method !== "federation") {
1521
1747
  throw new WalletProviderError(
@@ -1578,7 +1804,7 @@ var WalletProvider = class {
1578
1804
  const { signJwt } = options.callbacks;
1579
1805
  const now = /* @__PURE__ */ new Date();
1580
1806
  const issuedAt = options.issuedAt ?? now;
1581
- const expiresAt = options.expiresAt ?? (0, import_io_wallet_utils15.addSecondsToDate)(now, 3600 * 24 * 360);
1807
+ const expiresAt = options.expiresAt ?? (0, import_io_wallet_utils17.addSecondsToDate)(now, 3600 * 24 * 360);
1582
1808
  const header = {
1583
1809
  alg: options.signer.alg,
1584
1810
  kid: options.signer.kid,
@@ -1588,8 +1814,8 @@ var WalletProvider = class {
1588
1814
  };
1589
1815
  const payload = {
1590
1816
  attested_keys: options.attestedKeys,
1591
- exp: (0, import_io_wallet_utils15.dateToSeconds)(expiresAt),
1592
- iat: (0, import_io_wallet_utils15.dateToSeconds)(issuedAt),
1817
+ exp: (0, import_io_wallet_utils17.dateToSeconds)(expiresAt),
1818
+ iat: (0, import_io_wallet_utils17.dateToSeconds)(issuedAt),
1593
1819
  iss: options.issuer,
1594
1820
  key_storage: options.keyStorage,
1595
1821
  status: options.status,
@@ -1679,8 +1905,8 @@ var WalletProvider = class {
1679
1905
  * });
1680
1906
  */
1681
1907
  async createItWalletAttestationJwt(options) {
1682
- return (0, import_io_wallet_utils15.dispatchByVersion)(this.specVersion, {
1683
- [import_io_wallet_utils15.ItWalletSpecsVersion.V1_0]: () => {
1908
+ return (0, import_io_wallet_utils17.dispatchByVersion)(this.specVersion, {
1909
+ [import_io_wallet_utils17.ItWalletSpecsVersion.V1_0]: () => {
1684
1910
  assertV1_0Options(options);
1685
1911
  return (0, import_io_wallet_oauth29.createWalletAttestationJwtV1_0)({
1686
1912
  authenticatorAssuranceLevel: options.authenticatorAssuranceLevel,
@@ -1693,7 +1919,7 @@ var WalletProvider = class {
1693
1919
  walletName: options.walletName
1694
1920
  });
1695
1921
  },
1696
- [import_io_wallet_utils15.ItWalletSpecsVersion.V1_3]: () => {
1922
+ [import_io_wallet_utils17.ItWalletSpecsVersion.V1_3]: () => {
1697
1923
  assertV1_3Options(options);
1698
1924
  return (0, import_io_wallet_oauth29.createWalletAttestationJwtV1_3)({
1699
1925
  callbacks: options.callbacks,
@@ -1707,7 +1933,7 @@ var WalletProvider = class {
1707
1933
  walletName: options.walletName
1708
1934
  });
1709
1935
  },
1710
- [import_io_wallet_utils15.ItWalletSpecsVersion.V1_4]: () => {
1936
+ [import_io_wallet_utils17.ItWalletSpecsVersion.V1_4]: () => {
1711
1937
  assertV1_4Options(options);
1712
1938
  return (0, import_io_wallet_oauth29.createWalletAttestationJwtV1_4)({
1713
1939
  callbacks: options.callbacks,
@@ -1755,8 +1981,14 @@ var WalletProvider = class {
1755
1981
  verifyAuthorizationResponseFormPostJWT,
1756
1982
  verifyCredentialRequestJwtProof,
1757
1983
  verifyKeyAttestationJwt,
1984
+ zAuthorizationCodeGrantV1_3,
1985
+ zAuthorizationCodeGrantV1_4,
1758
1986
  zAuthorizationResponse,
1759
1987
  zCredentialObject,
1988
+ zCredentialOfferGrantsV1_3,
1989
+ zCredentialOfferGrantsV1_4,
1990
+ zCredentialOfferV1_3,
1991
+ zCredentialOfferV1_4,
1760
1992
  zCredentialRequestV1_0,
1761
1993
  zCredentialRequestV1_3,
1762
1994
  zCredentialResponseEncryption,