@pagopa/io-react-native-wallet 1.2.3 → 1.2.4

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.
Files changed (54) hide show
  1. package/lib/commonjs/credential/presentation/01-start-flow.js +12 -28
  2. package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
  3. package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js +96 -24
  4. package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js.map +1 -1
  5. package/lib/commonjs/credential/presentation/05-verify-request-object.js +7 -2
  6. package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -1
  7. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +9 -5
  8. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  9. package/lib/commonjs/credential/presentation/README.md +4 -4
  10. package/lib/commonjs/credential/presentation/errors.js +2 -19
  11. package/lib/commonjs/credential/presentation/errors.js.map +1 -1
  12. package/lib/commonjs/credential/presentation/types.js +7 -1
  13. package/lib/commonjs/credential/presentation/types.js.map +1 -1
  14. package/lib/commonjs/utils/crypto.js +41 -1
  15. package/lib/commonjs/utils/crypto.js.map +1 -1
  16. package/lib/module/credential/presentation/01-start-flow.js +12 -28
  17. package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
  18. package/lib/module/credential/presentation/04-retrieve-rp-jwks.js +96 -24
  19. package/lib/module/credential/presentation/04-retrieve-rp-jwks.js.map +1 -1
  20. package/lib/module/credential/presentation/05-verify-request-object.js +7 -2
  21. package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -1
  22. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +9 -5
  23. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
  24. package/lib/module/credential/presentation/README.md +4 -4
  25. package/lib/module/credential/presentation/errors.js +0 -16
  26. package/lib/module/credential/presentation/errors.js.map +1 -1
  27. package/lib/module/credential/presentation/types.js +7 -1
  28. package/lib/module/credential/presentation/types.js.map +1 -1
  29. package/lib/module/utils/crypto.js +38 -0
  30. package/lib/module/utils/crypto.js.map +1 -1
  31. package/lib/typescript/credential/presentation/01-start-flow.d.ts +3 -3
  32. package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
  33. package/lib/typescript/credential/presentation/03-get-request-object.d.ts +1 -1
  34. package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts +15 -8
  35. package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts.map +1 -1
  36. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -1
  37. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +3 -2
  38. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -1
  39. package/lib/typescript/credential/presentation/errors.d.ts +0 -11
  40. package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
  41. package/lib/typescript/credential/presentation/types.d.ts +242 -3
  42. package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
  43. package/lib/typescript/utils/crypto.d.ts +24 -0
  44. package/lib/typescript/utils/crypto.d.ts.map +1 -1
  45. package/package.json +3 -1
  46. package/src/credential/presentation/01-start-flow.ts +16 -32
  47. package/src/credential/presentation/03-get-request-object.ts +1 -1
  48. package/src/credential/presentation/04-retrieve-rp-jwks.ts +122 -34
  49. package/src/credential/presentation/05-verify-request-object.ts +4 -3
  50. package/src/credential/presentation/07-evaluate-input-descriptor.ts +20 -6
  51. package/src/credential/presentation/README.md +4 -4
  52. package/src/credential/presentation/errors.ts +0 -16
  53. package/src/credential/presentation/types.ts +8 -1
  54. package/src/utils/crypto.ts +43 -0
@@ -3,6 +3,7 @@ import { SdJwt4VC, type DisclosureWithEncoded } from "../../sd-jwt/types";
3
3
  export type EvaluatedDisclosures = {
4
4
  requiredDisclosures: DisclosureWithEncoded[];
5
5
  optionalDisclosures: DisclosureWithEncoded[];
6
+ unrequestedDisclosures: DisclosureWithEncoded[];
6
7
  };
7
8
  export type EvaluateInputDescriptorSdJwt4VC = (inputDescriptor: InputDescriptor, payloadCredential: SdJwt4VC["payload"], disclosures: DisclosureWithEncoded[]) => EvaluatedDisclosures;
8
9
  /**
@@ -13,8 +14,8 @@ export type EvaluateInputDescriptorSdJwt4VC = (inputDescriptor: InputDescriptor,
13
14
  * - Validates whether required fields are present (unless marked optional)
14
15
  * and match any specified JSONPath.
15
16
  * - If a field includes a JSON Schema filter, validates the claim value against that schema.
16
- * - Enforces `limit_disclosure` rules by returning only disclosures matching the specified fields
17
- * if set to "required". Otherwise return the array of all disclosures.
17
+ * - Enforces `limit_disclosure` rules by returning only disclosures, required and optional, matching the specified fields
18
+ * if set to "required". Otherwise also return the array unrequestedDisclosures with disclosures which can be passed for a particular use case.
18
19
  * - Throws an error if a required field is invalid or missing.
19
20
  *
20
21
  * @param inputDescriptor - Describes constraints (fields, filters, etc.) that must be satisfied.
@@ -1 +1 @@
1
- {"version":3,"file":"07-evaluate-input-descriptor.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/07-evaluate-input-descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAO1E,MAAM,MAAM,oBAAoB,GAAG;IACjC,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;IAC7C,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,CAC5C,eAAe,EAAE,eAAe,EAChC,iBAAiB,EAAE,QAAQ,CAAC,SAAS,CAAC,EACtC,WAAW,EAAE,qBAAqB,EAAE,KACjC,oBAAoB,CAAC;AA4E1B;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kCAAkC,EAAE,+BA4F9C,CAAC"}
1
+ {"version":3,"file":"07-evaluate-input-descriptor.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/07-evaluate-input-descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAO1E,MAAM,MAAM,oBAAoB,GAAG;IACjC,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;IAC7C,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;IAC7C,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,CAC5C,eAAe,EAAE,eAAe,EAChC,iBAAiB,EAAE,QAAQ,CAAC,SAAS,CAAC,EACtC,WAAW,EAAE,qBAAqB,EAAE,KACjC,oBAAoB,CAAC;AA4E1B;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kCAAkC,EAAE,+BAyG9C,CAAC"}
@@ -22,17 +22,6 @@ export declare class NoSuitableKeysFoundInEntityConfiguration extends IoWalletEr
22
22
  */
23
23
  constructor(scenario: string);
24
24
  }
25
- /**
26
- * When a QR code is not valid.
27
- *
28
- */
29
- export declare class InvalidQRCodeError extends IoWalletError {
30
- code: string;
31
- /**
32
- * @param detail A description of why the QR code is considered invalid.
33
- */
34
- constructor(detail: string);
35
- }
36
25
  /**
37
26
  * When the entity is unverified because the Relying Party is not trusted.
38
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,oBAAoB,CAAC;AAEnE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,aAAa;IACvD,IAAI,SAAwD;IAE5D,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IAEd,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;gBAGb,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAsB,EAC7B,MAAM,GAAE,MAAsB;CAMjC;AAED;;;GAGG;AACH,qBAAa,wCAAyC,SAAQ,aAAa;IACzE,IAAI,SAAoC;IAExC;;OAEG;gBACS,QAAQ,EAAE,MAAM;CAI7B;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,aAAa;IACnD,IAAI,SAAyB;IAE7B;;OAEG;gBACS,MAAM,EAAE,MAAM;CAI3B;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,IAAI,SAA8B;IAElC;;OAEG;gBACS,MAAM,EAAE,MAAM;CAI3B;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,IAAI,SAAsB;IAE1B;;OAEG;gBACS,iBAAiB,EAAE,MAAM;CAItC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,oBAAoB,CAAC;AAEnE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,aAAa;IACvD,IAAI,SAAwD;IAE5D,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IAEd,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;gBAGb,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAsB,EAC7B,MAAM,GAAE,MAAsB;CAMjC;AAED;;;GAGG;AACH,qBAAa,wCAAyC,SAAQ,aAAa;IACzE,IAAI,SAAoC;IAExC;;OAEG;gBACS,QAAQ,EAAE,MAAM;CAI7B;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,IAAI,SAA8B;IAElC;;OAEG;gBACS,MAAM,EAAE,MAAM;CAI3B;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,IAAI,SAAsB;IAE1B;;OAEG;gBACS,iBAAiB,EAAE,MAAM;CAItC"}
@@ -331,7 +331,188 @@ export declare const RequestObject: z.ZodObject<{
331
331
  response_type: z.ZodLiteral<"vp_token">;
332
332
  response_mode: z.ZodEnum<["direct_post.jwt", "direct_post"]>;
333
333
  client_id: z.ZodString;
334
- client_id_scheme: z.ZodString;
334
+ client_id_scheme: z.ZodOptional<z.ZodString>;
335
+ client_metadata: z.ZodOptional<z.ZodObject<{
336
+ jwks_uri: z.ZodOptional<z.ZodString>;
337
+ jwks: z.ZodOptional<z.ZodObject<{
338
+ keys: z.ZodArray<z.ZodObject<{
339
+ alg: z.ZodOptional<z.ZodString>;
340
+ crv: z.ZodOptional<z.ZodString>;
341
+ d: z.ZodOptional<z.ZodString>;
342
+ dp: z.ZodOptional<z.ZodString>;
343
+ dq: z.ZodOptional<z.ZodString>;
344
+ e: z.ZodOptional<z.ZodString>;
345
+ ext: z.ZodOptional<z.ZodBoolean>;
346
+ k: z.ZodOptional<z.ZodString>;
347
+ key_ops: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
348
+ kid: z.ZodOptional<z.ZodString>;
349
+ kty: z.ZodUnion<[z.ZodLiteral<"RSA">, z.ZodLiteral<"EC">]>;
350
+ n: z.ZodOptional<z.ZodString>;
351
+ p: z.ZodOptional<z.ZodString>;
352
+ q: z.ZodOptional<z.ZodString>;
353
+ qi: z.ZodOptional<z.ZodString>;
354
+ use: z.ZodOptional<z.ZodString>;
355
+ x: z.ZodOptional<z.ZodString>;
356
+ y: z.ZodOptional<z.ZodString>;
357
+ x5c: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
358
+ x5t: z.ZodOptional<z.ZodString>;
359
+ "x5t#S256": z.ZodOptional<z.ZodString>;
360
+ x5u: z.ZodOptional<z.ZodString>;
361
+ }, "strip", z.ZodTypeAny, {
362
+ kty: "RSA" | "EC";
363
+ alg?: string | undefined;
364
+ crv?: string | undefined;
365
+ d?: string | undefined;
366
+ dp?: string | undefined;
367
+ dq?: string | undefined;
368
+ e?: string | undefined;
369
+ ext?: boolean | undefined;
370
+ k?: string | undefined;
371
+ key_ops?: string[] | undefined;
372
+ kid?: string | undefined;
373
+ n?: string | undefined;
374
+ p?: string | undefined;
375
+ q?: string | undefined;
376
+ qi?: string | undefined;
377
+ use?: string | undefined;
378
+ x?: string | undefined;
379
+ y?: string | undefined;
380
+ x5c?: string[] | undefined;
381
+ x5t?: string | undefined;
382
+ "x5t#S256"?: string | undefined;
383
+ x5u?: string | undefined;
384
+ }, {
385
+ kty: "RSA" | "EC";
386
+ alg?: string | undefined;
387
+ crv?: string | undefined;
388
+ d?: string | undefined;
389
+ dp?: string | undefined;
390
+ dq?: string | undefined;
391
+ e?: string | undefined;
392
+ ext?: boolean | undefined;
393
+ k?: string | undefined;
394
+ key_ops?: string[] | undefined;
395
+ kid?: string | undefined;
396
+ n?: string | undefined;
397
+ p?: string | undefined;
398
+ q?: string | undefined;
399
+ qi?: string | undefined;
400
+ use?: string | undefined;
401
+ x?: string | undefined;
402
+ y?: string | undefined;
403
+ x5c?: string[] | undefined;
404
+ x5t?: string | undefined;
405
+ "x5t#S256"?: string | undefined;
406
+ x5u?: string | undefined;
407
+ }>, "many">;
408
+ }, "strip", z.ZodTypeAny, {
409
+ keys: {
410
+ kty: "RSA" | "EC";
411
+ alg?: string | undefined;
412
+ crv?: string | undefined;
413
+ d?: string | undefined;
414
+ dp?: string | undefined;
415
+ dq?: string | undefined;
416
+ e?: string | undefined;
417
+ ext?: boolean | undefined;
418
+ k?: string | undefined;
419
+ key_ops?: string[] | undefined;
420
+ kid?: string | undefined;
421
+ n?: string | undefined;
422
+ p?: string | undefined;
423
+ q?: string | undefined;
424
+ qi?: string | undefined;
425
+ use?: string | undefined;
426
+ x?: string | undefined;
427
+ y?: string | undefined;
428
+ x5c?: string[] | undefined;
429
+ x5t?: string | undefined;
430
+ "x5t#S256"?: string | undefined;
431
+ x5u?: string | undefined;
432
+ }[];
433
+ }, {
434
+ keys: {
435
+ kty: "RSA" | "EC";
436
+ alg?: string | undefined;
437
+ crv?: string | undefined;
438
+ d?: string | undefined;
439
+ dp?: string | undefined;
440
+ dq?: string | undefined;
441
+ e?: string | undefined;
442
+ ext?: boolean | undefined;
443
+ k?: string | undefined;
444
+ key_ops?: string[] | undefined;
445
+ kid?: string | undefined;
446
+ n?: string | undefined;
447
+ p?: string | undefined;
448
+ q?: string | undefined;
449
+ qi?: string | undefined;
450
+ use?: string | undefined;
451
+ x?: string | undefined;
452
+ y?: string | undefined;
453
+ x5c?: string[] | undefined;
454
+ x5t?: string | undefined;
455
+ "x5t#S256"?: string | undefined;
456
+ x5u?: string | undefined;
457
+ }[];
458
+ }>>;
459
+ }, "strip", z.ZodTypeAny, {
460
+ jwks_uri?: string | undefined;
461
+ jwks?: {
462
+ keys: {
463
+ kty: "RSA" | "EC";
464
+ alg?: string | undefined;
465
+ crv?: string | undefined;
466
+ d?: string | undefined;
467
+ dp?: string | undefined;
468
+ dq?: string | undefined;
469
+ e?: string | undefined;
470
+ ext?: boolean | undefined;
471
+ k?: string | undefined;
472
+ key_ops?: string[] | undefined;
473
+ kid?: string | undefined;
474
+ n?: string | undefined;
475
+ p?: string | undefined;
476
+ q?: string | undefined;
477
+ qi?: string | undefined;
478
+ use?: string | undefined;
479
+ x?: string | undefined;
480
+ y?: string | undefined;
481
+ x5c?: string[] | undefined;
482
+ x5t?: string | undefined;
483
+ "x5t#S256"?: string | undefined;
484
+ x5u?: string | undefined;
485
+ }[];
486
+ } | undefined;
487
+ }, {
488
+ jwks_uri?: string | undefined;
489
+ jwks?: {
490
+ keys: {
491
+ kty: "RSA" | "EC";
492
+ alg?: string | undefined;
493
+ crv?: string | undefined;
494
+ d?: string | undefined;
495
+ dp?: string | undefined;
496
+ dq?: string | undefined;
497
+ e?: string | undefined;
498
+ ext?: boolean | undefined;
499
+ k?: string | undefined;
500
+ key_ops?: string[] | undefined;
501
+ kid?: string | undefined;
502
+ n?: string | undefined;
503
+ p?: string | undefined;
504
+ q?: string | undefined;
505
+ qi?: string | undefined;
506
+ use?: string | undefined;
507
+ x?: string | undefined;
508
+ y?: string | undefined;
509
+ x5c?: string[] | undefined;
510
+ x5t?: string | undefined;
511
+ "x5t#S256"?: string | undefined;
512
+ x5u?: string | undefined;
513
+ }[];
514
+ } | undefined;
515
+ }>>;
335
516
  scope: z.ZodOptional<z.ZodString>;
336
517
  presentation_definition: z.ZodOptional<z.ZodObject<{
337
518
  id: z.ZodString;
@@ -557,10 +738,39 @@ export declare const RequestObject: z.ZodObject<{
557
738
  response_mode: "direct_post.jwt" | "direct_post";
558
739
  client_id: string;
559
740
  response_uri: string;
560
- client_id_scheme: string;
561
741
  iss?: string | undefined;
562
742
  iat?: number | undefined;
563
743
  exp?: number | undefined;
744
+ client_id_scheme?: string | undefined;
745
+ client_metadata?: {
746
+ jwks_uri?: string | undefined;
747
+ jwks?: {
748
+ keys: {
749
+ kty: "RSA" | "EC";
750
+ alg?: string | undefined;
751
+ crv?: string | undefined;
752
+ d?: string | undefined;
753
+ dp?: string | undefined;
754
+ dq?: string | undefined;
755
+ e?: string | undefined;
756
+ ext?: boolean | undefined;
757
+ k?: string | undefined;
758
+ key_ops?: string[] | undefined;
759
+ kid?: string | undefined;
760
+ n?: string | undefined;
761
+ p?: string | undefined;
762
+ q?: string | undefined;
763
+ qi?: string | undefined;
764
+ use?: string | undefined;
765
+ x?: string | undefined;
766
+ y?: string | undefined;
767
+ x5c?: string[] | undefined;
768
+ x5t?: string | undefined;
769
+ "x5t#S256"?: string | undefined;
770
+ x5u?: string | undefined;
771
+ }[];
772
+ } | undefined;
773
+ } | undefined;
564
774
  scope?: string | undefined;
565
775
  presentation_definition?: {
566
776
  id: string;
@@ -606,10 +816,39 @@ export declare const RequestObject: z.ZodObject<{
606
816
  response_mode: "direct_post.jwt" | "direct_post";
607
817
  client_id: string;
608
818
  response_uri: string;
609
- client_id_scheme: string;
610
819
  iss?: string | undefined;
611
820
  iat?: number | undefined;
612
821
  exp?: number | undefined;
822
+ client_id_scheme?: string | undefined;
823
+ client_metadata?: {
824
+ jwks_uri?: string | undefined;
825
+ jwks?: {
826
+ keys: {
827
+ kty: "RSA" | "EC";
828
+ alg?: string | undefined;
829
+ crv?: string | undefined;
830
+ d?: string | undefined;
831
+ dp?: string | undefined;
832
+ dq?: string | undefined;
833
+ e?: string | undefined;
834
+ ext?: boolean | undefined;
835
+ k?: string | undefined;
836
+ key_ops?: string[] | undefined;
837
+ kid?: string | undefined;
838
+ n?: string | undefined;
839
+ p?: string | undefined;
840
+ q?: string | undefined;
841
+ qi?: string | undefined;
842
+ use?: string | undefined;
843
+ x?: string | undefined;
844
+ y?: string | undefined;
845
+ x5c?: string[] | undefined;
846
+ x5t?: string | undefined;
847
+ "x5t#S256"?: string | undefined;
848
+ x5u?: string | undefined;
849
+ }[];
850
+ } | undefined;
851
+ } | undefined;
613
852
  scope?: string | undefined;
614
853
  presentation_definition?: {
615
854
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACO,MAAM;IACzB,MAAM,EAAE;IACsC,aAAa;CACzE,CAAC;AAmBF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO1B,CAAC;AAqBH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC5E,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMjC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAaxB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/credential/presentation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACO,MAAM;IACzB,MAAM,EAAE;IACsC,aAAa;CACzE,CAAC;AAmBF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO1B,CAAC;AAqBH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC5E,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMjC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBxB,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { type CryptoContext } from "@pagopa/io-react-native-jwt";
2
+ import { RSAKey, KJUR } from "jsrsasign";
3
+ import { JWK } from "./jwk";
2
4
  /**
3
5
  * Create a CryptoContext bound to a key pair.
4
6
  * Key pair is supposed to exist already in the device's keychain.
@@ -16,4 +18,26 @@ export declare const createCryptoContextFor: (keytag: string) => CryptoContext;
16
18
  * @returns The returned value of the input procedure.
17
19
  */
18
20
  export declare const withEphemeralKey: <R>(fn: (ephemeralContext: CryptoContext) => Promise<R>) => Promise<R>;
21
+ /**
22
+ * Converts a certificate string to PEM format.
23
+ *
24
+ * @param certificate - The certificate string.
25
+ * @returns The PEM-formatted certificate.
26
+ */
27
+ export declare const convertCertToPem: (certificate: string) => string;
28
+ /**
29
+ * Parses the public key from a PEM-formatted certificate.
30
+ *
31
+ * @param pemCert - The PEM-formatted certificate.
32
+ * @returns The public key object.
33
+ * @throws Will throw an error if the public key is unsupported.
34
+ */
35
+ export declare const parsePublicKey: (pemCert: string) => RSAKey | KJUR.crypto.ECDSA | undefined;
36
+ /**
37
+ * Retrieves the signing JWK from the public key.
38
+ *
39
+ * @param publicKey - The public key object.
40
+ * @returns The signing JWK.
41
+ */
42
+ export declare const getSigningJwk: (publicKey: RSAKey | KJUR.crypto.ECDSA) => JWK;
19
43
  //# sourceMappingURL=crypto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../src/utils/crypto.ts"],"names":[],"mappings":"AAOA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG7E;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,KAAG,aA6BvD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,6BACJ,aAAa,8BAOrC,CAAC"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../src/utils/crypto.ts"],"names":[],"mappings":"AAOA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE7E,OAAO,EAAiB,MAAM,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,KAAG,aA6BvD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,6BACJ,aAAa,8BAOrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,gBAAiB,MAAM,KAAG,MACmB,CAAC;AAE3E;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,YAChB,MAAM,KACd,MAAM,GAAG,KAAK,MAAM,CAAC,KAAK,GAAG,SAU/B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,cAAe,MAAM,GAAG,KAAK,MAAM,CAAC,KAAK,KAAG,GAGpE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/io-react-native-wallet",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Provide data structures, helpers and API for IO Wallet",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -108,10 +108,12 @@
108
108
  ]
109
109
  },
110
110
  "dependencies": {
111
+ "@types/jsrsasign": "^10.5.15",
111
112
  "ajv": "^8.17.1",
112
113
  "js-base64": "^3.7.7",
113
114
  "js-sha256": "^0.9.0",
114
115
  "jsonpath-plus": "^10.2.0",
116
+ "jsrsasign": "^11.1.0",
115
117
  "parse-url": "^9.2.0",
116
118
  "react-native-url-polyfill": "^2.0.0",
117
119
  "react-native-uuid": "^2.0.1",
@@ -1,11 +1,9 @@
1
1
  import * as z from "zod";
2
- import { InvalidQRCodeError } from "./errors";
2
+ import { ValidationFailed } from "../../utils/errors";
3
3
 
4
- const QRCodePayload = z.object({
5
- protocol: z.string(),
6
- resource: z.string(), // TODO: refine to known paths using literals
7
- clientId: z.string(),
8
- requestURI: z.string(),
4
+ const PresentationParams = z.object({
5
+ clientId: z.string().nonempty(),
6
+ requestUri: z.string().url(),
9
7
  });
10
8
 
11
9
  /**
@@ -16,46 +14,32 @@ const QRCodePayload = z.object({
16
14
  * @returns The url for the Relying Party to connect with
17
15
  */
18
16
  export type StartFlow<T extends Array<unknown> = []> = (...args: T) => {
19
- requestURI: string;
17
+ requestUri: string;
20
18
  clientId: string;
21
19
  };
22
20
 
23
21
  /**
24
- * Start a presentation flow by decoding an incoming QR-code
22
+ * Start a presentation flow by decoding the parameters needed to start the presentation flow.
25
23
  *
26
24
  * @param qrcode The encoded QR-code content
27
25
  * @returns The url for the Relying Party to connect with
28
26
  * @throws If the provided qr code fails to be decoded
29
27
  */
30
- export const startFlowFromQR: StartFlow<[string]> = (qrcode) => {
31
- let decodedUrl: URL;
32
- try {
33
- // splitting qrcode to identify which is link format
34
- const originalQrCode = qrcode.split("://");
35
- const replacedQrcode = originalQrCode[1]?.startsWith("?")
36
- ? qrcode.replace(`${originalQrCode[0]}://`, "https://wallet.example/")
37
- : qrcode;
38
-
39
- decodedUrl = new URL(replacedQrcode);
40
- } catch (error) {
41
- throw new InvalidQRCodeError(`Failed to decode QR code: ${qrcode}`);
42
- }
43
-
44
- const protocol = decodedUrl.protocol;
45
- const resource = decodedUrl.hostname;
46
- const requestURI = decodedUrl.searchParams.get("request_uri");
47
- const clientId = decodedUrl.searchParams.get("client_id");
48
-
49
- const result = QRCodePayload.safeParse({
50
- protocol,
51
- resource,
52
- requestURI,
28
+ export const startFlowFromQR: StartFlow<[string, string]> = (
29
+ requestUri: string,
30
+ clientId: string
31
+ ) => {
32
+ const result = PresentationParams.safeParse({
33
+ requestUri,
53
34
  clientId,
54
35
  });
55
36
 
56
37
  if (result.success) {
57
38
  return result.data;
58
39
  } else {
59
- throw new InvalidQRCodeError(`${result.error.message}, ${decodedUrl}`);
40
+ throw new ValidationFailed({
41
+ message: "Invalid parameters provided",
42
+ reason: result.error.message,
43
+ });
60
44
  }
61
45
  };
@@ -9,7 +9,7 @@ import { hasStatusOrThrow, type Out } from "../../utils/misc";
9
9
  import type { StartFlow } from "./01-start-flow";
10
10
 
11
11
  export type GetRequestObject = (
12
- requestUri: Out<StartFlow>["requestURI"],
12
+ requestUri: Out<StartFlow>["requestUri"],
13
13
  context: {
14
14
  wiaCryptoContext: CryptoContext;
15
15
  appFetch?: GlobalFetch["fetch"];
@@ -3,6 +3,12 @@ import { hasStatusOrThrow } from "../../utils/misc";
3
3
  import { RelyingPartyEntityConfiguration } from "../../entity/trust/types";
4
4
  import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
5
5
  import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
6
+ import { RequestObject } from "./types";
7
+ import {
8
+ convertCertToPem,
9
+ parsePublicKey,
10
+ getSigningJwk,
11
+ } from "../../utils/crypto";
6
12
 
7
13
  /**
8
14
  * Defines the signature for a function that retrieves JSON Web Key Sets (JWKS) from a client.
@@ -16,54 +22,136 @@ export type FetchJwks<T extends Array<unknown> = []> = (...args: T) => Promise<{
16
22
  }>;
17
23
 
18
24
  /**
19
- * Retrieves the JSON Web Key Set (JWKS) from the specified client's well-known endpoint.
20
- * It is formed using `{issUrl.base}/.well-known/jar-issuer${issUrl.pah}` as explained in SD-JWT VC issuer metadata section
25
+ * Fetches and parses JWKS from a given URI.
21
26
  *
22
- * @param requestObjectEncodedJwt - Request Object in JWT format.
23
- * @param options - Optional context containing a custom fetch implementation.
24
- * @param options.context - Optional context object.
25
- * @param options.context.appFetch - Optional custom fetch function to use instead of the global `fetch`.
26
- * @returns A promise resolving to an object containing an array of JWKs.
27
- * @throws Will throw an error if the JWKS retrieval fails.
27
+ * @param jwksUri - The JWKS URI.
28
+ * @param fetchFn - The fetch function to use.
29
+ * @returns An array of JWKs.
30
+ */
31
+ const fetchJwksFromUri = async (
32
+ jwksUri: string,
33
+ appFetch: GlobalFetch["fetch"]
34
+ ): Promise<JWK[]> => {
35
+ const jwks = await appFetch(jwksUri, {
36
+ method: "GET",
37
+ })
38
+ .then(hasStatusOrThrow(200))
39
+ .then((raw) => raw.json())
40
+ .then((json) => (json.jwks ? JWKS.parse(json.jwks) : JWKS.parse(json)));
41
+ return jwks.keys;
42
+ };
43
+
44
+ /**
45
+ * Retrieves JWKS when the client ID scheme includes x509 SAN DNS.
46
+ *
47
+ * @param decodedJwt - The decoded JWT.
48
+ * @param fetchFn - The fetch function to use.
49
+ * @returns An array of JWKs.
50
+ * @throws Will throw an error if no suitable keys are found.
51
+ */
52
+ const getJwksFromX509Cert = async (certChain: string[]): Promise<JWK[]> => {
53
+ if (!Array.isArray(certChain) || certChain.length === 0 || !certChain[0]) {
54
+ throw new NoSuitableKeysFoundInEntityConfiguration(
55
+ "No RP encrypt key found!"
56
+ );
57
+ }
58
+
59
+ const pemCert = convertCertToPem(certChain[0]);
60
+ const publicKey = parsePublicKey(pemCert);
61
+ if (!publicKey) {
62
+ throw new NoSuitableKeysFoundInEntityConfiguration(
63
+ "Unsupported public key type."
64
+ );
65
+ }
66
+ const signingJwk = getSigningJwk(publicKey);
67
+
68
+ return [signingJwk];
69
+ };
70
+
71
+ /**
72
+ * Constructs the well-known JWKS URL based on the issuer claim.
73
+ *
74
+ * @param issuer - The issuer URL.
75
+ * @returns The well-known JWKS URL.
76
+ */
77
+ const constructWellKnownJwksUrl = (issuer: string): string => {
78
+ const issuerUrl = new URL(issuer);
79
+ return new URL(
80
+ `/.well-known/jar-issuer${issuerUrl.pathname}`,
81
+ `${issuerUrl.protocol}//${issuerUrl.host}`
82
+ ).toString();
83
+ };
84
+
85
+ /**
86
+ * Fetches the JSON Web Key Set (JWKS) based on the provided Request Object encoded as a JWT.
87
+ * The retrieval process follows these steps in order:
88
+ *
89
+ * 1. **Direct JWK Retrieval**: If the JWT's protected header contains a `jwk` attribute, it uses this key directly.
90
+ * 2. **X.509 Certificate Retrieval**: If the protected header includes an `x5c` attribute, it extracts the JWKs from the provided X.509 certificate chain.
91
+ * 3. **Issuer's Well-Known Endpoint**: If neither `jwk` nor `x5c` are present, it constructs the JWKS URL using the issuer (`iss`) claim and fetches the keys from the issuer's well-known JWKS endpoint.
92
+ *
93
+ * The JWKS URL is constructed in the format `{issUrl.base}/.well-known/jar-issuer${issUrl.path}`,
94
+ * as detailed in the SD-JWT VC issuer metadata specification.
95
+ *
96
+ * @param requestObjectEncodedJwt - The Request Object encoded as a JWT.
97
+ * @param options - Optional parameters for fetching the JWKS.
98
+ * @param options.context - Optional context providing a custom fetch implementation.
99
+ * @param options.context.appFetch - A custom fetch function to replace the global `fetch` if provided.
100
+ * @returns A promise that resolves to an object containing an array of JSON Web Keys (JWKs).
101
+ * @throws {NoSuitableKeysFoundInEntityConfiguration} Throws an error if JWKS retrieval or key extraction fails.
28
102
  */
29
103
  export const fetchJwksFromRequestObject: FetchJwks<
30
104
  [string, { context?: { appFetch?: GlobalFetch["fetch"] } }?]
31
105
  > = async (requestObjectEncodedJwt, { context = {} } = {}) => {
32
106
  const { appFetch = fetch } = context;
33
107
  const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
108
+ const jwks: JWK[] = [];
34
109
 
35
110
  // 1. check if request object jwt contains the 'jwk' attribute
36
111
  if (requestObjectJwt.protectedHeader?.jwk) {
37
- return {
38
- keys: [JWK.parse(requestObjectJwt.protectedHeader.jwk)],
39
- };
112
+ const keys = [JWK.parse(requestObjectJwt.protectedHeader.jwk)];
113
+ jwks.push(...keys);
114
+ }
115
+
116
+ // 2. check if request object jwt contains the 'x5c' attribute
117
+ if (requestObjectJwt.protectedHeader.x5c) {
118
+ const keys = await getJwksFromX509Cert(
119
+ requestObjectJwt.protectedHeader.x5c
120
+ );
121
+ jwks.push(...keys);
122
+ }
123
+
124
+ // 3. check if client_metadata contains the 'jwks' or 'jwks_uri' attribute
125
+ const requestObject = RequestObject.parse(requestObjectJwt.payload);
126
+ const { client_metadata } = requestObject;
127
+
128
+ if (client_metadata?.jwks_uri) {
129
+ const fetchedJwks = await fetchJwksFromUri(
130
+ new URL(client_metadata.jwks_uri).toString(),
131
+ appFetch
132
+ );
133
+ jwks.push(...fetchedJwks);
134
+ }
135
+
136
+ if (client_metadata?.jwks) {
137
+ jwks.push(...client_metadata.jwks.keys);
138
+ }
139
+
140
+ // 3. According to Potential profile, retrieve from RP endpoint using iss claim
141
+ const issuer = requestObjectJwt.payload?.iss;
142
+ if (jwks.length === 0 && typeof issuer === "string") {
143
+ const wellKnownJwksUrl = constructWellKnownJwksUrl(issuer);
144
+ const jwksKeys = await fetchJwksFromUri(wellKnownJwksUrl, appFetch);
145
+ jwks.push(...jwksKeys);
40
146
  }
41
147
 
42
- // 2. According to Potential profile, retrieve from RP endpoint using iss claim
43
- const issClaimValue = requestObjectJwt.payload?.iss as string;
44
- if (issClaimValue) {
45
- const issUrl = new URL(issClaimValue);
46
- const wellKnownUrl = new URL(
47
- `/.well-known/jar-issuer${issUrl.pathname}`,
48
- `${issUrl.protocol}//${issUrl.host}`
49
- ).toString();
50
-
51
- // Fetches the JWKS from a specific endpoint of the entity's well-known configuration
52
- const jwks = await appFetch(wellKnownUrl, {
53
- method: "GET",
54
- })
55
- .then(hasStatusOrThrow(200))
56
- .then((raw) => raw.json())
57
- .then((json) => JWKS.parse(json.jwks));
58
-
59
- return {
60
- keys: jwks.keys,
61
- };
148
+ if (jwks.length === 0) {
149
+ throw new NoSuitableKeysFoundInEntityConfiguration(
150
+ "Request Object signature verification"
151
+ );
62
152
  }
63
153
 
64
- throw new NoSuitableKeysFoundInEntityConfiguration(
65
- "Request Object signature verification"
66
- );
154
+ return { keys: jwks };
67
155
  };
68
156
 
69
157
  /**