@pagopa/io-react-native-wallet 0.27.1 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/client/generated/wallet-provider.js +27 -19
- package/lib/commonjs/client/generated/wallet-provider.js.map +1 -1
- package/lib/commonjs/credential/issuance/03-start-user-authorization.js +3 -0
- package/lib/commonjs/credential/issuance/03-start-user-authorization.js.map +1 -1
- package/lib/commonjs/credential/presentation/01-start-flow.js +14 -24
- package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/commonjs/credential/presentation/03-get-request-object.js +30 -42
- package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -1
- package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js +32 -0
- package/lib/commonjs/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
- package/lib/commonjs/credential/presentation/05-verify-request-object.js +53 -0
- package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -0
- package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js +39 -0
- package/lib/commonjs/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
- package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js +125 -0
- package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js.map +1 -0
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +289 -0
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js +170 -0
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -0
- package/lib/commonjs/credential/presentation/errors.js +69 -1
- package/lib/commonjs/credential/presentation/errors.js.map +1 -1
- package/lib/commonjs/credential/presentation/index.js +29 -1
- package/lib/commonjs/credential/presentation/index.js.map +1 -1
- package/lib/commonjs/credential/presentation/types.js +124 -3
- package/lib/commonjs/credential/presentation/types.js.map +1 -1
- package/lib/commonjs/sd-jwt/index.js +41 -1
- package/lib/commonjs/sd-jwt/index.js.map +1 -1
- package/lib/commonjs/trust/chain.js +35 -50
- package/lib/commonjs/trust/chain.js.map +1 -1
- package/lib/commonjs/trust/index.js +139 -16
- package/lib/commonjs/trust/index.js.map +1 -1
- package/lib/commonjs/trust/types.js +36 -12
- package/lib/commonjs/trust/types.js.map +1 -1
- package/lib/commonjs/trust/utils.js +41 -0
- package/lib/commonjs/trust/utils.js.map +1 -0
- package/lib/commonjs/utils/jwk.js +5 -1
- package/lib/commonjs/utils/jwk.js.map +1 -1
- package/lib/commonjs/wallet-instance/index.js +10 -0
- package/lib/commonjs/wallet-instance/index.js.map +1 -1
- package/lib/module/client/generated/wallet-provider.js +22 -15
- package/lib/module/client/generated/wallet-provider.js.map +1 -1
- package/lib/module/credential/issuance/03-start-user-authorization.js +3 -0
- package/lib/module/credential/issuance/03-start-user-authorization.js.map +1 -1
- package/lib/module/credential/presentation/01-start-flow.js +14 -24
- package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/module/credential/presentation/03-get-request-object.js +31 -43
- package/lib/module/credential/presentation/03-get-request-object.js.map +1 -1
- package/lib/module/credential/presentation/04-retrieve-rp-jwks.js +25 -0
- package/lib/module/credential/presentation/04-retrieve-rp-jwks.js.map +1 -0
- package/lib/module/credential/presentation/05-verify-request-object.js +46 -0
- package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -0
- package/lib/module/credential/presentation/06-fetch-presentation-definition.js +32 -0
- package/lib/module/credential/presentation/06-fetch-presentation-definition.js.map +1 -0
- package/lib/module/credential/presentation/07-evaluate-dcql-query.js +117 -0
- package/lib/module/credential/presentation/07-evaluate-dcql-query.js.map +1 -0
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +278 -0
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -0
- package/lib/module/credential/presentation/08-send-authorization-response.js +158 -0
- package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -0
- package/lib/module/credential/presentation/errors.js +64 -0
- package/lib/module/credential/presentation/errors.js.map +1 -1
- package/lib/module/credential/presentation/index.js +6 -2
- package/lib/module/credential/presentation/index.js.map +1 -1
- package/lib/module/credential/presentation/types.js +121 -2
- package/lib/module/credential/presentation/types.js.map +1 -1
- package/lib/module/sd-jwt/index.js +40 -1
- package/lib/module/sd-jwt/index.js.map +1 -1
- package/lib/module/trust/chain.js +32 -46
- package/lib/module/trust/chain.js.map +1 -1
- package/lib/module/trust/index.js +139 -18
- package/lib/module/trust/index.js.map +1 -1
- package/lib/module/trust/types.js +34 -11
- package/lib/module/trust/types.js.map +1 -1
- package/lib/module/trust/utils.js +33 -0
- package/lib/module/trust/utils.js.map +1 -0
- package/lib/module/utils/jwk.js +3 -0
- package/lib/module/utils/jwk.js.map +1 -1
- package/lib/module/wallet-instance/index.js +9 -0
- package/lib/module/wallet-instance/index.js.map +1 -1
- package/lib/typescript/client/generated/wallet-provider.d.ts +91 -54
- package/lib/typescript/client/generated/wallet-provider.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/01-start-flow.d.ts +26 -5
- package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts +7 -10
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/04-retrieve-rp-jwks.d.ts +23 -0
- 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 +18 -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 +21 -0
- package/lib/typescript/credential/presentation/06-fetch-presentation-definition.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/07-evaluate-dcql-query.d.ts +20 -0
- package/lib/typescript/credential/presentation/07-evaluate-dcql-query.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +88 -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 +70 -0
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -0
- package/lib/typescript/credential/presentation/errors.d.ts +44 -0
- package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/index.d.ts +7 -3
- package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/types.d.ts +747 -10
- package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
- package/lib/typescript/credential/status/types.d.ts +6 -6
- package/lib/typescript/sd-jwt/index.d.ts +31 -12
- package/lib/typescript/sd-jwt/index.d.ts.map +1 -1
- package/lib/typescript/sd-jwt/types.d.ts +6 -6
- package/lib/typescript/trust/chain.d.ts +4 -9
- package/lib/typescript/trust/chain.d.ts.map +1 -1
- package/lib/typescript/trust/index.d.ts +337 -61
- package/lib/typescript/trust/index.d.ts.map +1 -1
- package/lib/typescript/trust/types.d.ts +4074 -407
- package/lib/typescript/trust/types.d.ts.map +1 -1
- package/lib/typescript/trust/utils.d.ts +12 -0
- package/lib/typescript/trust/utils.d.ts.map +1 -0
- package/lib/typescript/utils/decoder.d.ts +1 -1
- package/lib/typescript/utils/decoder.d.ts.map +1 -1
- package/lib/typescript/utils/jwk.d.ts +137 -0
- package/lib/typescript/utils/jwk.d.ts.map +1 -1
- package/lib/typescript/wallet-instance/index.d.ts +8 -0
- package/lib/typescript/wallet-instance/index.d.ts.map +1 -1
- package/lib/typescript/wallet-instance-attestation/types.d.ts +36 -36
- package/package.json +5 -2
- package/src/client/generated/wallet-provider.ts +28 -19
- package/src/credential/issuance/03-start-user-authorization.ts +3 -0
- package/src/credential/presentation/01-start-flow.ts +19 -26
- package/src/credential/presentation/03-get-request-object.ts +35 -58
- package/src/credential/presentation/04-retrieve-rp-jwks.ts +34 -0
- package/src/credential/presentation/05-verify-request-object.ts +52 -0
- package/src/credential/presentation/06-fetch-presentation-definition.ts +48 -0
- package/src/credential/presentation/07-evaluate-dcql-query.ts +166 -0
- package/src/credential/presentation/07-evaluate-input-descriptor.ts +391 -0
- package/src/credential/presentation/08-send-authorization-response.ts +220 -0
- package/src/credential/presentation/errors.ts +64 -0
- package/src/credential/presentation/index.ts +22 -1
- package/src/credential/presentation/types.ts +133 -2
- package/src/sd-jwt/index.ts +49 -1
- package/src/trust/chain.ts +46 -66
- package/src/trust/index.ts +185 -20
- package/src/trust/types.ts +34 -10
- package/src/trust/utils.ts +35 -0
- package/src/utils/decoder.ts +1 -1
- package/src/utils/jwk.ts +8 -1
- package/src/wallet-instance/index.ts +13 -0
- package/lib/commonjs/credential/presentation/04-send-authorization-response.js +0 -138
- package/lib/commonjs/credential/presentation/04-send-authorization-response.js.map +0 -1
- package/lib/module/credential/presentation/04-send-authorization-response.js +0 -128
- package/lib/module/credential/presentation/04-send-authorization-response.js.map +0 -1
- package/lib/typescript/credential/presentation/04-send-authorization-response.d.ts +0 -34
- package/lib/typescript/credential/presentation/04-send-authorization-response.d.ts.map +0 -1
- package/src/credential/presentation/04-send-authorization-response.ts +0 -168
@@ -1,60 +1,48 @@
|
|
1
|
-
import { v4 as uuidv4 } from "uuid";
|
2
|
-
import { decode as decodeJwt, sha256ToBase64, verify } from "@pagopa/io-react-native-jwt";
|
3
|
-
import { createDPopToken } from "../../utils/dpop";
|
4
|
-
import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
|
5
1
|
import { hasStatusOrThrow } from "../../utils/misc";
|
6
|
-
import {
|
2
|
+
import { RequestObjectWalletCapabilities } from "./types";
|
7
3
|
/**
|
8
|
-
* Obtain the Request Object for RP authentication
|
4
|
+
* Obtain the Request Object for RP authentication. Both the GET and POST `request_uri_method` are supported.
|
9
5
|
* @see https://italia.github.io/eudi-wallet-it-docs/versione-corrente/en/relying-party-solution.html
|
10
6
|
*
|
11
7
|
* @param requestUri The url for the Relying Party to connect with
|
12
|
-
* @param rpConf The Relying Party's configuration
|
13
|
-
* @param context.
|
14
|
-
* @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
8
|
+
* @param rpConf The Relying Party's configuration * @param context.walletInstanceAttestation The Wallet Instance Attestation token
|
9
|
+
* @param context.walletCapabilities (optional) An object containing the wallet technical capabilities that will be sent with a POST request
|
15
10
|
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
16
11
|
* @returns The Request Object that describes the presentation
|
17
12
|
*/
|
18
|
-
export const getRequestObject = async (requestUri,
|
13
|
+
export const getRequestObject = async (requestUri, _ref) => {
|
19
14
|
let {
|
20
|
-
wiaCryptoContext,
|
21
15
|
appFetch = fetch,
|
22
|
-
|
16
|
+
walletCapabilities
|
23
17
|
} = _ref;
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
36
|
-
}).then(hasStatusOrThrow(200)).then(res => res.json()).then(responseJson => responseJson.response);
|
37
|
-
const responseJwt = decodeJwt(responseEncodedJwt);
|
38
|
-
|
39
|
-
// verify token signature according to RP's entity configuration
|
40
|
-
// to ensure the request object is authentic
|
41
|
-
{
|
42
|
-
const pubKey = rpConf.wallet_relying_party.jwks.keys.find(_ref2 => {
|
43
|
-
let {
|
44
|
-
kid
|
45
|
-
} = _ref2;
|
46
|
-
return kid === responseJwt.protectedHeader.kid;
|
18
|
+
if (walletCapabilities) {
|
19
|
+
// Validate external input
|
20
|
+
const {
|
21
|
+
wallet_metadata,
|
22
|
+
wallet_nonce
|
23
|
+
} = RequestObjectWalletCapabilities.parse(walletCapabilities);
|
24
|
+
const formUrlEncodedBody = new URLSearchParams({
|
25
|
+
wallet_metadata: JSON.stringify(wallet_metadata),
|
26
|
+
...(wallet_nonce && {
|
27
|
+
wallet_nonce
|
28
|
+
})
|
47
29
|
});
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
30
|
+
const requestObjectEncodedJwt = await appFetch(requestUri, {
|
31
|
+
method: "POST",
|
32
|
+
headers: {
|
33
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
34
|
+
},
|
35
|
+
body: formUrlEncodedBody.toString()
|
36
|
+
}).then(hasStatusOrThrow(200)).then(res => res.text());
|
37
|
+
return {
|
38
|
+
requestObjectEncodedJwt
|
39
|
+
};
|
52
40
|
}
|
53
|
-
|
54
|
-
|
55
|
-
|
41
|
+
const requestObjectEncodedJwt = await appFetch(requestUri, {
|
42
|
+
method: "GET"
|
43
|
+
}).then(hasStatusOrThrow(200)).then(res => res.text());
|
56
44
|
return {
|
57
|
-
|
45
|
+
requestObjectEncodedJwt
|
58
46
|
};
|
59
47
|
};
|
60
48
|
//# sourceMappingURL=03-get-request-object.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["
|
1
|
+
{"version":3,"names":["hasStatusOrThrow","RequestObjectWalletCapabilities","getRequestObject","requestUri","_ref","appFetch","fetch","walletCapabilities","wallet_metadata","wallet_nonce","parse","formUrlEncodedBody","URLSearchParams","JSON","stringify","requestObjectEncodedJwt","method","headers","body","toString","then","res","text"],"sourceRoot":"../../../../src","sources":["credential/presentation/03-get-request-object.ts"],"mappings":"AAAA,SAASA,gBAAgB,QAAkB,kBAAkB;AAE7D,SAASC,+BAA+B,QAAQ,SAAS;AAWzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAkC,GAAG,MAAAA,CAChDC,UAAU,EAAAC,IAAA,KAEP;EAAA,IADH;IAAEC,QAAQ,GAAGC,KAAK;IAAEC;EAAmB,CAAC,GAAAH,IAAA;EAExC,IAAIG,kBAAkB,EAAE;IACtB;IACA,MAAM;MAAEC,eAAe;MAAEC;IAAa,CAAC,GACrCR,+BAA+B,CAACS,KAAK,CAACH,kBAAkB,CAAC;IAE3D,MAAMI,kBAAkB,GAAG,IAAIC,eAAe,CAAC;MAC7CJ,eAAe,EAAEK,IAAI,CAACC,SAAS,CAACN,eAAe,CAAC;MAChD,IAAIC,YAAY,IAAI;QAAEA;MAAa,CAAC;IACtC,CAAC,CAAC;IAEF,MAAMM,uBAAuB,GAAG,MAAMV,QAAQ,CAACF,UAAU,EAAE;MACzDa,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE;QACP,cAAc,EAAE;MAClB,CAAC;MACDC,IAAI,EAAEP,kBAAkB,CAACQ,QAAQ,CAAC;IACpC,CAAC,CAAC,CACCC,IAAI,CAACpB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3BoB,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC;IAE5B,OAAO;MACLP;IACF,CAAC;EACH;EAEA,MAAMA,uBAAuB,GAAG,MAAMV,QAAQ,CAACF,UAAU,EAAE;IACzDa,MAAM,EAAE;EACV,CAAC,CAAC,CACCI,IAAI,CAACpB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3BoB,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC;EAE5B,OAAO;IACLP;EACF,CAAC;AACH,CAAC"}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/**
|
2
|
+
* Defines the signature for a function that retrieves JSON Web Key Sets (JWKS) from a client.
|
3
|
+
*
|
4
|
+
* @template T - The tuple type representing the function arguments.
|
5
|
+
* @param args - The arguments passed to the function.
|
6
|
+
* @returns A promise resolving to an object containing an array of JWKs.
|
7
|
+
*/
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Retrieves the JSON Web Key Set (JWKS) from a Relying Party's entity configuration.
|
11
|
+
*
|
12
|
+
* @param rpConfig - The configuration object of the Relying Party entity.
|
13
|
+
* @returns An object containing an array of JWKs.
|
14
|
+
* @throws Will throw an error if the configuration is invalid or if JWKS is not found.
|
15
|
+
*/
|
16
|
+
export const getJwksFromConfig = rpConfig => {
|
17
|
+
const jwks = rpConfig.openid_credential_verifier.jwks;
|
18
|
+
if (!jwks || !Array.isArray(jwks.keys)) {
|
19
|
+
throw new Error("JWKS not found in Relying Party configuration.");
|
20
|
+
}
|
21
|
+
return {
|
22
|
+
keys: jwks.keys
|
23
|
+
};
|
24
|
+
};
|
25
|
+
//# sourceMappingURL=04-retrieve-rp-jwks.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"names":["getJwksFromConfig","rpConfig","jwks","openid_credential_verifier","Array","isArray","keys","Error"],"sourceRoot":"../../../../src","sources":["credential/presentation/04-retrieve-rp-jwks.ts"],"mappings":"AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,iBAEZ,GAAIC,QAAQ,IAAK;EAChB,MAAMC,IAAI,GAAGD,QAAQ,CAACE,0BAA0B,CAACD,IAAI;EAErD,IAAI,CAACA,IAAI,IAAI,CAACE,KAAK,CAACC,OAAO,CAACH,IAAI,CAACI,IAAI,CAAC,EAAE;IACtC,MAAM,IAAIC,KAAK,CAAC,gDAAgD,CAAC;EACnE;EAEA,OAAO;IACLD,IAAI,EAAEJ,IAAI,CAACI;EACb,CAAC;AACH,CAAC"}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { decode as decodeJwt, verify } from "@pagopa/io-react-native-jwt";
|
2
|
+
import { UnverifiedEntityError } from "./errors";
|
3
|
+
import { RequestObject } from "./types";
|
4
|
+
import { getJwksFromConfig } from "./04-retrieve-rp-jwks";
|
5
|
+
/**
|
6
|
+
* Function to verify the Request Object's signature and the client ID.
|
7
|
+
* @param requestObjectEncodedJwt The Request Object in JWT format
|
8
|
+
* @param context.clientId The client ID to verify
|
9
|
+
* @param context.jwkKeys The set of keys to verify the signature
|
10
|
+
* @param context.rpConf The Entity Configuration of the Relying Party
|
11
|
+
* @returns The verified Request Object
|
12
|
+
*/
|
13
|
+
export const verifyRequestObject = async (requestObjectEncodedJwt, _ref) => {
|
14
|
+
let {
|
15
|
+
clientId,
|
16
|
+
rpConf
|
17
|
+
} = _ref;
|
18
|
+
const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
|
19
|
+
const {
|
20
|
+
keys
|
21
|
+
} = getJwksFromConfig(rpConf.metadata);
|
22
|
+
|
23
|
+
// Verify token signature to ensure the request object is authentic
|
24
|
+
const pubKey = keys === null || keys === void 0 ? void 0 : keys.find(_ref2 => {
|
25
|
+
let {
|
26
|
+
kid
|
27
|
+
} = _ref2;
|
28
|
+
return kid === requestObjectJwt.protectedHeader.kid;
|
29
|
+
});
|
30
|
+
if (!pubKey) {
|
31
|
+
throw new UnverifiedEntityError("Request Object signature verification!");
|
32
|
+
}
|
33
|
+
|
34
|
+
// Standard claims are verified within `verify`
|
35
|
+
await verify(requestObjectEncodedJwt, pubKey, {
|
36
|
+
issuer: clientId
|
37
|
+
});
|
38
|
+
const requestObject = RequestObject.parse(requestObjectJwt.payload);
|
39
|
+
if (!(clientId === requestObject.client_id && clientId === rpConf.sub)) {
|
40
|
+
throw new UnverifiedEntityError("Client ID does not match Request Object or Entity Configuration");
|
41
|
+
}
|
42
|
+
return {
|
43
|
+
requestObject
|
44
|
+
};
|
45
|
+
};
|
46
|
+
//# sourceMappingURL=05-verify-request-object.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"names":["decode","decodeJwt","verify","UnverifiedEntityError","RequestObject","getJwksFromConfig","verifyRequestObject","requestObjectEncodedJwt","_ref","clientId","rpConf","requestObjectJwt","keys","metadata","pubKey","find","_ref2","kid","protectedHeader","issuer","requestObject","parse","payload","client_id","sub"],"sourceRoot":"../../../../src","sources":["credential/presentation/05-verify-request-object.ts"],"mappings":"AAAA,SAASA,MAAM,IAAIC,SAAS,EAAEC,MAAM,QAAQ,6BAA6B;AAEzE,SAASC,qBAAqB,QAAQ,UAAU;AAChD,SAASC,aAAa,QAAQ,SAAS;AACvC,SAASC,iBAAiB,QAAQ,uBAAuB;AAWzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,mBAAwC,GAAG,MAAAA,CACtDC,uBAAuB,EAAAC,IAAA,KAEpB;EAAA,IADH;IAAEC,QAAQ;IAAEC;EAAO,CAAC,GAAAF,IAAA;EAEpB,MAAMG,gBAAgB,GAAGV,SAAS,CAACM,uBAAuB,CAAC;EAC3D,MAAM;IAAEK;EAAK,CAAC,GAAGP,iBAAiB,CAACK,MAAM,CAACG,QAAQ,CAAC;;EAEnD;EACA,MAAMC,MAAM,GAAGF,IAAI,aAAJA,IAAI,uBAAJA,IAAI,CAAEG,IAAI,CACvBC,KAAA;IAAA,IAAC;MAAEC;IAAI,CAAC,GAAAD,KAAA;IAAA,OAAKC,GAAG,KAAKN,gBAAgB,CAACO,eAAe,CAACD,GAAG;EAAA,CAC3D,CAAC;EAED,IAAI,CAACH,MAAM,EAAE;IACX,MAAM,IAAIX,qBAAqB,CAAC,wCAAwC,CAAC;EAC3E;;EAEA;EACA,MAAMD,MAAM,CAACK,uBAAuB,EAAEO,MAAM,EAAE;IAAEK,MAAM,EAAEV;EAAS,CAAC,CAAC;EAEnE,MAAMW,aAAa,GAAGhB,aAAa,CAACiB,KAAK,CAACV,gBAAgB,CAACW,OAAO,CAAC;EAEnE,IAAI,EAAEb,QAAQ,KAAKW,aAAa,CAACG,SAAS,IAAId,QAAQ,KAAKC,MAAM,CAACc,GAAG,CAAC,EAAE;IACtE,MAAM,IAAIrB,qBAAqB,CAC7B,iEACF,CAAC;EACH;EAEA,OAAO;IAAEiB;EAAc,CAAC;AAC1B,CAAC"}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
/**
|
2
|
+
* Retrieves a PresentationDefinition based on the given parameters.
|
3
|
+
*
|
4
|
+
* The method attempts the following strategies in order:
|
5
|
+
* 1. Checks if `presentation_definition` is directly available in the request object.
|
6
|
+
* 2. Uses a pre-configured `presentation_definition` from the relying party configuration if the `scope` is present in the request object.
|
7
|
+
*
|
8
|
+
* If none of the above conditions are met, the function throws an error indicating the definition could not be found. Note that `presentation_definition_uri` is not supported in 0.9.x.
|
9
|
+
*
|
10
|
+
* @param {RequestObject} requestObject - The request object containing the presentation definition or references to it.
|
11
|
+
* @param {RelyingPartyEntityConfiguration["payload"]["metadata"]} [rpConf] - Optional relying party configuration.
|
12
|
+
* @returns {Promise<{ presentationDefinition: PresentationDefinition }>} - Resolves with the presentation definition.
|
13
|
+
* @throws {Error} - Throws if the presentation definition cannot be found or fetched.
|
14
|
+
*/
|
15
|
+
export const fetchPresentDefinition = async (requestObject, rpConf) => {
|
16
|
+
var _rpConf$openid_creden;
|
17
|
+
// Check if `presentation_definition` is directly available in the request object
|
18
|
+
if (requestObject.presentation_definition) {
|
19
|
+
return {
|
20
|
+
presentationDefinition: requestObject.presentation_definition
|
21
|
+
};
|
22
|
+
}
|
23
|
+
|
24
|
+
// Check if `scope` is present in the request object and a pre-configured presentation definition exists
|
25
|
+
if (requestObject.scope && rpConf !== null && rpConf !== void 0 && (_rpConf$openid_creden = rpConf.openid_credential_verifier) !== null && _rpConf$openid_creden !== void 0 && _rpConf$openid_creden.presentation_definition) {
|
26
|
+
return {
|
27
|
+
presentationDefinition: rpConf.openid_credential_verifier.presentation_definition
|
28
|
+
};
|
29
|
+
}
|
30
|
+
throw new Error("Presentation definition not found");
|
31
|
+
};
|
32
|
+
//# sourceMappingURL=06-fetch-presentation-definition.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"names":["fetchPresentDefinition","requestObject","rpConf","_rpConf$openid_creden","presentation_definition","presentationDefinition","scope","openid_credential_verifier","Error"],"sourceRoot":"../../../../src","sources":["credential/presentation/06-fetch-presentation-definition.ts"],"mappings":"AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,sBAAmD,GAAG,MAAAA,CACjEC,aAAa,EACbC,MAAM,KACH;EAAA,IAAAC,qBAAA;EACH;EACA,IAAIF,aAAa,CAACG,uBAAuB,EAAE;IACzC,OAAO;MACLC,sBAAsB,EAAEJ,aAAa,CAACG;IACxC,CAAC;EACH;;EAEA;EACA,IACEH,aAAa,CAACK,KAAK,IACnBJ,MAAM,aAANA,MAAM,gBAAAC,qBAAA,GAAND,MAAM,CAAEK,0BAA0B,cAAAJ,qBAAA,eAAlCA,qBAAA,CAAoCC,uBAAuB,EAC3D;IACA,OAAO;MACLC,sBAAsB,EACpBH,MAAM,CAACK,0BAA0B,CAACH;IACtC,CAAC;EACH;EAEA,MAAM,IAAII,KAAK,CAAC,mCAAmC,CAAC;AACtD,CAAC"}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import { DcqlQuery, DcqlError, DcqlCredentialSetError } from "dcql";
|
2
|
+
import { isValiError } from "valibot";
|
3
|
+
import { decode, prepareVpToken } from "../../sd-jwt";
|
4
|
+
import { ValidationFailed } from "../../utils/errors";
|
5
|
+
import { createCryptoContextFor } from "../../utils/crypto";
|
6
|
+
/**
|
7
|
+
* Convert a credential in JWT format to an object with claims
|
8
|
+
* for correct parsing by the `dcql` library.
|
9
|
+
*/
|
10
|
+
const mapCredentialToObject = jwt => {
|
11
|
+
const {
|
12
|
+
sdJwt,
|
13
|
+
disclosures
|
14
|
+
} = decode(jwt);
|
15
|
+
const credentialFormat = sdJwt.header.typ;
|
16
|
+
|
17
|
+
// TODO [SIW-2082]: support MDOC credentials
|
18
|
+
if (credentialFormat !== "vc+sd-jwt") {
|
19
|
+
throw new Error(`Unsupported credential format: ${credentialFormat}`);
|
20
|
+
}
|
21
|
+
return {
|
22
|
+
vct: sdJwt.payload.vct,
|
23
|
+
credential_format: credentialFormat,
|
24
|
+
claims: disclosures.reduce((acc, disclosure) => ({
|
25
|
+
...acc,
|
26
|
+
[disclosure.decoded[1]]: disclosure.decoded
|
27
|
+
}), {})
|
28
|
+
};
|
29
|
+
};
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Extract only successful matches from the DCQL query result.
|
33
|
+
*/
|
34
|
+
const getDcqlQueryMatches = result => Object.entries(result.credential_matches).filter(_ref => {
|
35
|
+
let [, match] = _ref;
|
36
|
+
return match.success === true;
|
37
|
+
});
|
38
|
+
export const evaluateDcqlQuery = (credentialsSdJwt, query) => {
|
39
|
+
const credentials = credentialsSdJwt.map(_ref2 => {
|
40
|
+
let [, credential] = _ref2;
|
41
|
+
return mapCredentialToObject(credential);
|
42
|
+
});
|
43
|
+
try {
|
44
|
+
// Validate the query
|
45
|
+
const parsedQuery = DcqlQuery.parse(query);
|
46
|
+
DcqlQuery.validate(parsedQuery);
|
47
|
+
const queryResult = DcqlQuery.query(parsedQuery, credentials);
|
48
|
+
if (!queryResult.canBeSatisfied) {
|
49
|
+
throw new Error("No credential can satisfy the provided DCQL query");
|
50
|
+
}
|
51
|
+
|
52
|
+
// Build an object vct:credentialJwt to map matched credentials to their JWT
|
53
|
+
const credentialsSdJwtByVct = credentials.reduce((acc, c, i) => ({
|
54
|
+
...acc,
|
55
|
+
[c.vct]: credentialsSdJwt[i]
|
56
|
+
}), {});
|
57
|
+
return getDcqlQueryMatches(queryResult).map(_ref3 => {
|
58
|
+
var _queryResult$credenti;
|
59
|
+
let [id, match] = _ref3;
|
60
|
+
if (match.output.credential_format !== "vc+sd-jwt") {
|
61
|
+
throw new Error("Unsupported format"); // TODO [SIW-2082]: support MDOC credentials
|
62
|
+
}
|
63
|
+
|
64
|
+
const {
|
65
|
+
vct,
|
66
|
+
claims
|
67
|
+
} = match.output;
|
68
|
+
|
69
|
+
// Find a matching credential set to see whether the credential is optional
|
70
|
+
// If no credential set is found, then the credential is required by default
|
71
|
+
// NOTE: This is an extra, it might not be necessary
|
72
|
+
const credentialSet = (_queryResult$credenti = queryResult.credential_sets) === null || _queryResult$credenti === void 0 ? void 0 : _queryResult$credenti.find(set => {
|
73
|
+
var _set$matching_options;
|
74
|
+
return (_set$matching_options = set.matching_options) === null || _set$matching_options === void 0 ? void 0 : _set$matching_options.flat().includes(vct);
|
75
|
+
});
|
76
|
+
const isOptional = credentialSet ? !credentialSet.required : false;
|
77
|
+
const [keyTag, credential] = credentialsSdJwtByVct[vct];
|
78
|
+
const requiredDisclosures = Object.values(claims);
|
79
|
+
return {
|
80
|
+
id,
|
81
|
+
keyTag,
|
82
|
+
credential,
|
83
|
+
isOptional,
|
84
|
+
requiredDisclosures
|
85
|
+
};
|
86
|
+
});
|
87
|
+
} catch (error) {
|
88
|
+
// Invalid DCQL query structure
|
89
|
+
if (isValiError(error)) {
|
90
|
+
throw new ValidationFailed({
|
91
|
+
message: "Invalid DCQL query",
|
92
|
+
reason: error.issues.map(issue => issue.message).join(", ")
|
93
|
+
});
|
94
|
+
}
|
95
|
+
if (error instanceof DcqlError) {
|
96
|
+
// TODO [SIW-2110]: handle invalid DQCL query or let the error propagate
|
97
|
+
}
|
98
|
+
if (error instanceof DcqlCredentialSetError) {
|
99
|
+
// TODO [SIW-2110]: handle missing credentials or let the error propagate
|
100
|
+
}
|
101
|
+
throw error;
|
102
|
+
}
|
103
|
+
};
|
104
|
+
export const prepareRemotePresentations = async (credentials, nonce, clientId) => {
|
105
|
+
return Promise.all(credentials.map(async item => {
|
106
|
+
const {
|
107
|
+
vp_token
|
108
|
+
} = await prepareVpToken(nonce, clientId, [item.credential, item.requestedClaims, createCryptoContextFor(item.keyTag)]);
|
109
|
+
return {
|
110
|
+
credentialId: item.id,
|
111
|
+
requestedClaims: item.requestedClaims,
|
112
|
+
vpToken: vp_token,
|
113
|
+
format: "vc+sd-jwt"
|
114
|
+
};
|
115
|
+
}));
|
116
|
+
};
|
117
|
+
//# sourceMappingURL=07-evaluate-dcql-query.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"names":["DcqlQuery","DcqlError","DcqlCredentialSetError","isValiError","decode","prepareVpToken","ValidationFailed","createCryptoContextFor","mapCredentialToObject","jwt","sdJwt","disclosures","credentialFormat","header","typ","Error","vct","payload","credential_format","claims","reduce","acc","disclosure","decoded","getDcqlQueryMatches","result","Object","entries","credential_matches","filter","_ref","match","success","evaluateDcqlQuery","credentialsSdJwt","query","credentials","map","_ref2","credential","parsedQuery","parse","validate","queryResult","canBeSatisfied","credentialsSdJwtByVct","c","i","_ref3","_queryResult$credenti","id","output","credentialSet","credential_sets","find","set","_set$matching_options","matching_options","flat","includes","isOptional","required","keyTag","requiredDisclosures","values","error","message","reason","issues","issue","join","prepareRemotePresentations","nonce","clientId","Promise","all","item","vp_token","requestedClaims","credentialId","vpToken","format"],"sourceRoot":"../../../../src","sources":["credential/presentation/07-evaluate-dcql-query.ts"],"mappings":"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"}
|
@@ -0,0 +1,278 @@
|
|
1
|
+
import { decode, prepareVpToken } from "../../sd-jwt";
|
2
|
+
import { createCryptoContextFor } from "../../utils/crypto";
|
3
|
+
import { JSONPath } from "jsonpath-plus";
|
4
|
+
import { CredentialNotFoundError, MissingDataError } from "./errors";
|
5
|
+
import Ajv from "ajv";
|
6
|
+
const ajv = new Ajv({
|
7
|
+
allErrors: true
|
8
|
+
});
|
9
|
+
const INDEX_CLAIM_NAME = 1;
|
10
|
+
/**
|
11
|
+
* Transforms an array of DisclosureWithEncoded objects into a key-value map.
|
12
|
+
* @param disclosures - An array of DisclosureWithEncoded, each containing a decoded property with [?, claimName, claimValue].
|
13
|
+
* @returns An object mapping claim names to their corresponding values.
|
14
|
+
*/
|
15
|
+
const mapDisclosuresToObject = disclosures => {
|
16
|
+
return disclosures.reduce((obj, _ref) => {
|
17
|
+
let {
|
18
|
+
decoded
|
19
|
+
} = _ref;
|
20
|
+
const [, claimName, claimValue] = decoded;
|
21
|
+
obj[claimName] = claimValue;
|
22
|
+
return obj;
|
23
|
+
}, {});
|
24
|
+
};
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Finds a claim within the payload based on provided JSONPath expressions.
|
28
|
+
* @param paths - An array of JSONPath expressions to search for in the payload.
|
29
|
+
* @param payload - The object to search within using JSONPath.
|
30
|
+
* @returns A tuple with the first matched JSONPath and its corresponding value, or [undefined, undefined] if not found.
|
31
|
+
*/
|
32
|
+
const findMatchedClaim = (paths, payload) => {
|
33
|
+
let matchedPath;
|
34
|
+
let matchedValue;
|
35
|
+
paths.some(singlePath => {
|
36
|
+
try {
|
37
|
+
const result = JSONPath({
|
38
|
+
path: singlePath,
|
39
|
+
json: payload
|
40
|
+
});
|
41
|
+
if (result.length > 0) {
|
42
|
+
matchedPath = singlePath;
|
43
|
+
matchedValue = result[0];
|
44
|
+
return true;
|
45
|
+
}
|
46
|
+
} catch (error) {
|
47
|
+
throw new MissingDataError(`JSONPath for "${singlePath}" does not match the provided payload.`);
|
48
|
+
}
|
49
|
+
return false;
|
50
|
+
});
|
51
|
+
return [matchedPath, matchedValue];
|
52
|
+
};
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Extracts the claim name from a path that can be in one of the following formats:
|
56
|
+
* 1. $.propertyName
|
57
|
+
* 2. $["propertyName"] or $['propertyName']
|
58
|
+
*
|
59
|
+
* @param path - The path string containing the claim reference.
|
60
|
+
* @returns The extracted claim name if matched; otherwise, throws an exception.
|
61
|
+
*/
|
62
|
+
const extractClaimName = path => {
|
63
|
+
// Define a regular expression that matches both formats:
|
64
|
+
// 1. $.propertyName
|
65
|
+
// 2. $["propertyName"] or $['propertyName']
|
66
|
+
const regex = /^\$\.(\w+)$|^\$\[(?:'|")(\w+)(?:'|")\]$/;
|
67
|
+
const match = path.match(regex);
|
68
|
+
if (match) {
|
69
|
+
// match[1] corresponds to the first capture group (\w+) after $.
|
70
|
+
// match[2] corresponds to the second capture group (\w+) inside [""] or ['']
|
71
|
+
return match[1] || match[2];
|
72
|
+
}
|
73
|
+
|
74
|
+
// If the input doesn't match any of the expected formats, return null
|
75
|
+
|
76
|
+
throw new Error(`Invalid input format: "${path}". Expected formats are "$.propertyName", "$['propertyName']", or '$["propertyName"]'.`);
|
77
|
+
};
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Evaluates an InputDescriptor for an SD-JWT-based verifiable credential.
|
81
|
+
*
|
82
|
+
* - Checks each field in the InputDescriptor against the provided `payloadCredential`
|
83
|
+
* and `disclosures` (selectively disclosed claims).
|
84
|
+
* - Validates whether required fields are present (unless marked optional)
|
85
|
+
* and match any specified JSONPath.
|
86
|
+
* - If a field includes a JSON Schema filter, validates the claim value against that schema.
|
87
|
+
* - Enforces `limit_disclosure` rules by returning only disclosures, required and optional, matching the specified fields
|
88
|
+
* if set to "required". Otherwise also return the array unrequestedDisclosures with disclosures which can be passed for a particular use case.
|
89
|
+
* - Throws an error if a required field is invalid or missing.
|
90
|
+
*
|
91
|
+
* @param inputDescriptor - Describes constraints (fields, filters, etc.) that must be satisfied.
|
92
|
+
* @param payloadCredential - The credential payload to check against.
|
93
|
+
* @param disclosures - An array of DisclosureWithEncoded objects representing selective disclosures.
|
94
|
+
* @returns A filtered list of disclosures satisfying the descriptor constraints, or throws an error if not.
|
95
|
+
* @throws Will throw an error if any required constraint fails or if JSONPath lookups are invalid.
|
96
|
+
*/
|
97
|
+
export const evaluateInputDescriptorForSdJwt4VC = (inputDescriptor, payloadCredential, disclosures) => {
|
98
|
+
var _inputDescriptor$cons;
|
99
|
+
if (!(inputDescriptor !== null && inputDescriptor !== void 0 && (_inputDescriptor$cons = inputDescriptor.constraints) !== null && _inputDescriptor$cons !== void 0 && _inputDescriptor$cons.fields)) {
|
100
|
+
// No validation, all field are optional
|
101
|
+
return {
|
102
|
+
requiredDisclosures: [],
|
103
|
+
optionalDisclosures: [],
|
104
|
+
unrequestedDisclosures: disclosures
|
105
|
+
};
|
106
|
+
}
|
107
|
+
const requiredClaimNames = [];
|
108
|
+
const optionalClaimNames = [];
|
109
|
+
|
110
|
+
// Transform disclosures to find claim using JSONPath
|
111
|
+
const disclosuresAsPayload = mapDisclosuresToObject(disclosures);
|
112
|
+
|
113
|
+
// For each field, we need at least one matching path
|
114
|
+
// If we succeed, we push the matched disclosure in matchedDisclosures and stop checking further paths
|
115
|
+
const allFieldsValid = inputDescriptor.constraints.fields.every(field => {
|
116
|
+
// For Potential profile, selectively disclosed claims will always be built as an individual object property, by using a name-value pair.
|
117
|
+
// Hence that selective claim for array element and recursive disclosures are not supported by Potential for the first iteration of Piloting.
|
118
|
+
// We need to check inside disclosures or inside credential payload. Example path: "$.given_name"
|
119
|
+
let [matchedPath, matchedValue] = findMatchedClaim(field.path, disclosuresAsPayload);
|
120
|
+
if (!matchedPath) {
|
121
|
+
[matchedPath, matchedValue] = findMatchedClaim(field.path, payloadCredential);
|
122
|
+
if (!matchedPath) {
|
123
|
+
// Path could be optional, in this case no need to validate! continue to next field
|
124
|
+
return field === null || field === void 0 ? void 0 : field.optional;
|
125
|
+
}
|
126
|
+
} else {
|
127
|
+
// if match a disclouse we save which is required or optional
|
128
|
+
const claimName = extractClaimName(matchedPath);
|
129
|
+
if (claimName) {
|
130
|
+
(field !== null && field !== void 0 && field.optional ? optionalClaimNames : requiredClaimNames).push(claimName);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
// FILTER validation
|
135
|
+
// If this field has a "filter" (JSON Schema), validate the claimValue
|
136
|
+
if (field.filter) {
|
137
|
+
try {
|
138
|
+
const validateSchema = ajv.compile(field.filter);
|
139
|
+
if (!validateSchema(matchedValue)) {
|
140
|
+
throw new MissingDataError(`Claim value "${matchedValue}" for path "${matchedPath}" does not match the provided JSON Schema.`);
|
141
|
+
}
|
142
|
+
} catch (error) {
|
143
|
+
return false;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
// Submission Requirements validation
|
147
|
+
// TODO: [EUDIW-216] Read rule value if “all” o “pick” and validate
|
148
|
+
|
149
|
+
return true;
|
150
|
+
});
|
151
|
+
if (!allFieldsValid) {
|
152
|
+
throw new MissingDataError("Credential validation failed: Required fields are missing or do not match the input descriptor.");
|
153
|
+
}
|
154
|
+
|
155
|
+
// Categorizes disclosures into required and optional based on claim names and disclosure constraints.
|
156
|
+
|
157
|
+
const requiredDisclosures = disclosures.filter(disclosure => requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]));
|
158
|
+
const optionalDisclosures = disclosures.filter(disclosure => optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]));
|
159
|
+
const isNotLimitDisclosure = !(inputDescriptor.constraints.limit_disclosure === "required");
|
160
|
+
const unrequestedDisclosures = isNotLimitDisclosure ? disclosures.filter(disclosure => !optionalClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME]) && !requiredClaimNames.includes(disclosure.decoded[INDEX_CLAIM_NAME])) : [];
|
161
|
+
return {
|
162
|
+
requiredDisclosures,
|
163
|
+
optionalDisclosures,
|
164
|
+
unrequestedDisclosures
|
165
|
+
};
|
166
|
+
};
|
167
|
+
/**
|
168
|
+
* Finds the first credential that satisfies the input descriptor constraints.
|
169
|
+
* @param inputDescriptor The input descriptor to evaluate.
|
170
|
+
* @param decodedSdJwtCredentials An array of decoded SD-JWT credentials.
|
171
|
+
* @returns An object containing the matched evaluation, keyTag, and credential.
|
172
|
+
*/
|
173
|
+
export const findCredentialSdJwt = (inputDescriptor, decodedSdJwtCredentials) => {
|
174
|
+
for (const {
|
175
|
+
keyTag,
|
176
|
+
credential,
|
177
|
+
sdJwt,
|
178
|
+
disclosures
|
179
|
+
} of decodedSdJwtCredentials) {
|
180
|
+
try {
|
181
|
+
const evaluatedDisclosure = evaluateInputDescriptorForSdJwt4VC(inputDescriptor, sdJwt.payload, disclosures);
|
182
|
+
return {
|
183
|
+
matchedEvaluation: evaluatedDisclosure,
|
184
|
+
matchedKeyTag: keyTag,
|
185
|
+
matchedCredential: credential
|
186
|
+
};
|
187
|
+
} catch {
|
188
|
+
// skip to next credential
|
189
|
+
continue;
|
190
|
+
}
|
191
|
+
}
|
192
|
+
throw new CredentialNotFoundError("None of the vc+sd-jwt credentials satisfy the requirements.");
|
193
|
+
};
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Evaluates multiple input descriptors against provided SD-JWT and MDOC credentials.
|
197
|
+
*
|
198
|
+
* For each input descriptor, this function:
|
199
|
+
* - Checks the credential format.
|
200
|
+
* - Decodes the credential.
|
201
|
+
* - Evaluates the descriptor using the associated disclosures.
|
202
|
+
*
|
203
|
+
* @param inputDescriptors - An array of input descriptors.
|
204
|
+
* @param credentialsSdJwt - An array of tuples containing keyTag and SD-JWT credential.
|
205
|
+
* @returns An array of objects, each containing the evaluated disclosures,
|
206
|
+
* the input descriptor, the credential, and the keyTag.
|
207
|
+
* @throws {CredentialNotFoundError} When the credential format is unsupported.
|
208
|
+
*/
|
209
|
+
export const evaluateInputDescriptors = async (inputDescriptors, credentialsSdJwt) => {
|
210
|
+
// We need decode SD-JWT credentials for evaluation
|
211
|
+
const decodedSdJwtCredentials = (credentialsSdJwt === null || credentialsSdJwt === void 0 ? void 0 : credentialsSdJwt.map(_ref2 => {
|
212
|
+
let [keyTag, credential] = _ref2;
|
213
|
+
const {
|
214
|
+
sdJwt,
|
215
|
+
disclosures
|
216
|
+
} = decode(credential);
|
217
|
+
return {
|
218
|
+
keyTag,
|
219
|
+
credential,
|
220
|
+
sdJwt,
|
221
|
+
disclosures
|
222
|
+
};
|
223
|
+
})) || [];
|
224
|
+
return Promise.all(inputDescriptors.map(async descriptor => {
|
225
|
+
var _descriptor$format;
|
226
|
+
if ((_descriptor$format = descriptor.format) !== null && _descriptor$format !== void 0 && _descriptor$format["vc+sd-jwt"]) {
|
227
|
+
if (!decodedSdJwtCredentials.length) {
|
228
|
+
throw new CredentialNotFoundError("vc+sd-jwt credential is not supported.");
|
229
|
+
}
|
230
|
+
const {
|
231
|
+
matchedEvaluation,
|
232
|
+
matchedKeyTag,
|
233
|
+
matchedCredential
|
234
|
+
} = findCredentialSdJwt(descriptor, decodedSdJwtCredentials);
|
235
|
+
return {
|
236
|
+
evaluatedDisclosure: matchedEvaluation,
|
237
|
+
inputDescriptor: descriptor,
|
238
|
+
credential: matchedCredential,
|
239
|
+
keyTag: matchedKeyTag
|
240
|
+
};
|
241
|
+
}
|
242
|
+
throw new CredentialNotFoundError(`${descriptor.format} format is not supported.`);
|
243
|
+
}));
|
244
|
+
};
|
245
|
+
|
246
|
+
/**
|
247
|
+
* Prepares remote presentations for a set of credentials based on input descriptors.
|
248
|
+
*
|
249
|
+
* For each credential and its corresponding input descriptor, this function:
|
250
|
+
* - Validates the credential format.
|
251
|
+
* - Generates a verifiable presentation token (vpToken) using the provided nonce and client identifier.
|
252
|
+
*
|
253
|
+
* @param credentialAndDescriptors - An array containing objects with requested claims,
|
254
|
+
* input descriptor, credential, and keyTag.
|
255
|
+
* @param nonce - A unique nonce for the verifiable presentation token.
|
256
|
+
* @param client_id - The client identifier.
|
257
|
+
* @returns A promise that resolves to an array of RemotePresentation objects.
|
258
|
+
* @throws {CredentialNotFoundError} When the credential format is unsupported.
|
259
|
+
*/
|
260
|
+
export const prepareRemotePresentations = async (credentialAndDescriptors, nonce, client_id) => {
|
261
|
+
return Promise.all(credentialAndDescriptors.map(async item => {
|
262
|
+
var _descriptor$format2;
|
263
|
+
const descriptor = item.inputDescriptor;
|
264
|
+
if ((_descriptor$format2 = descriptor.format) !== null && _descriptor$format2 !== void 0 && _descriptor$format2["vc+sd-jwt"]) {
|
265
|
+
const {
|
266
|
+
vp_token
|
267
|
+
} = await prepareVpToken(nonce, client_id, [item.credential, item.requestedClaims, createCryptoContextFor(item.keyTag)]);
|
268
|
+
return {
|
269
|
+
requestedClaims: item.requestedClaims,
|
270
|
+
inputDescriptor: descriptor,
|
271
|
+
vpToken: vp_token,
|
272
|
+
format: "vc+sd-jwt"
|
273
|
+
};
|
274
|
+
}
|
275
|
+
throw new CredentialNotFoundError(`${descriptor.format} format is not supported.`);
|
276
|
+
}));
|
277
|
+
};
|
278
|
+
//# sourceMappingURL=07-evaluate-input-descriptor.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"names":["decode","prepareVpToken","createCryptoContextFor","JSONPath","CredentialNotFoundError","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","unrequestedDisclosures","requiredClaimNames","optionalClaimNames","disclosuresAsPayload","allFieldsValid","every","field","optional","push","filter","validateSchema","compile","disclosure","includes","isNotLimitDisclosure","limit_disclosure","findCredentialSdJwt","decodedSdJwtCredentials","keyTag","credential","sdJwt","evaluatedDisclosure","matchedEvaluation","matchedKeyTag","matchedCredential","evaluateInputDescriptors","inputDescriptors","credentialsSdJwt","map","_ref2","Promise","all","descriptor","_descriptor$format","format","prepareRemotePresentations","credentialAndDescriptors","nonce","client_id","item","_descriptor$format2","vp_token","requestedClaims","vpToken"],"sourceRoot":"../../../../src","sources":["credential/presentation/07-evaluate-input-descriptor.ts"],"mappings":"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"}
|