@pagopa/io-react-native-wallet 1.1.2 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/lib/commonjs/credential/presentation/01-start-flow.js +7 -5
  2. package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
  3. package/lib/commonjs/credential/presentation/03-get-request-object.js +47 -0
  4. package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -0
  5. package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js +82 -0
  6. package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
  7. package/lib/commonjs/credential/presentation/05-verify-request-object.js +35 -0
  8. package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -0
  9. package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js +63 -0
  10. package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
  11. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +169 -0
  12. package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
  13. package/lib/commonjs/credential/presentation/08-send-authorization-response.js +202 -0
  14. package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -0
  15. package/lib/commonjs/credential/presentation/README.md +43 -4
  16. package/lib/commonjs/credential/presentation/errors.js +52 -1
  17. package/lib/commonjs/credential/presentation/errors.js.map +1 -1
  18. package/lib/commonjs/credential/presentation/index.js +27 -6
  19. package/lib/commonjs/credential/presentation/index.js.map +1 -1
  20. package/lib/commonjs/credential/presentation/types.js +69 -4
  21. package/lib/commonjs/credential/presentation/types.js.map +1 -1
  22. package/lib/commonjs/entity/trust/types.js +4 -1
  23. package/lib/commonjs/entity/trust/types.js.map +1 -1
  24. package/lib/module/credential/presentation/01-start-flow.js +8 -6
  25. package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
  26. package/lib/module/credential/presentation/03-get-request-object.js +39 -0
  27. package/lib/module/credential/presentation/03-get-request-object.js.map +1 -0
  28. package/lib/module/credential/presentation/04-retrieve-rp-jwks.js +75 -0
  29. package/lib/module/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
  30. package/lib/module/credential/presentation/05-verify-request-object.js +28 -0
  31. package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -0
  32. package/lib/module/credential/presentation/06-fetch-presentation-definition.js +56 -0
  33. package/lib/module/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
  34. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +161 -0
  35. package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
  36. package/lib/module/credential/presentation/08-send-authorization-response.js +188 -0
  37. package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -0
  38. package/lib/module/credential/presentation/README.md +43 -4
  39. package/lib/module/credential/presentation/errors.js +48 -0
  40. package/lib/module/credential/presentation/errors.js.map +1 -1
  41. package/lib/module/credential/presentation/index.js +7 -4
  42. package/lib/module/credential/presentation/index.js.map +1 -1
  43. package/lib/module/credential/presentation/types.js +67 -3
  44. package/lib/module/credential/presentation/types.js.map +1 -1
  45. package/lib/module/entity/trust/types.js +4 -1
  46. package/lib/module/entity/trust/types.js.map +1 -1
  47. package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
  48. package/lib/typescript/credential/presentation/{04-get-request-object.d.ts → 03-get-request-object.d.ts} +3 -5
  49. package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -0
  50. package/lib/typescript/credential/presentation/{03-retrieve-jwks.d.ts → 04-retrieve-rp-jwks.d.ts} +5 -4
  51. package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts.map +1 -0
  52. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts +8 -0
  53. package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -0
  54. package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts +26 -0
  55. package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts.map +1 -0
  56. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +27 -0
  57. package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -0
  58. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +99 -0
  59. package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -0
  60. package/lib/typescript/credential/presentation/errors.d.ts +33 -0
  61. package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
  62. package/lib/typescript/credential/presentation/index.d.ts +8 -5
  63. package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
  64. package/lib/typescript/credential/presentation/types.d.ts +612 -9
  65. package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
  66. package/lib/typescript/entity/trust/index.d.ts +152 -0
  67. package/lib/typescript/entity/trust/index.d.ts.map +1 -1
  68. package/lib/typescript/entity/trust/types.d.ts +2088 -0
  69. package/lib/typescript/entity/trust/types.d.ts.map +1 -1
  70. package/package.json +5 -1
  71. package/src/credential/presentation/01-start-flow.ts +10 -6
  72. package/src/credential/presentation/{04-get-request-object.ts → 03-get-request-object.ts} +6 -51
  73. package/src/credential/presentation/{03-retrieve-jwks.ts → 04-retrieve-rp-jwks.ts} +39 -24
  74. package/src/credential/presentation/05-verify-request-object.ts +35 -0
  75. package/src/credential/presentation/06-fetch-presentation-definition.ts +78 -0
  76. package/src/credential/presentation/07-evaluate-input-descriptor.ts +204 -0
  77. package/src/credential/presentation/08-send-authorization-response.ts +251 -0
  78. package/src/credential/presentation/README.md +43 -4
  79. package/src/credential/presentation/errors.ts +48 -0
  80. package/src/credential/presentation/index.ts +27 -9
  81. package/src/credential/presentation/types.ts +59 -3
  82. package/src/entity/trust/types.ts +3 -0
  83. package/lib/commonjs/credential/presentation/03-retrieve-jwks.js +0 -68
  84. package/lib/commonjs/credential/presentation/03-retrieve-jwks.js.map +0 -1
  85. package/lib/commonjs/credential/presentation/04-get-request-object.js +0 -82
  86. package/lib/commonjs/credential/presentation/04-get-request-object.js.map +0 -1
  87. package/lib/commonjs/credential/presentation/05-send-authorization-response.js +0 -139
  88. package/lib/commonjs/credential/presentation/05-send-authorization-response.js.map +0 -1
  89. package/lib/module/credential/presentation/03-retrieve-jwks.js +0 -61
  90. package/lib/module/credential/presentation/03-retrieve-jwks.js.map +0 -1
  91. package/lib/module/credential/presentation/04-get-request-object.js +0 -74
  92. package/lib/module/credential/presentation/04-get-request-object.js.map +0 -1
  93. package/lib/module/credential/presentation/05-send-authorization-response.js +0 -128
  94. package/lib/module/credential/presentation/05-send-authorization-response.js.map +0 -1
  95. package/lib/typescript/credential/presentation/03-retrieve-jwks.d.ts.map +0 -1
  96. package/lib/typescript/credential/presentation/04-get-request-object.d.ts.map +0 -1
  97. package/lib/typescript/credential/presentation/05-send-authorization-response.d.ts +0 -34
  98. package/lib/typescript/credential/presentation/05-send-authorization-response.d.ts.map +0 -1
  99. package/src/credential/presentation/05-send-authorization-response.ts +0 -168
@@ -1,6 +1,5 @@
1
1
  import * as z from "zod";
2
- import { decodeBase64 } from "@pagopa/io-react-native-jwt";
3
- import { AuthRequestDecodeError } from "./errors";
2
+ import { InvalidQRCodeError } from "./errors";
4
3
  const QRCodePayload = z.object({
5
4
  protocol: z.string(),
6
5
  resource: z.string(),
@@ -27,10 +26,13 @@ const QRCodePayload = z.object({
27
26
  export const startFlowFromQR = qrcode => {
28
27
  let decodedUrl;
29
28
  try {
30
- const decoded = decodeBase64(qrcode);
31
- decodedUrl = new URL(decoded);
29
+ var _originalQrCode$;
30
+ // splitting qrcode to identify which is link format
31
+ const originalQrCode = qrcode.split("://");
32
+ const replacedQrcode = (_originalQrCode$ = originalQrCode[1]) !== null && _originalQrCode$ !== void 0 && _originalQrCode$.startsWith("?") ? qrcode.replace(`${originalQrCode[0]}://`, "https://wallet.example/") : qrcode;
33
+ decodedUrl = new URL(replacedQrcode);
32
34
  } catch (error) {
33
- throw new AuthRequestDecodeError("Failed to decode QR code: ", qrcode);
35
+ throw new InvalidQRCodeError(`Failed to decode QR code: ${qrcode}`);
34
36
  }
35
37
  const protocol = decodedUrl.protocol;
36
38
  const resource = decodedUrl.hostname;
@@ -45,7 +47,7 @@ export const startFlowFromQR = qrcode => {
45
47
  if (result.success) {
46
48
  return result.data;
47
49
  } else {
48
- throw new AuthRequestDecodeError(result.error.message, `${decodedUrl}`);
50
+ throw new InvalidQRCodeError(`${result.error.message}, ${decodedUrl}`);
49
51
  }
50
52
  };
51
53
  //# sourceMappingURL=01-start-flow.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["z","decodeBase64","AuthRequestDecodeError","QRCodePayload","object","protocol","string","resource","clientId","requestURI","startFlowFromQR","qrcode","decodedUrl","decoded","URL","error","hostname","searchParams","get","result","safeParse","success","data","message"],"sourceRoot":"../../../../src","sources":["credential/presentation/01-start-flow.ts"],"mappings":"AAAA,OAAO,KAAKA,CAAC,MAAM,KAAK;AACxB,SAASC,YAAY,QAAQ,6BAA6B;AAC1D,SAASC,sBAAsB,QAAQ,UAAU;AAEjD,MAAMC,aAAa,GAAGH,CAAC,CAACI,MAAM,CAAC;EAC7BC,QAAQ,EAAEL,CAAC,CAACM,MAAM,CAAC,CAAC;EACpBC,QAAQ,EAAEP,CAAC,CAACM,MAAM,CAAC,CAAC;EAAE;EACtBE,QAAQ,EAAER,CAAC,CAACM,MAAM,CAAC,CAAC;EACpBG,UAAU,EAAET,CAAC,CAACM,MAAM,CAAC;AACvB,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMI,eAAoC,GAAIC,MAAM,IAAK;EAC9D,IAAIC,UAAe;EACnB,IAAI;IACF,MAAMC,OAAO,GAAGZ,YAAY,CAACU,MAAM,CAAC;IACpCC,UAAU,GAAG,IAAIE,GAAG,CAACD,OAAO,CAAC;EAC/B,CAAC,CAAC,OAAOE,KAAK,EAAE;IACd,MAAM,IAAIb,sBAAsB,CAAC,4BAA4B,EAAES,MAAM,CAAC;EACxE;EAEA,MAAMN,QAAQ,GAAGO,UAAU,CAACP,QAAQ;EACpC,MAAME,QAAQ,GAAGK,UAAU,CAACI,QAAQ;EACpC,MAAMP,UAAU,GAAGG,UAAU,CAACK,YAAY,CAACC,GAAG,CAAC,aAAa,CAAC;EAC7D,MAAMV,QAAQ,GAAGI,UAAU,CAACK,YAAY,CAACC,GAAG,CAAC,WAAW,CAAC;EAEzD,MAAMC,MAAM,GAAGhB,aAAa,CAACiB,SAAS,CAAC;IACrCf,QAAQ;IACRE,QAAQ;IACRE,UAAU;IACVD;EACF,CAAC,CAAC;EAEF,IAAIW,MAAM,CAACE,OAAO,EAAE;IAClB,OAAOF,MAAM,CAACG,IAAI;EACpB,CAAC,MAAM;IACL,MAAM,IAAIpB,sBAAsB,CAACiB,MAAM,CAACJ,KAAK,CAACQ,OAAO,EAAG,GAAEX,UAAW,EAAC,CAAC;EACzE;AACF,CAAC"}
1
+ {"version":3,"names":["z","InvalidQRCodeError","QRCodePayload","object","protocol","string","resource","clientId","requestURI","startFlowFromQR","qrcode","decodedUrl","_originalQrCode$","originalQrCode","split","replacedQrcode","startsWith","replace","URL","error","hostname","searchParams","get","result","safeParse","success","data","message"],"sourceRoot":"../../../../src","sources":["credential/presentation/01-start-flow.ts"],"mappings":"AAAA,OAAO,KAAKA,CAAC,MAAM,KAAK;AACxB,SAASC,kBAAkB,QAAQ,UAAU;AAE7C,MAAMC,aAAa,GAAGF,CAAC,CAACG,MAAM,CAAC;EAC7BC,QAAQ,EAAEJ,CAAC,CAACK,MAAM,CAAC,CAAC;EACpBC,QAAQ,EAAEN,CAAC,CAACK,MAAM,CAAC,CAAC;EAAE;EACtBE,QAAQ,EAAEP,CAAC,CAACK,MAAM,CAAC,CAAC;EACpBG,UAAU,EAAER,CAAC,CAACK,MAAM,CAAC;AACvB,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMI,eAAoC,GAAIC,MAAM,IAAK;EAC9D,IAAIC,UAAe;EACnB,IAAI;IAAA,IAAAC,gBAAA;IACF;IACA,MAAMC,cAAc,GAAGH,MAAM,CAACI,KAAK,CAAC,KAAK,CAAC;IAC1C,MAAMC,cAAc,GAAG,CAAAH,gBAAA,GAAAC,cAAc,CAAC,CAAC,CAAC,cAAAD,gBAAA,eAAjBA,gBAAA,CAAmBI,UAAU,CAAC,GAAG,CAAC,GACrDN,MAAM,CAACO,OAAO,CAAE,GAAEJ,cAAc,CAAC,CAAC,CAAE,KAAI,EAAE,yBAAyB,CAAC,GACpEH,MAAM;IAEVC,UAAU,GAAG,IAAIO,GAAG,CAACH,cAAc,CAAC;EACtC,CAAC,CAAC,OAAOI,KAAK,EAAE;IACd,MAAM,IAAIlB,kBAAkB,CAAE,8BAA6BS,MAAO,EAAC,CAAC;EACtE;EAEA,MAAMN,QAAQ,GAAGO,UAAU,CAACP,QAAQ;EACpC,MAAME,QAAQ,GAAGK,UAAU,CAACS,QAAQ;EACpC,MAAMZ,UAAU,GAAGG,UAAU,CAACU,YAAY,CAACC,GAAG,CAAC,aAAa,CAAC;EAC7D,MAAMf,QAAQ,GAAGI,UAAU,CAACU,YAAY,CAACC,GAAG,CAAC,WAAW,CAAC;EAEzD,MAAMC,MAAM,GAAGrB,aAAa,CAACsB,SAAS,CAAC;IACrCpB,QAAQ;IACRE,QAAQ;IACRE,UAAU;IACVD;EACF,CAAC,CAAC;EAEF,IAAIgB,MAAM,CAACE,OAAO,EAAE;IAClB,OAAOF,MAAM,CAACG,IAAI;EACpB,CAAC,MAAM;IACL,MAAM,IAAIzB,kBAAkB,CAAE,GAAEsB,MAAM,CAACJ,KAAK,CAACQ,OAAQ,KAAIhB,UAAW,EAAC,CAAC;EACxE;AACF,CAAC"}
@@ -0,0 +1,39 @@
1
+ import uuid from "react-native-uuid";
2
+ import { sha256ToBase64 } from "@pagopa/io-react-native-jwt";
3
+ import { createDPopToken } from "../../utils/dpop";
4
+ import { hasStatusOrThrow } from "../../utils/misc";
5
+ /**
6
+ * Obtain the Request Object for RP authentication
7
+ * @see https://italia.github.io/eudi-wallet-it-docs/versione-corrente/en/relying-party-solution.html
8
+ *
9
+ * @param requestUri The url for the Relying Party to connect with
10
+ * @param rpConf The Relying Party's configuration
11
+ * @param context.wiaCryptoContext The context to access the key associated with the Wallet Instance Attestation
12
+ * @param context.walletInstanceAttestation The Wallet Instance Attestation token
13
+ * @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
14
+ * @returns The Request Object that describes the presentation
15
+ */
16
+ export const getRequestObject = async (requestUri, _ref) => {
17
+ let {
18
+ wiaCryptoContext,
19
+ appFetch = fetch,
20
+ walletInstanceAttestation
21
+ } = _ref;
22
+ const signedWalletInstanceDPoP = await createDPopToken({
23
+ jti: `${uuid.v4()}`,
24
+ htm: "GET",
25
+ htu: requestUri,
26
+ ath: await sha256ToBase64(walletInstanceAttestation)
27
+ }, wiaCryptoContext);
28
+ const requestObjectEncodedJwt = await appFetch(requestUri, {
29
+ method: "GET",
30
+ headers: {
31
+ Authorization: `DPoP ${walletInstanceAttestation}`,
32
+ DPoP: signedWalletInstanceDPoP
33
+ }
34
+ }).then(hasStatusOrThrow(200)).then(res => res.text());
35
+ return {
36
+ requestObjectEncodedJwt
37
+ };
38
+ };
39
+ //# sourceMappingURL=03-get-request-object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["uuid","sha256ToBase64","createDPopToken","hasStatusOrThrow","getRequestObject","requestUri","_ref","wiaCryptoContext","appFetch","fetch","walletInstanceAttestation","signedWalletInstanceDPoP","jti","v4","htm","htu","ath","requestObjectEncodedJwt","method","headers","Authorization","DPoP","then","res","text"],"sourceRoot":"../../../../src","sources":["credential/presentation/03-get-request-object.ts"],"mappings":"AAAA,OAAOA,IAAI,MAAM,mBAAmB;AACpC,SACEC,cAAc,QAET,6BAA6B;AAEpC,SAASC,eAAe,QAAQ,kBAAkB;AAClD,SAASC,gBAAgB,QAAkB,kBAAkB;AAY7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAkC,GAAG,MAAAA,CAChDC,UAAU,EAAAC,IAAA,KAEP;EAAA,IADH;IAAEC,gBAAgB;IAAEC,QAAQ,GAAGC,KAAK;IAAEC;EAA0B,CAAC,GAAAJ,IAAA;EAEjE,MAAMK,wBAAwB,GAAG,MAAMT,eAAe,CACpD;IACEU,GAAG,EAAG,GAAEZ,IAAI,CAACa,EAAE,CAAC,CAAE,EAAC;IACnBC,GAAG,EAAE,KAAK;IACVC,GAAG,EAAEV,UAAU;IACfW,GAAG,EAAE,MAAMf,cAAc,CAACS,yBAAyB;EACrD,CAAC,EACDH,gBACF,CAAC;EAED,MAAMU,uBAAuB,GAAG,MAAMT,QAAQ,CAACH,UAAU,EAAE;IACzDa,MAAM,EAAE,KAAK;IACbC,OAAO,EAAE;MACPC,aAAa,EAAG,QAAOV,yBAA0B,EAAC;MAClDW,IAAI,EAAEV;IACR;EACF,CAAC,CAAC,CACCW,IAAI,CAACnB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3BmB,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC;EAE5B,OAAO;IACLP;EACF,CAAC;AACH,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { JWKS, JWK } from "../../utils/jwk";
2
+ import { hasStatusOrThrow } from "../../utils/misc";
3
+ import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
4
+ import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
5
+
6
+ /**
7
+ * Defines the signature for a function that retrieves JSON Web Key Sets (JWKS) from a client.
8
+ *
9
+ * @template T - The tuple type representing the function arguments.
10
+ * @param args - The arguments passed to the function.
11
+ * @returns A promise resolving to an object containing an array of JWKs.
12
+ */
13
+
14
+ /**
15
+ * Retrieves the JSON Web Key Set (JWKS) from the specified client's well-known endpoint.
16
+ * It is formed using `{issUrl.base}/.well-known/jar-issuer${issUrl.pah}` as explained in SD-JWT VC issuer metadata section
17
+ *
18
+ * @param requestObjectEncodedJwt - Request Object in JWT format.
19
+ * @param options - Optional context containing a custom fetch implementation.
20
+ * @param options.context - Optional context object.
21
+ * @param options.context.appFetch - Optional custom fetch function to use instead of the global `fetch`.
22
+ * @returns A promise resolving to an object containing an array of JWKs.
23
+ * @throws Will throw an error if the JWKS retrieval fails.
24
+ */
25
+ export const fetchJwksFromRequestObject = async function (requestObjectEncodedJwt) {
26
+ var _requestObjectJwt$pro, _requestObjectJwt$pay;
27
+ let {
28
+ context = {}
29
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
30
+ const {
31
+ appFetch = fetch
32
+ } = context;
33
+ const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
34
+
35
+ // 1. check if request object jwt contains the 'jwk' attribute
36
+ if ((_requestObjectJwt$pro = requestObjectJwt.protectedHeader) !== null && _requestObjectJwt$pro !== void 0 && _requestObjectJwt$pro.jwk) {
37
+ return {
38
+ keys: [JWK.parse(requestObjectJwt.protectedHeader.jwk)]
39
+ };
40
+ }
41
+
42
+ // 2. According to Potential profile, retrieve from RP endpoint using iss claim
43
+ const issClaimValue = (_requestObjectJwt$pay = requestObjectJwt.payload) === null || _requestObjectJwt$pay === void 0 ? void 0 : _requestObjectJwt$pay.iss;
44
+ if (issClaimValue) {
45
+ const issUrl = new URL(issClaimValue);
46
+ const wellKnownUrl = new URL(`/.well-known/jar-issuer${issUrl.pathname}`, `${issUrl.protocol}//${issUrl.host}`).toString();
47
+
48
+ // Fetches the JWKS from a specific endpoint of the entity's well-known configuration
49
+ const jwks = await appFetch(wellKnownUrl, {
50
+ method: "GET"
51
+ }).then(hasStatusOrThrow(200)).then(raw => raw.json()).then(json => JWKS.parse(json.jwks));
52
+ return {
53
+ keys: jwks.keys
54
+ };
55
+ }
56
+ throw new NoSuitableKeysFoundInEntityConfiguration("Request Object signature verification");
57
+ };
58
+
59
+ /**
60
+ * Retrieves the JSON Web Key Set (JWKS) from a Relying Party's entity configuration.
61
+ *
62
+ * @param rpConfig - The configuration object of the Relying Party entity.
63
+ * @returns An object containing an array of JWKs.
64
+ * @throws Will throw an error if the configuration is invalid or if JWKS is not found.
65
+ */
66
+ export const fetchJwksFromConfig = async rpConfig => {
67
+ const jwks = rpConfig.wallet_relying_party.jwks;
68
+ if (!jwks || !Array.isArray(jwks.keys)) {
69
+ throw new Error("JWKS not found in Relying Party configuration.");
70
+ }
71
+ return {
72
+ keys: jwks.keys
73
+ };
74
+ };
75
+ //# sourceMappingURL=04-retrieve-rp-jwks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["JWKS","JWK","hasStatusOrThrow","decode","decodeJwt","NoSuitableKeysFoundInEntityConfiguration","fetchJwksFromRequestObject","requestObjectEncodedJwt","_requestObjectJwt$pro","_requestObjectJwt$pay","context","arguments","length","undefined","appFetch","fetch","requestObjectJwt","protectedHeader","jwk","keys","parse","issClaimValue","payload","iss","issUrl","URL","wellKnownUrl","pathname","protocol","host","toString","jwks","method","then","raw","json","fetchJwksFromConfig","rpConfig","wallet_relying_party","Array","isArray","Error"],"sourceRoot":"../../../../src","sources":["credential/presentation/04-retrieve-rp-jwks.ts"],"mappings":"AAAA,SAASA,IAAI,EAAEC,GAAG,QAAQ,iBAAiB;AAC3C,SAASC,gBAAgB,QAAQ,kBAAkB;AAEnD,SAASC,MAAM,IAAIC,SAAS,QAAQ,6BAA6B;AACjE,SAASC,wCAAwC,QAAQ,UAAU;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,0BAEZ,GAAG,eAAAA,CAAOC,uBAAuB,EAA4B;EAAA,IAAAC,qBAAA,EAAAC,qBAAA;EAAA,IAA1B;IAAEC,OAAO,GAAG,CAAC;EAAE,CAAC,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EACvD,MAAM;IAAEG,QAAQ,GAAGC;EAAM,CAAC,GAAGL,OAAO;EACpC,MAAMM,gBAAgB,GAAGZ,SAAS,CAACG,uBAAuB,CAAC;;EAE3D;EACA,KAAAC,qBAAA,GAAIQ,gBAAgB,CAACC,eAAe,cAAAT,qBAAA,eAAhCA,qBAAA,CAAkCU,GAAG,EAAE;IACzC,OAAO;MACLC,IAAI,EAAE,CAAClB,GAAG,CAACmB,KAAK,CAACJ,gBAAgB,CAACC,eAAe,CAACC,GAAG,CAAC;IACxD,CAAC;EACH;;EAEA;EACA,MAAMG,aAAa,IAAAZ,qBAAA,GAAGO,gBAAgB,CAACM,OAAO,cAAAb,qBAAA,uBAAxBA,qBAAA,CAA0Bc,GAAa;EAC7D,IAAIF,aAAa,EAAE;IACjB,MAAMG,MAAM,GAAG,IAAIC,GAAG,CAACJ,aAAa,CAAC;IACrC,MAAMK,YAAY,GAAG,IAAID,GAAG,CACzB,0BAAyBD,MAAM,CAACG,QAAS,EAAC,EAC1C,GAAEH,MAAM,CAACI,QAAS,KAAIJ,MAAM,CAACK,IAAK,EACrC,CAAC,CAACC,QAAQ,CAAC,CAAC;;IAEZ;IACA,MAAMC,IAAI,GAAG,MAAMjB,QAAQ,CAACY,YAAY,EAAE;MACxCM,MAAM,EAAE;IACV,CAAC,CAAC,CACCC,IAAI,CAAC/B,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3B+B,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBF,IAAI,CAAEE,IAAI,IAAKnC,IAAI,CAACoB,KAAK,CAACe,IAAI,CAACJ,IAAI,CAAC,CAAC;IAExC,OAAO;MACLZ,IAAI,EAAEY,IAAI,CAACZ;IACb,CAAC;EACH;EAEA,MAAM,IAAId,wCAAwC,CAChD,uCACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM+B,mBAEZ,GAAG,MAAOC,QAAQ,IAAK;EACtB,MAAMN,IAAI,GAAGM,QAAQ,CAACC,oBAAoB,CAACP,IAAI;EAE/C,IAAI,CAACA,IAAI,IAAI,CAACQ,KAAK,CAACC,OAAO,CAACT,IAAI,CAACZ,IAAI,CAAC,EAAE;IACtC,MAAM,IAAIsB,KAAK,CAAC,gDAAgD,CAAC;EACnE;EAEA,OAAO;IACLtB,IAAI,EAAEY,IAAI,CAACZ;EACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { UnverifiedEntityError } from "./errors";
2
+ import { decode as decodeJwt, verify } from "@pagopa/io-react-native-jwt";
3
+ import { RequestObject } from "./types";
4
+ export const verifyRequestObjectSignature = async (requestObjectEncodedJwt, jwkKeys) => {
5
+ const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
6
+
7
+ // verify token signature to ensure the request object is authentic
8
+ const pubKey = jwkKeys === null || jwkKeys === void 0 ? void 0 : jwkKeys.find(_ref => {
9
+ let {
10
+ kid
11
+ } = _ref;
12
+ return kid === requestObjectJwt.protectedHeader.kid;
13
+ });
14
+ if (!pubKey) {
15
+ throw new UnverifiedEntityError("Request Object signature verification!");
16
+ }
17
+ await verify(requestObjectEncodedJwt, pubKey);
18
+ const requestObject = RequestObject.parse(requestObjectJwt.payload);
19
+ // Check if exp exists and is expired
20
+ // exp is typically in seconds since epoch, Get current time in seconds
21
+ if (requestObject.exp && requestObject.exp <= Date.now() / 1000) {
22
+ throw new UnverifiedEntityError("Request Object is expired!");
23
+ }
24
+ return {
25
+ requestObject
26
+ };
27
+ };
28
+ //# sourceMappingURL=05-verify-request-object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UnverifiedEntityError","decode","decodeJwt","verify","RequestObject","verifyRequestObjectSignature","requestObjectEncodedJwt","jwkKeys","requestObjectJwt","pubKey","find","_ref","kid","protectedHeader","requestObject","parse","payload","exp","Date","now"],"sourceRoot":"../../../../src","sources":["credential/presentation/05-verify-request-object.ts"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,UAAU;AAEhD,SAASC,MAAM,IAAIC,SAAS,EAAEC,MAAM,QAAQ,6BAA6B;AACzE,SAASC,aAAa,QAAQ,SAAS;AASvC,OAAO,MAAMC,4BAA0D,GACrE,MAAAA,CAAOC,uBAAuB,EAAEC,OAAO,KAAK;EAC1C,MAAMC,gBAAgB,GAAGN,SAAS,CAACI,uBAAuB,CAAC;;EAE3D;EACA,MAAMG,MAAM,GAAGF,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEG,IAAI,CAC1BC,IAAA;IAAA,IAAC;MAAEC;IAAI,CAAC,GAAAD,IAAA;IAAA,OAAKC,GAAG,KAAKJ,gBAAgB,CAACK,eAAe,CAACD,GAAG;EAAA,CAC3D,CAAC;EAED,IAAI,CAACH,MAAM,EAAE;IACX,MAAM,IAAIT,qBAAqB,CAAC,wCAAwC,CAAC;EAC3E;EACA,MAAMG,MAAM,CAACG,uBAAuB,EAAEG,MAAM,CAAC;EAE7C,MAAMK,aAAa,GAAGV,aAAa,CAACW,KAAK,CAACP,gBAAgB,CAACQ,OAAO,CAAC;EACnE;EACA;EACA,IAAIF,aAAa,CAACG,GAAG,IAAIH,aAAa,CAACG,GAAG,IAAIC,IAAI,CAACC,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE;IAC/D,MAAM,IAAInB,qBAAqB,CAAC,4BAA4B,CAAC;EAC/D;EAEA,OAAO;IAAEc;EAAc,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { PresentationDefinition } from "./types";
2
+ import { hasStatusOrThrow } from "../../utils/misc";
3
+ /**
4
+ * Retrieves a PresentationDefinition based on the given parameters.
5
+ *
6
+ * The method attempts the following strategies in order:
7
+ * 1. Checks if `presentation_definition` is directly available in the request object.
8
+ * 2. Fetches the `presentation_definition` from the URI provided in the relying party configuration.
9
+ * 3. Uses a pre-configured `presentation_definition` from the relying party configuration if the `scope` is present in the request object.
10
+ *
11
+ * If none of the above conditions are met, the function throws an error indicating the definition could not be found.
12
+ *
13
+ * @param {RequestObject} requestObject - The request object containing the presentation definition or references to it.
14
+ * @param {RelyingPartyEntityConfiguration["payload"]["metadata"]} [rpConf] - Optional relying party configuration.
15
+ * @param {Object} [context] - Optional context for providing a custom fetch implementation.
16
+ * @param {GlobalFetch["fetch"]} [context.appFetch] - Custom fetch function, defaults to global `fetch`.
17
+ * @returns {Promise<{ presentationDefinition: PresentationDefinition }>} - Resolves with the presentation definition.
18
+ * @throws {Error} - Throws if the presentation definition cannot be found or fetched.
19
+ */
20
+ export const fetchPresentDefinition = async function (requestObject) {
21
+ var _rpConf$wallet_relyin, _rpConf$wallet_relyin2;
22
+ let {
23
+ appFetch = fetch
24
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25
+ let rpConf = arguments.length > 2 ? arguments[2] : undefined;
26
+ // Check if `presentation_definition` is directly available in the request object
27
+ if (requestObject.presentation_definition) {
28
+ return {
29
+ presentationDefinition: requestObject.presentation_definition
30
+ };
31
+ }
32
+
33
+ // Check if `presentation_definition_uri` is provided in the relying party configuration
34
+ if (rpConf !== null && rpConf !== void 0 && (_rpConf$wallet_relyin = rpConf.wallet_relying_party) !== null && _rpConf$wallet_relyin !== void 0 && _rpConf$wallet_relyin.presentation_definition_uri) {
35
+ try {
36
+ // Fetch the presentation definition from the provided URI
37
+ const presentationDefinition = await appFetch(rpConf === null || rpConf === void 0 ? void 0 : rpConf.wallet_relying_party.presentation_definition_uri, {
38
+ method: "GET"
39
+ }).then(hasStatusOrThrow(200)).then(raw => raw.json()).then(json => PresentationDefinition.parse(json));
40
+ return {
41
+ presentationDefinition
42
+ };
43
+ } catch (error) {
44
+ throw new Error(`Failed to fetch presentation definition: ${error}`);
45
+ }
46
+ }
47
+
48
+ // Check if `scope` is present in the request object and a pre-configured presentation definition exists
49
+ if (requestObject.scope && rpConf !== null && rpConf !== void 0 && (_rpConf$wallet_relyin2 = rpConf.wallet_relying_party) !== null && _rpConf$wallet_relyin2 !== void 0 && _rpConf$wallet_relyin2.presentation_definition) {
50
+ return {
51
+ presentationDefinition: rpConf.wallet_relying_party.presentation_definition
52
+ };
53
+ }
54
+ throw new Error("Presentation definition not found");
55
+ };
56
+ //# sourceMappingURL=06-fetch-presentation-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["PresentationDefinition","hasStatusOrThrow","fetchPresentDefinition","requestObject","_rpConf$wallet_relyin","_rpConf$wallet_relyin2","appFetch","fetch","arguments","length","undefined","rpConf","presentation_definition","presentationDefinition","wallet_relying_party","presentation_definition_uri","method","then","raw","json","parse","error","Error","scope"],"sourceRoot":"../../../../src","sources":["credential/presentation/06-fetch-presentation-definition.ts"],"mappings":"AAAA,SAASA,sBAAsB,QAAuB,SAAS;AAE/D,SAASC,gBAAgB,QAAQ,kBAAkB;AAYnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAAmD,GAAG,eAAAA,CACjEC,aAAa,EAGV;EAAA,IAAAC,qBAAA,EAAAC,sBAAA;EAAA,IAFH;IAAEC,QAAQ,GAAGC;EAAM,CAAC,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAAA,IACzBG,MAAM,GAAAH,SAAA,CAAAC,MAAA,OAAAD,SAAA,MAAAE,SAAA;EAEN;EACA,IAAIP,aAAa,CAACS,uBAAuB,EAAE;IACzC,OAAO;MACLC,sBAAsB,EAAEV,aAAa,CAACS;IACxC,CAAC;EACH;;EAEA;EACA,IAAID,MAAM,aAANA,MAAM,gBAAAP,qBAAA,GAANO,MAAM,CAAEG,oBAAoB,cAAAV,qBAAA,eAA5BA,qBAAA,CAA8BW,2BAA2B,EAAE;IAC7D,IAAI;MACF;MACA,MAAMF,sBAAsB,GAAG,MAAMP,QAAQ,CAC3CK,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEG,oBAAoB,CAACC,2BAA2B,EACxD;QACEC,MAAM,EAAE;MACV,CACF,CAAC,CACEC,IAAI,CAAChB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3BgB,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBF,IAAI,CAAEE,IAAI,IAAKnB,sBAAsB,CAACoB,KAAK,CAACD,IAAI,CAAC,CAAC;MAErD,OAAO;QACLN;MACF,CAAC;IACH,CAAC,CAAC,OAAOQ,KAAK,EAAE;MACd,MAAM,IAAIC,KAAK,CAAE,4CAA2CD,KAAM,EAAC,CAAC;IACtE;EACF;;EAEA;EACA,IACElB,aAAa,CAACoB,KAAK,IACnBZ,MAAM,aAANA,MAAM,gBAAAN,sBAAA,GAANM,MAAM,CAAEG,oBAAoB,cAAAT,sBAAA,eAA5BA,sBAAA,CAA8BO,uBAAuB,EACrD;IACA,OAAO;MACLC,sBAAsB,EACpBF,MAAM,CAACG,oBAAoB,CAACF;IAChC,CAAC;EACH;EAEA,MAAM,IAAIU,KAAK,CAAC,mCAAmC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,161 @@
1
+ import { JSONPath } from "jsonpath-plus";
2
+ import { MissingDataError } from "./errors";
3
+ import Ajv from "ajv";
4
+ const ajv = new Ajv({
5
+ allErrors: true
6
+ });
7
+ const INDEX_CLAIM_NAME = 1;
8
+ /**
9
+ * Transforms an array of DisclosureWithEncoded objects into a key-value map.
10
+ * @param disclosures - An array of DisclosureWithEncoded, each containing a decoded property with [?, claimName, claimValue].
11
+ * @returns An object mapping claim names to their corresponding values.
12
+ */
13
+ const mapDisclosuresToObject = disclosures => {
14
+ return disclosures.reduce((obj, _ref) => {
15
+ let {
16
+ decoded
17
+ } = _ref;
18
+ const [, claimName, claimValue] = decoded;
19
+ obj[claimName] = claimValue;
20
+ return obj;
21
+ }, {});
22
+ };
23
+
24
+ /**
25
+ * Finds a claim within the payload based on provided JSONPath expressions.
26
+ * @param paths - An array of JSONPath expressions to search for in the payload.
27
+ * @param payload - The object to search within using JSONPath.
28
+ * @returns A tuple with the first matched JSONPath and its corresponding value, or [undefined, undefined] if not found.
29
+ */
30
+ const findMatchedClaim = (paths, payload) => {
31
+ let matchedPath;
32
+ let matchedValue;
33
+ paths.some(singlePath => {
34
+ try {
35
+ const result = JSONPath({
36
+ path: singlePath,
37
+ json: payload
38
+ });
39
+ if (result.length > 0) {
40
+ matchedPath = singlePath;
41
+ matchedValue = result[0];
42
+ return true;
43
+ }
44
+ } catch (error) {
45
+ throw new MissingDataError(`JSONPath for "${singlePath}" does not match the provided payload.`);
46
+ }
47
+ return false;
48
+ });
49
+ return [matchedPath, matchedValue];
50
+ };
51
+
52
+ /**
53
+ * Extracts the claim name from a path that can be in one of the following formats:
54
+ * 1. $.propertyName
55
+ * 2. $["propertyName"] or $['propertyName']
56
+ *
57
+ * @param path - The path string containing the claim reference.
58
+ * @returns The extracted claim name if matched; otherwise, throws an exception.
59
+ */
60
+ const extractClaimName = path => {
61
+ // Define a regular expression that matches both formats:
62
+ // 1. $.propertyName
63
+ // 2. $["propertyName"] or $['propertyName']
64
+ const regex = /^\$\.(\w+)$|^\$\[(?:'|")(\w+)(?:'|")\]$/;
65
+ const match = path.match(regex);
66
+ if (match) {
67
+ // match[1] corresponds to the first capture group (\w+) after $.
68
+ // match[2] corresponds to the second capture group (\w+) inside [""] or ['']
69
+ return match[1] || match[2];
70
+ }
71
+
72
+ // If the input doesn't match any of the expected formats, return null
73
+
74
+ throw new Error(`Invalid input format: "${path}". Expected formats are "$.propertyName", "$['propertyName']", or '$["propertyName"]'.`);
75
+ };
76
+
77
+ /**
78
+ * Evaluates an InputDescriptor for an SD-JWT-based verifiable credential.
79
+ *
80
+ * - Checks each field in the InputDescriptor against the provided `payloadCredential`
81
+ * and `disclosures` (selectively disclosed claims).
82
+ * - Validates whether required fields are present (unless marked optional)
83
+ * and match any specified JSONPath.
84
+ * - If a field includes a JSON Schema filter, validates the claim value against that schema.
85
+ * - Enforces `limit_disclosure` rules by returning only disclosures matching the specified fields
86
+ * if set to "required". Otherwise return the array of all disclosures.
87
+ * - Throws an error if a required field is invalid or missing.
88
+ *
89
+ * @param inputDescriptor - Describes constraints (fields, filters, etc.) that must be satisfied.
90
+ * @param payloadCredential - The credential payload to check against.
91
+ * @param disclosures - An array of DisclosureWithEncoded objects representing selective disclosures.
92
+ * @returns A filtered list of disclosures satisfying the descriptor constraints, or throws an error if not.
93
+ * @throws Will throw an error if any required constraint fails or if JSONPath lookups are invalid.
94
+ */
95
+ export const evaluateInputDescriptorForSdJwt4VC = (inputDescriptor, payloadCredential, disclosures) => {
96
+ var _inputDescriptor$cons;
97
+ if (!(inputDescriptor !== null && inputDescriptor !== void 0 && (_inputDescriptor$cons = inputDescriptor.constraints) !== null && _inputDescriptor$cons !== void 0 && _inputDescriptor$cons.fields)) {
98
+ // No validation, all field are optional
99
+ return {
100
+ requiredDisclosures: [],
101
+ optionalDisclosures: disclosures
102
+ };
103
+ }
104
+ const requiredClaimNames = [];
105
+ const optionalClaimNames = [];
106
+
107
+ // Transform disclosures to find claim using JSONPath
108
+ const disclosuresAsPayload = mapDisclosuresToObject(disclosures);
109
+
110
+ // For each field, we need at least one matching path
111
+ // If we succeed, we push the matched disclosure in matchedDisclosures and stop checking further paths
112
+ const allFieldsValid = inputDescriptor.constraints.fields.every(field => {
113
+ // For Potential profile, selectively disclosed claims will always be built as an individual object property, by using a name-value pair.
114
+ // Hence that selective claim for array element and recursive disclosures are not supported by Potential for the first iteration of Piloting.
115
+ // We need to check inside disclosures or inside credential payload. Example path: "$.given_name"
116
+ let [matchedPath, matchedValue] = findMatchedClaim(field.path, disclosuresAsPayload);
117
+ if (!matchedPath) {
118
+ [matchedPath, matchedValue] = findMatchedClaim(field.path, payloadCredential);
119
+ if (!matchedPath) {
120
+ // Path could be optional, in this case no need to validate! continue to next field
121
+ return field === null || field === void 0 ? void 0 : field.optional;
122
+ }
123
+ } else {
124
+ // if match a disclouse we save which is required or optional
125
+ const claimName = extractClaimName(matchedPath);
126
+ if (claimName) {
127
+ (field !== null && field !== void 0 && field.optional ? optionalClaimNames : requiredClaimNames).push(claimName);
128
+ }
129
+ }
130
+
131
+ // FILTER validation
132
+ // If this field has a "filter" (JSON Schema), validate the claimValue
133
+ if (field.filter) {
134
+ try {
135
+ const validateSchema = ajv.compile(field.filter);
136
+ if (!validateSchema(matchedValue)) {
137
+ throw new MissingDataError(`Claim value "${matchedValue}" for path "${matchedPath}" does not match the provided JSON Schema.`);
138
+ }
139
+ } catch (error) {
140
+ return false;
141
+ }
142
+ }
143
+ // Submission Requirements validation
144
+ // TODO: [EUDIW-216] Read rule value if “all” o “pick” and validate
145
+
146
+ return true;
147
+ });
148
+ if (!allFieldsValid) {
149
+ throw new MissingDataError("Credential validation failed: Required fields are missing or do not match the input descriptor.");
150
+ }
151
+
152
+ // Categorizes disclosures into required and optional based on claim names and disclosure constraints.
153
+ const isNotLimitDisclosure = !(inputDescriptor.constraints.limit_disclosure === "required");
154
+ const requiredDisclosures = disclosures.filter(disclosure => requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]));
155
+ const optionalDisclosures = disclosures.filter(disclosure => optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]) || isNotLimitDisclosure && !requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]));
156
+ return {
157
+ requiredDisclosures,
158
+ optionalDisclosures
159
+ };
160
+ };
161
+ //# sourceMappingURL=07-evaluate-input-descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["JSONPath","MissingDataError","Ajv","ajv","allErrors","INDEX_CLAIM_NAME","mapDisclosuresToObject","disclosures","reduce","obj","_ref","decoded","claimName","claimValue","findMatchedClaim","paths","payload","matchedPath","matchedValue","some","singlePath","result","path","json","length","error","extractClaimName","regex","match","Error","evaluateInputDescriptorForSdJwt4VC","inputDescriptor","payloadCredential","_inputDescriptor$cons","constraints","fields","requiredDisclosures","optionalDisclosures","requiredClaimNames","optionalClaimNames","disclosuresAsPayload","allFieldsValid","every","field","optional","push","filter","validateSchema","compile","isNotLimitDisclosure","limit_disclosure","disclosure","includes"],"sourceRoot":"../../../../src","sources":["credential/presentation/07-evaluate-input-descriptor.ts"],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ import { EncryptJwe, SignJWT, sha256ToBase64 } from "@pagopa/io-react-native-jwt";
2
+ import uuid from "react-native-uuid";
3
+ import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
4
+ import { hasStatusOrThrow } from "../../utils/misc";
5
+ import { disclose } from "../../sd-jwt";
6
+ import * as z from "zod";
7
+ export const AuthorizationResponse = z.object({
8
+ status: z.string().optional(),
9
+ response_code: z.string() /**
10
+ FIXME: [SIW-627] we expect this value from every RP implementation
11
+ Actually some RP does not return the value
12
+ We make it optional to not break the flow.
13
+ */.optional(),
14
+ redirect_uri: z.string().optional()
15
+ });
16
+
17
+ /**
18
+ * Selects an RSA public key (with `use = enc` and `kty = RSA`) from the set of JWK keys
19
+ * offered by the Relying Party (RP) for encryption.
20
+ *
21
+ * @param rpJwkKeys - The array of JWKs retrieved from the RP entity configuration.
22
+ * @returns The first suitable RSA public key found in the list.
23
+ * @throws {NoSuitableKeysFoundInEntityConfiguration} If no suitable RSA encryption key is found.
24
+ */
25
+ export const chooseRSAPublicKeyToEncrypt = rpJwkKeys => {
26
+ const [rsaEncKey] = rpJwkKeys.filter(jwk => jwk.use === "enc" && jwk.kty === "RSA");
27
+ if (rsaEncKey) {
28
+ return rsaEncKey;
29
+ }
30
+
31
+ // No suitable key found
32
+ throw new NoSuitableKeysFoundInEntityConfiguration("No suitable RSA public key found for encryption.");
33
+ };
34
+
35
+ /**
36
+ * Prepares a Verified Presentation (VP) token to be sent as part of an
37
+ * authorization response in an OpenID 4 Verifiable Presentations flow.
38
+ *
39
+ * @param requestObject - The request object containing the nonce, response URI, and other necessary info.
40
+ * @param presentationTuple - A tuple containing a verifiable credential, the claims to disclose,
41
+ * and a cryptographic context for signing.
42
+ * @returns An object containing the signed VP token (`vp_token`) and a `presentation_submission` object.
43
+ * @param presentationDefinition - Definition outlining presentation requirements.
44
+ * @param presentationTuple - Tuple containing:
45
+ * - A verifiable credential.
46
+ * - Claims that should be disclosed.
47
+ * - Cryptographic context for signing.
48
+ * @returns An object with:
49
+ * - `vp_token`: The signed VP token.
50
+ * - `presentation_submission`: Object mapping disclosed credentials to the request.
51
+ *
52
+ * @remarks
53
+ * 1. The `disclose()` function is used to produce a token with only the requested claims.
54
+ * 2. A new JWT is then signed, including the VP, `jti`, `iss`, `nonce`, audience, and expiration.
55
+ * 3. The `presentation_submission` object follows the OpenID 4 VP specification for describing
56
+ * how the disclosed credentials map to the request.
57
+ *
58
+ * @todo [SIW-353] Support multiple verifiable credentials in a single request.
59
+ */
60
+ export const prepareVpToken = async (requestObject, presentationDefinition, _ref) => {
61
+ var _presentationDefiniti;
62
+ let [verifiableCredential, requestedClaims, cryptoContext] = _ref;
63
+ // Produce a VP token with only requested claims from the verifiable credential
64
+ const {
65
+ token: vp
66
+ } = await disclose(verifiableCredential, requestedClaims);
67
+
68
+ // <Issuer-signed JWT>~<Disclosure 1>~<Disclosure N>~
69
+ const sd_hash = await sha256ToBase64(`${vp}~`);
70
+ const kbJwt = await new SignJWT(cryptoContext).setProtectedHeader({
71
+ typ: "kb+jwt",
72
+ alg: "ES256"
73
+ }).setPayload({
74
+ sd_hash,
75
+ nonce: requestObject.nonce
76
+ }).setAudience(requestObject.client_id).setIssuedAt().sign();
77
+
78
+ // <Issuer-signed JWT>~<Disclosure 1>~...~<Disclosure N>~<KB-JWT>
79
+ const vp_token = [vp, kbJwt].join("~");
80
+
81
+ // Determine the descriptor ID to use for mapping. Fallback to first input descriptor ID if not specified
82
+ // We support only one credential for now, so we get first input_descriptor and create just one descriptor_map
83
+ const presentation_submission = {
84
+ id: uuid.v4(),
85
+ definition_id: presentationDefinition.id,
86
+ descriptor_map: [{
87
+ id: presentationDefinition === null || presentationDefinition === void 0 || (_presentationDefiniti = presentationDefinition.input_descriptors[0]) === null || _presentationDefiniti === void 0 ? void 0 : _presentationDefiniti.id,
88
+ path: `$`,
89
+ format: "vc+sd-jwt"
90
+ }]
91
+ };
92
+ return {
93
+ vp_token,
94
+ presentation_submission
95
+ };
96
+ };
97
+
98
+ /**
99
+ * Builds a URL-encoded form body for a direct POST response without encryption.
100
+ *
101
+ * @param requestObject - Contains state, nonce, and other relevant info.
102
+ * @param vpToken - The signed VP token to include.
103
+ * @param presentationSubmission - Object mapping credential disclosures.
104
+ * @returns A URL-encoded string suitable for an `application/x-www-form-urlencoded` POST body.
105
+ */
106
+ export const buildDirectPostBody = async (requestObject, vpToken, presentationSubmission) => {
107
+ const formUrlEncodedBody = new URLSearchParams({
108
+ state: requestObject.state,
109
+ presentation_submission: JSON.stringify(presentationSubmission),
110
+ vp_token: vpToken
111
+ });
112
+ return formUrlEncodedBody.toString();
113
+ };
114
+
115
+ /**
116
+ * Builds a URL-encoded form body for a direct POST response using JWT encryption.
117
+ *
118
+ * @param jwkKeys - Array of JWKs from the Relying Party for encryption.
119
+ * @param requestObject - Contains state, nonce, and other relevant info.
120
+ * @param vpToken - The signed VP token to encrypt.
121
+ * @param presentationSubmission - Object mapping credential disclosures.
122
+ * @returns A URL-encoded string for an `application/x-www-form-urlencoded` POST body,
123
+ * where `response` contains the encrypted JWE.
124
+ */
125
+ export const buildDirectPostJwtBody = async (jwkKeys, requestObject, vpToken, presentationSubmission) => {
126
+ // Prepare the authorization response payload to be encrypted
127
+ const authzResponsePayload = JSON.stringify({
128
+ state: requestObject.state,
129
+ presentation_submission: presentationSubmission,
130
+ vp_token: vpToken
131
+ });
132
+
133
+ // Choose a suitable RSA public key for encryption
134
+ const rsaPublicJwk = chooseRSAPublicKeyToEncrypt(jwkKeys);
135
+
136
+ // Encrypt the authorization payload
137
+ const encryptedResponse = await new EncryptJwe(authzResponsePayload, {
138
+ alg: "RSA-OAEP-256",
139
+ enc: "A256CBC-HS512",
140
+ kid: rsaPublicJwk.kid
141
+ }).encrypt(rsaPublicJwk);
142
+
143
+ // Build the x-www-form-urlencoded form body
144
+ const formBody = new URLSearchParams({
145
+ response: encryptedResponse
146
+ });
147
+ return formBody.toString();
148
+ };
149
+
150
+ /**
151
+ * Type definition for the function that sends the authorization response
152
+ * to the Relying Party, completing the presentation flow.
153
+ */
154
+
155
+ /**
156
+ * Sends the authorization response to the Relying Party (RP) using the specified `response_mode`.
157
+ * This function completes the presentation flow in an OpenID 4 Verifiable Presentations scenario.
158
+ *
159
+ * @param requestObject - The request details, including presentation requirements.
160
+ * @param presentationDefinition - The definition of the expected presentation.
161
+ * @param jwkKeys - Array of JWKs from the Relying Party for optional encryption.
162
+ * @param presentation - Tuple with verifiable credential, claims, and crypto context.
163
+ * @param context - Contains optional custom fetch implementation.
164
+ * @returns Parsed and validated authorization response from the Relying Party.
165
+ */
166
+ export const sendAuthorizationResponse = async (requestObject, presentationDefinition, jwkKeys, presentation, _ref2) => {
167
+ let {
168
+ appFetch = fetch
169
+ } = _ref2;
170
+ // 1. Create the VP token and associated submission mapping
171
+ const {
172
+ vp_token,
173
+ presentation_submission
174
+ } = await prepareVpToken(requestObject, presentationDefinition, presentation);
175
+
176
+ // 2. Choose the appropriate request body builder based on response mode
177
+ const requestBody = requestObject.response_mode === "direct_post.jwt" ? await buildDirectPostJwtBody(jwkKeys, requestObject, vp_token, presentation_submission) : await buildDirectPostBody(requestObject, vp_token, presentation_submission);
178
+
179
+ // 3. Send the authorization response via HTTP POST and validate the response
180
+ return await appFetch(requestObject.response_uri, {
181
+ method: "POST",
182
+ headers: {
183
+ "Content-Type": "application/x-www-form-urlencoded"
184
+ },
185
+ body: requestBody
186
+ }).then(hasStatusOrThrow(200)).then(res => res.json()).then(AuthorizationResponse.parse);
187
+ };
188
+ //# sourceMappingURL=08-send-authorization-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["EncryptJwe","SignJWT","sha256ToBase64","uuid","NoSuitableKeysFoundInEntityConfiguration","hasStatusOrThrow","disclose","z","AuthorizationResponse","object","status","string","optional","response_code","redirect_uri","chooseRSAPublicKeyToEncrypt","rpJwkKeys","rsaEncKey","filter","jwk","use","kty","prepareVpToken","requestObject","presentationDefinition","_ref","_presentationDefiniti","verifiableCredential","requestedClaims","cryptoContext","token","vp","sd_hash","kbJwt","setProtectedHeader","typ","alg","setPayload","nonce","setAudience","client_id","setIssuedAt","sign","vp_token","join","presentation_submission","id","v4","definition_id","descriptor_map","input_descriptors","path","format","buildDirectPostBody","vpToken","presentationSubmission","formUrlEncodedBody","URLSearchParams","state","JSON","stringify","toString","buildDirectPostJwtBody","jwkKeys","authzResponsePayload","rsaPublicJwk","encryptedResponse","enc","kid","encrypt","formBody","response","sendAuthorizationResponse","presentation","_ref2","appFetch","fetch","requestBody","response_mode","response_uri","method","headers","body","then","res","json","parse"],"sourceRoot":"../../../../src","sources":["credential/presentation/08-send-authorization-response.ts"],"mappings":"AAAA,SACEA,UAAU,EACVC,OAAO,EACPC,cAAc,QACT,6BAA6B;AACpC,OAAOC,IAAI,MAAM,mBAAmB;AAIpC,SAASC,wCAAwC,QAAQ,UAAU;AACnE,SAASC,gBAAgB,QAAkB,kBAAkB;AAC7D,SAASC,QAAQ,QAAQ,cAAc;AAEvC,OAAO,KAAKC,CAAC,MAAM,KAAK;AAGxB,OAAO,MAAMC,qBAAqB,GAAGD,CAAC,CAACE,MAAM,CAAC;EAC5CC,MAAM,EAAEH,CAAC,CAACI,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,CAAC;EAC7BC,aAAa,EAAEN,CAAC,CACbI,MAAM,CAAC,CAAC,CAAC;AACd;AACA;AACA;AACA,8BAJc,CAKTC,QAAQ,CAAC,CAAC;EACbE,YAAY,EAAEP,CAAC,CAACI,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC;AACpC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,2BAA2B,GACtCC,SAAiC,IACzB;EACR,MAAM,CAACC,SAAS,CAAC,GAAGD,SAAS,CAACE,MAAM,CACjCC,GAAG,IAAKA,GAAG,CAACC,GAAG,KAAK,KAAK,IAAID,GAAG,CAACE,GAAG,KAAK,KAC5C,CAAC;EAED,IAAIJ,SAAS,EAAE;IACb,OAAOA,SAAS;EAClB;;EAEA;EACA,MAAM,IAAIb,wCAAwC,CAChD,kDACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMkB,cAAc,GAAG,MAAAA,CAC5BC,aAAiE,EACjEC,sBAA8C,EAAAC,IAAA,KAK1C;EAAA,IAAAC,qBAAA;EAAA,IAJJ,CAACC,oBAAoB,EAAEC,eAAe,EAAEC,aAAa,CAAe,GAAAJ,IAAA;EAKpE;EACA,MAAM;IAAEK,KAAK,EAAEC;EAAG,CAAC,GAAG,MAAMzB,QAAQ,CAACqB,oBAAoB,EAAEC,eAAe,CAAC;;EAE3E;EACA,MAAMI,OAAO,GAAG,MAAM9B,cAAc,CAAE,GAAE6B,EAAG,GAAE,CAAC;EAE9C,MAAME,KAAK,GAAG,MAAM,IAAIhC,OAAO,CAAC4B,aAAa,CAAC,CAC3CK,kBAAkB,CAAC;IAClBC,GAAG,EAAE,QAAQ;IACbC,GAAG,EAAE;EACP,CAAC,CAAC,CACDC,UAAU,CAAC;IACVL,OAAO;IACPM,KAAK,EAAEf,aAAa,CAACe;EACvB,CAAC,CAAC,CACDC,WAAW,CAAChB,aAAa,CAACiB,SAAS,CAAC,CACpCC,WAAW,CAAC,CAAC,CACbC,IAAI,CAAC,CAAC;;EAET;EACA,MAAMC,QAAQ,GAAG,CAACZ,EAAE,EAAEE,KAAK,CAAC,CAACW,IAAI,CAAC,GAAG,CAAC;;EAEtC;EACA;EACA,MAAMC,uBAAuB,GAAG;IAC9BC,EAAE,EAAE3C,IAAI,CAAC4C,EAAE,CAAC,CAAC;IACbC,aAAa,EAAExB,sBAAsB,CAACsB,EAAE;IACxCG,cAAc,EAAE,CACd;MACEH,EAAE,EAAEtB,sBAAsB,aAAtBA,sBAAsB,gBAAAE,qBAAA,GAAtBF,sBAAsB,CAAE0B,iBAAiB,CAAC,CAAC,CAAC,cAAAxB,qBAAA,uBAA5CA,qBAAA,CAA8CoB,EAAE;MACpDK,IAAI,EAAG,GAAE;MACTC,MAAM,EAAE;IACV,CAAC;EAEL,CAAC;EAED,OAAO;IAAET,QAAQ;IAAEE;EAAwB,CAAC;AAC9C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMQ,mBAAmB,GAAG,MAAAA,CACjC9B,aAAiE,EACjE+B,OAAe,EACfC,sBAA+C,KAC3B;EACpB,MAAMC,kBAAkB,GAAG,IAAIC,eAAe,CAAC;IAC7CC,KAAK,EAAEnC,aAAa,CAACmC,KAAK;IAC1Bb,uBAAuB,EAAEc,IAAI,CAACC,SAAS,CAACL,sBAAsB,CAAC;IAC/DZ,QAAQ,EAAEW;EACZ,CAAC,CAAC;EAEF,OAAOE,kBAAkB,CAACK,QAAQ,CAAC,CAAC;AACtC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,GAAG,MAAAA,CACpCC,OAA+B,EAC/BxC,aAAiE,EACjE+B,OAAe,EACfC,sBAA+C,KAC3B;EACpB;EACA,MAAMS,oBAAoB,GAAGL,IAAI,CAACC,SAAS,CAAC;IAC1CF,KAAK,EAAEnC,aAAa,CAACmC,KAAK;IAC1Bb,uBAAuB,EAAEU,sBAAsB;IAC/CZ,QAAQ,EAAEW;EACZ,CAAC,CAAC;;EAEF;EACA,MAAMW,YAAY,GAAGlD,2BAA2B,CAACgD,OAAO,CAAC;;EAEzD;EACA,MAAMG,iBAAiB,GAAG,MAAM,IAAIlE,UAAU,CAACgE,oBAAoB,EAAE;IACnE5B,GAAG,EAAE,cAAc;IACnB+B,GAAG,EAAE,eAAe;IACpBC,GAAG,EAAEH,YAAY,CAACG;EACpB,CAAC,CAAC,CAACC,OAAO,CAACJ,YAAY,CAAC;;EAExB;EACA,MAAMK,QAAQ,GAAG,IAAIb,eAAe,CAAC;IAAEc,QAAQ,EAAEL;EAAkB,CAAC,CAAC;EACrE,OAAOI,QAAQ,CAACT,QAAQ,CAAC,CAAC;AAC5B,CAAC;;AAED;AACA;AACA;AACA;;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMW,yBAAoD,GAAG,MAAAA,CAClEjD,aAAa,EACbC,sBAAsB,EACtBuC,OAAO,EACPU,YAAY,EAAAC,KAAA,KAEuB;EAAA,IADnC;IAAEC,QAAQ,GAAGC;EAAM,CAAC,GAAAF,KAAA;EAEpB;EACA,MAAM;IAAE/B,QAAQ;IAAEE;EAAwB,CAAC,GAAG,MAAMvB,cAAc,CAChEC,aAAa,EACbC,sBAAsB,EACtBiD,YACF,CAAC;;EAED;EACA,MAAMI,WAAW,GACftD,aAAa,CAACuD,aAAa,KAAK,iBAAiB,GAC7C,MAAMhB,sBAAsB,CAC1BC,OAAO,EACPxC,aAAa,EACboB,QAAQ,EACRE,uBACF,CAAC,GACD,MAAMQ,mBAAmB,CACvB9B,aAAa,EACboB,QAAQ,EACRE,uBACF,CAAC;;EAEP;EACA,OAAO,MAAM8B,QAAQ,CAACpD,aAAa,CAACwD,YAAY,EAAE;IAChDC,MAAM,EAAE,MAAM;IACdC,OAAO,EAAE;MACP,cAAc,EAAE;IAClB,CAAC;IACDC,IAAI,EAAEL;EACR,CAAC,CAAC,CACCM,IAAI,CAAC9E,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3B8E,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBF,IAAI,CAAC3E,qBAAqB,CAAC8E,KAAK,CAAC;AACtC,CAAC"}