@pagopa/io-react-native-wallet 1.1.2 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/commonjs/credential/presentation/01-start-flow.js +7 -5
- package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/commonjs/credential/presentation/03-get-request-object.js +47 -0
- package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -0
- package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js +82 -0
- package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
- package/lib/commonjs/credential/presentation/05-verify-request-object.js +35 -0
- package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -0
- package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js +63 -0
- package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +169 -0
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js +202 -0
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -0
- package/lib/commonjs/credential/presentation/README.md +43 -4
- package/lib/commonjs/credential/presentation/errors.js +52 -1
- package/lib/commonjs/credential/presentation/errors.js.map +1 -1
- package/lib/commonjs/credential/presentation/index.js +27 -6
- package/lib/commonjs/credential/presentation/index.js.map +1 -1
- package/lib/commonjs/credential/presentation/types.js +69 -4
- package/lib/commonjs/credential/presentation/types.js.map +1 -1
- package/lib/commonjs/entity/trust/types.js +4 -1
- package/lib/commonjs/entity/trust/types.js.map +1 -1
- package/lib/module/credential/presentation/01-start-flow.js +8 -6
- package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/module/credential/presentation/03-get-request-object.js +39 -0
- package/lib/module/credential/presentation/03-get-request-object.js.map +1 -0
- package/lib/module/credential/presentation/04-retrieve-rp-jwks.js +75 -0
- package/lib/module/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
- package/lib/module/credential/presentation/05-verify-request-object.js +28 -0
- package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -0
- package/lib/module/credential/presentation/06-fetch-presentation-definition.js +56 -0
- package/lib/module/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +161 -0
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
- package/lib/module/credential/presentation/08-send-authorization-response.js +188 -0
- package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -0
- package/lib/module/credential/presentation/README.md +43 -4
- package/lib/module/credential/presentation/errors.js +48 -0
- package/lib/module/credential/presentation/errors.js.map +1 -1
- package/lib/module/credential/presentation/index.js +7 -4
- package/lib/module/credential/presentation/index.js.map +1 -1
- package/lib/module/credential/presentation/types.js +67 -3
- package/lib/module/credential/presentation/types.js.map +1 -1
- package/lib/module/entity/trust/types.js +4 -1
- package/lib/module/entity/trust/types.js.map +1 -1
- package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/{04-get-request-object.d.ts → 03-get-request-object.d.ts} +3 -5
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/{03-retrieve-jwks.d.ts → 04-retrieve-rp-jwks.d.ts} +5 -4
- package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/05-verify-request-object.d.ts +8 -0
- package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts +26 -0
- package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +27 -0
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +99 -0
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/errors.d.ts +33 -0
- package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/index.d.ts +8 -5
- package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/types.d.ts +612 -9
- package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
- package/lib/typescript/entity/trust/index.d.ts +152 -0
- package/lib/typescript/entity/trust/index.d.ts.map +1 -1
- package/lib/typescript/entity/trust/types.d.ts +2088 -0
- package/lib/typescript/entity/trust/types.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/credential/presentation/01-start-flow.ts +10 -6
- package/src/credential/presentation/{04-get-request-object.ts → 03-get-request-object.ts} +6 -51
- package/src/credential/presentation/{03-retrieve-jwks.ts → 04-retrieve-rp-jwks.ts} +39 -24
- package/src/credential/presentation/05-verify-request-object.ts +35 -0
- package/src/credential/presentation/06-fetch-presentation-definition.ts +78 -0
- package/src/credential/presentation/07-evaluate-input-descriptor.ts +204 -0
- package/src/credential/presentation/08-send-authorization-response.ts +251 -0
- package/src/credential/presentation/README.md +43 -4
- package/src/credential/presentation/errors.ts +48 -0
- package/src/credential/presentation/index.ts +27 -9
- package/src/credential/presentation/types.ts +59 -3
- package/src/entity/trust/types.ts +3 -0
- package/lib/commonjs/credential/presentation/03-retrieve-jwks.js +0 -68
- package/lib/commonjs/credential/presentation/03-retrieve-jwks.js.map +0 -1
- package/lib/commonjs/credential/presentation/04-get-request-object.js +0 -82
- package/lib/commonjs/credential/presentation/04-get-request-object.js.map +0 -1
- package/lib/commonjs/credential/presentation/05-send-authorization-response.js +0 -139
- package/lib/commonjs/credential/presentation/05-send-authorization-response.js.map +0 -1
- package/lib/module/credential/presentation/03-retrieve-jwks.js +0 -61
- package/lib/module/credential/presentation/03-retrieve-jwks.js.map +0 -1
- package/lib/module/credential/presentation/04-get-request-object.js +0 -74
- package/lib/module/credential/presentation/04-get-request-object.js.map +0 -1
- package/lib/module/credential/presentation/05-send-authorization-response.js +0 -128
- package/lib/module/credential/presentation/05-send-authorization-response.js.map +0 -1
- package/lib/typescript/credential/presentation/03-retrieve-jwks.d.ts.map +0 -1
- package/lib/typescript/credential/presentation/04-get-request-object.d.ts.map +0 -1
- package/lib/typescript/credential/presentation/05-send-authorization-response.d.ts +0 -34
- package/lib/typescript/credential/presentation/05-send-authorization-response.d.ts.map +0 -1
- package/src/credential/presentation/05-send-authorization-response.ts +0 -168
@@ -1,6 +1,5 @@
|
|
1
1
|
import * as z from "zod";
|
2
|
-
import {
|
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
|
-
|
31
|
-
|
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
|
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
|
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","
|
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":"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"}
|