@pagopa/io-react-native-wallet 0.28.1 → 0.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/credential/issuance/04-complete-user-authorization.js +5 -3
- package/lib/commonjs/credential/issuance/04-complete-user-authorization.js.map +1 -1
- package/lib/commonjs/credential/presentation/01-start-flow.js +6 -7
- package/lib/commonjs/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/commonjs/credential/presentation/02-evaluate-rp-trust.js +4 -2
- package/lib/commonjs/credential/presentation/02-evaluate-rp-trust.js.map +1 -1
- package/lib/commonjs/credential/presentation/03-get-request-object.js +2 -2
- package/lib/commonjs/credential/presentation/03-get-request-object.js.map +1 -1
- package/lib/commonjs/credential/presentation/05-verify-request-object.js +11 -4
- package/lib/commonjs/credential/presentation/05-verify-request-object.js.map +1 -1
- package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js +19 -10
- package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js.map +1 -1
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +10 -3
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js +4 -4
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -1
- package/lib/commonjs/credential/presentation/README.md +88 -2
- package/lib/commonjs/credential/presentation/errors.js +5 -6
- package/lib/commonjs/credential/presentation/errors.js.map +1 -1
- package/lib/commonjs/credential/presentation/index.js +27 -2
- package/lib/commonjs/credential/presentation/index.js.map +1 -1
- package/lib/commonjs/credential/presentation/types.js +1 -1
- package/lib/commonjs/credential/presentation/types.js.map +1 -1
- package/lib/module/credential/issuance/04-complete-user-authorization.js +5 -3
- package/lib/module/credential/issuance/04-complete-user-authorization.js.map +1 -1
- package/lib/module/credential/presentation/01-start-flow.js +6 -7
- package/lib/module/credential/presentation/01-start-flow.js.map +1 -1
- package/lib/module/credential/presentation/02-evaluate-rp-trust.js +4 -2
- package/lib/module/credential/presentation/02-evaluate-rp-trust.js.map +1 -1
- package/lib/module/credential/presentation/03-get-request-object.js +2 -2
- package/lib/module/credential/presentation/03-get-request-object.js.map +1 -1
- package/lib/module/credential/presentation/05-verify-request-object.js +11 -4
- package/lib/module/credential/presentation/05-verify-request-object.js.map +1 -1
- package/lib/module/credential/presentation/07-evaluate-dcql-query.js +20 -10
- package/lib/module/credential/presentation/07-evaluate-dcql-query.js.map +1 -1
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +8 -1
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
- package/lib/module/credential/presentation/08-send-authorization-response.js +4 -4
- package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -1
- package/lib/module/credential/presentation/README.md +88 -2
- package/lib/module/credential/presentation/errors.js +5 -6
- package/lib/module/credential/presentation/errors.js.map +1 -1
- package/lib/module/credential/presentation/index.js +4 -3
- package/lib/module/credential/presentation/index.js.map +1 -1
- package/lib/module/credential/presentation/types.js +1 -1
- package/lib/module/credential/presentation/types.js.map +1 -1
- package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts +2 -2
- package/lib/typescript/credential/issuance/04-complete-user-authorization.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/01-start-flow.d.ts +1 -6
- package/lib/typescript/credential/presentation/01-start-flow.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/02-evaluate-rp-trust.d.ts +1 -0
- package/lib/typescript/credential/presentation/02-evaluate-rp-trust.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts +1 -2
- package/lib/typescript/credential/presentation/03-get-request-object.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/05-verify-request-object.d.ts +4 -2
- package/lib/typescript/credential/presentation/05-verify-request-object.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/07-evaluate-dcql-query.d.ts +13 -5
- package/lib/typescript/credential/presentation/07-evaluate-dcql-query.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts +7 -2
- package/lib/typescript/credential/presentation/07-evaluate-input-descriptor.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +3 -3
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/errors.d.ts +3 -4
- package/lib/typescript/credential/presentation/errors.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/index.d.ts +5 -4
- package/lib/typescript/credential/presentation/index.d.ts.map +1 -1
- package/lib/typescript/credential/presentation/types.d.ts +3 -3
- package/package.json +3 -3
- package/src/credential/issuance/04-complete-user-authorization.ts +6 -3
- package/src/credential/presentation/01-start-flow.ts +10 -13
- package/src/credential/presentation/02-evaluate-rp-trust.ts +3 -2
- package/src/credential/presentation/03-get-request-object.ts +2 -3
- package/src/credential/presentation/05-verify-request-object.ts +17 -6
- package/src/credential/presentation/07-evaluate-dcql-query.ts +25 -17
- package/src/credential/presentation/07-evaluate-input-descriptor.ts +32 -30
- package/src/credential/presentation/08-send-authorization-response.ts +9 -7
- package/src/credential/presentation/README.md +88 -2
- package/src/credential/presentation/errors.ts +6 -6
- package/src/credential/presentation/index.ts +22 -4
- package/src/credential/presentation/types.ts +1 -1
@@ -10,6 +10,7 @@ export type EvaluateRelyingPartyTrust = (
|
|
10
10
|
}
|
11
11
|
) => Promise<{
|
12
12
|
rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"];
|
13
|
+
subject: string;
|
13
14
|
}>;
|
14
15
|
|
15
16
|
/**
|
@@ -25,9 +26,9 @@ export const evaluateRelyingPartyTrust: EvaluateRelyingPartyTrust = async (
|
|
25
26
|
{ appFetch = fetch } = {}
|
26
27
|
) => {
|
27
28
|
const {
|
28
|
-
payload: { metadata: rpConf },
|
29
|
+
payload: { metadata: rpConf, sub },
|
29
30
|
} = await getRelyingPartyEntityConfiguration(rpUrl, {
|
30
31
|
appFetch,
|
31
32
|
});
|
32
|
-
return { rpConf };
|
33
|
+
return { rpConf, subject: sub };
|
33
34
|
};
|
@@ -4,9 +4,8 @@ import { RequestObjectWalletCapabilities } from "./types";
|
|
4
4
|
|
5
5
|
export type GetRequestObject = (
|
6
6
|
requestUri: Out<StartFlow>["requestUri"],
|
7
|
-
context
|
7
|
+
context?: {
|
8
8
|
appFetch?: GlobalFetch["fetch"];
|
9
|
-
walletInstanceAttestation: string;
|
10
9
|
walletCapabilities?: RequestObjectWalletCapabilities;
|
11
10
|
}
|
12
11
|
) => Promise<{ requestObjectEncodedJwt: string }>;
|
@@ -23,7 +22,7 @@ export type GetRequestObject = (
|
|
23
22
|
*/
|
24
23
|
export const getRequestObject: GetRequestObject = async (
|
25
24
|
requestUri,
|
26
|
-
{ appFetch = fetch, walletCapabilities }
|
25
|
+
{ appFetch = fetch, walletCapabilities } = {}
|
27
26
|
) => {
|
28
27
|
if (walletCapabilities) {
|
29
28
|
// Validate external input
|
@@ -8,8 +8,9 @@ export type VerifyRequestObject = (
|
|
8
8
|
requestObjectEncodedJwt: string,
|
9
9
|
context: {
|
10
10
|
clientId: string;
|
11
|
-
|
12
|
-
|
11
|
+
rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"];
|
12
|
+
rpSubject: string;
|
13
|
+
state?: string;
|
13
14
|
}
|
14
15
|
) => Promise<{ requestObject: RequestObject }>;
|
15
16
|
|
@@ -17,16 +18,16 @@ export type VerifyRequestObject = (
|
|
17
18
|
* Function to verify the Request Object's signature and the client ID.
|
18
19
|
* @param requestObjectEncodedJwt The Request Object in JWT format
|
19
20
|
* @param context.clientId The client ID to verify
|
20
|
-
* @param context.jwkKeys The set of keys to verify the signature
|
21
21
|
* @param context.rpConf The Entity Configuration of the Relying Party
|
22
|
+
* @param context.state Optional state
|
22
23
|
* @returns The verified Request Object
|
23
24
|
*/
|
24
25
|
export const verifyRequestObject: VerifyRequestObject = async (
|
25
26
|
requestObjectEncodedJwt,
|
26
|
-
{ clientId, rpConf }
|
27
|
+
{ clientId, rpConf, rpSubject, state }
|
27
28
|
) => {
|
28
29
|
const requestObjectJwt = decodeJwt(requestObjectEncodedJwt);
|
29
|
-
const { keys } = getJwksFromConfig(rpConf
|
30
|
+
const { keys } = getJwksFromConfig(rpConf);
|
30
31
|
|
31
32
|
// Verify token signature to ensure the request object is authentic
|
32
33
|
const pubKey = keys?.find(
|
@@ -42,11 +43,21 @@ export const verifyRequestObject: VerifyRequestObject = async (
|
|
42
43
|
|
43
44
|
const requestObject = RequestObject.parse(requestObjectJwt.payload);
|
44
45
|
|
45
|
-
|
46
|
+
const isClientIdMatch =
|
47
|
+
clientId === requestObject.client_id && clientId === rpSubject;
|
48
|
+
|
49
|
+
if (!isClientIdMatch) {
|
46
50
|
throw new UnverifiedEntityError(
|
47
51
|
"Client ID does not match Request Object or Entity Configuration"
|
48
52
|
);
|
49
53
|
}
|
50
54
|
|
55
|
+
const isStateMatch =
|
56
|
+
state && requestObject.state ? state === requestObject.state : true;
|
57
|
+
|
58
|
+
if (!isStateMatch) {
|
59
|
+
throw new UnverifiedEntityError("State does not match Request Object");
|
60
|
+
}
|
61
|
+
|
51
62
|
return { requestObject };
|
52
63
|
};
|
@@ -6,23 +6,32 @@ import {
|
|
6
6
|
} from "dcql";
|
7
7
|
import { isValiError } from "valibot";
|
8
8
|
import { decode, prepareVpToken } from "../../sd-jwt";
|
9
|
-
import type { Disclosure
|
9
|
+
import type { Disclosure } from "../../sd-jwt/types";
|
10
10
|
import { ValidationFailed } from "../../utils/errors";
|
11
11
|
import { createCryptoContextFor } from "../../utils/crypto";
|
12
12
|
import type { RemotePresentation } from "./types";
|
13
13
|
|
14
|
-
|
14
|
+
/**
|
15
|
+
* The purpose for the credential request by the RP.
|
16
|
+
*/
|
17
|
+
type CredentialPurpose = {
|
18
|
+
required: boolean;
|
19
|
+
description?: string;
|
20
|
+
};
|
21
|
+
|
22
|
+
export type EvaluateDcqlQuery = (
|
15
23
|
credentialsSdJwt: [string /* keyTag */, string /* credential */][],
|
16
24
|
query: DcqlQuery.Input
|
17
25
|
) => {
|
18
26
|
id: string;
|
27
|
+
vct: string;
|
19
28
|
credential: string;
|
20
29
|
keyTag: string;
|
21
|
-
requiredDisclosures:
|
22
|
-
|
30
|
+
requiredDisclosures: Disclosure[];
|
31
|
+
purposes: CredentialPurpose[];
|
23
32
|
}[];
|
24
33
|
|
25
|
-
type PrepareRemotePresentations = (
|
34
|
+
export type PrepareRemotePresentations = (
|
26
35
|
credentials: {
|
27
36
|
id: string;
|
28
37
|
credential: string;
|
@@ -90,7 +99,6 @@ export const evaluateDcqlQuery: EvaluateDcqlQuery = (
|
|
90
99
|
if (!queryResult.canBeSatisfied) {
|
91
100
|
throw new Error("No credential can satisfy the provided DCQL query");
|
92
101
|
}
|
93
|
-
|
94
102
|
// Build an object vct:credentialJwt to map matched credentials to their JWT
|
95
103
|
const credentialsSdJwtByVct = credentials.reduce(
|
96
104
|
(acc, c, i) => ({ ...acc, [c.vct]: credentialsSdJwt[i]! }),
|
@@ -103,24 +111,24 @@ export const evaluateDcqlQuery: EvaluateDcqlQuery = (
|
|
103
111
|
}
|
104
112
|
const { vct, claims } = match.output;
|
105
113
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
const isOptional = credentialSet ? !credentialSet.required : false;
|
114
|
+
const purposes = queryResult.credential_sets
|
115
|
+
?.filter((set) => set.matching_options?.flat().includes(id))
|
116
|
+
?.map<CredentialPurpose>((credentialSet) => ({
|
117
|
+
description: credentialSet.purpose?.toString(),
|
118
|
+
required: Boolean(credentialSet.required),
|
119
|
+
}));
|
113
120
|
|
114
121
|
const [keyTag, credential] = credentialsSdJwtByVct[vct]!;
|
115
|
-
const requiredDisclosures = Object.values(
|
116
|
-
claims
|
117
|
-
) as DisclosureWithEncoded[];
|
122
|
+
const requiredDisclosures = Object.values(claims) as Disclosure[];
|
118
123
|
return {
|
119
124
|
id,
|
125
|
+
vct,
|
120
126
|
keyTag,
|
121
127
|
credential,
|
122
|
-
isOptional,
|
123
128
|
requiredDisclosures,
|
129
|
+
// When it is a match but no credential_sets are found, the credential is required by default
|
130
|
+
// See https://openid.net/specs/openid-4-verifiable-presentations-1_0-24.html#section-6.3.1.2-2.1
|
131
|
+
purposes: purposes ?? [{ required: true }],
|
124
132
|
};
|
125
133
|
});
|
126
134
|
} catch (error) {
|
@@ -33,7 +33,10 @@ export type EvaluateInputDescriptors = (
|
|
33
33
|
}[]
|
34
34
|
>;
|
35
35
|
|
36
|
-
|
36
|
+
/**
|
37
|
+
* @deprecated Use `prepareRemotePresentations` from DCQL
|
38
|
+
*/
|
39
|
+
export type PrepareLegacyRemotePresentations = (
|
37
40
|
credentialAndDescriptors: {
|
38
41
|
requestedClaims: string[];
|
39
42
|
inputDescriptor: InputDescriptor;
|
@@ -352,6 +355,8 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
|
|
352
355
|
* - Validates the credential format.
|
353
356
|
* - Generates a verifiable presentation token (vpToken) using the provided nonce and client identifier.
|
354
357
|
*
|
358
|
+
* @deprecated Use `prepareRemotePresentations` from DCQL
|
359
|
+
*
|
355
360
|
* @param credentialAndDescriptors - An array containing objects with requested claims,
|
356
361
|
* input descriptor, credential, and keyTag.
|
357
362
|
* @param nonce - A unique nonce for the verifiable presentation token.
|
@@ -359,33 +364,30 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
|
|
359
364
|
* @returns A promise that resolves to an array of RemotePresentation objects.
|
360
365
|
* @throws {CredentialNotFoundError} When the credential format is unsupported.
|
361
366
|
*/
|
362
|
-
export const
|
363
|
-
credentialAndDescriptors,
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
format: "vc+sd-jwt",
|
383
|
-
};
|
384
|
-
}
|
367
|
+
export const prepareLegacyRemotePresentations: PrepareLegacyRemotePresentations =
|
368
|
+
async (credentialAndDescriptors, nonce, client_id) => {
|
369
|
+
return Promise.all(
|
370
|
+
credentialAndDescriptors.map(async (item) => {
|
371
|
+
const descriptor = item.inputDescriptor;
|
372
|
+
|
373
|
+
if (descriptor.format?.["vc+sd-jwt"]) {
|
374
|
+
const { vp_token } = await prepareVpToken(nonce, client_id, [
|
375
|
+
item.credential,
|
376
|
+
item.requestedClaims,
|
377
|
+
createCryptoContextFor(item.keyTag),
|
378
|
+
]);
|
379
|
+
|
380
|
+
return {
|
381
|
+
requestedClaims: item.requestedClaims,
|
382
|
+
inputDescriptor: descriptor,
|
383
|
+
vpToken: vp_token,
|
384
|
+
format: "vc+sd-jwt",
|
385
|
+
};
|
386
|
+
}
|
385
387
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
};
|
388
|
+
throw new CredentialNotFoundError(
|
389
|
+
`${descriptor.format} format is not supported.`
|
390
|
+
);
|
391
|
+
})
|
392
|
+
);
|
393
|
+
};
|
@@ -60,7 +60,7 @@ export const choosePublicKeyToEncrypt = (
|
|
60
60
|
*/
|
61
61
|
export const buildDirectPostJwtBody = async (
|
62
62
|
requestObject: Out<VerifyRequestObject>["requestObject"],
|
63
|
-
rpConf: RelyingPartyEntityConfiguration["payload"],
|
63
|
+
rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"],
|
64
64
|
payload: DirectAuthorizationBodyPayload | LegacyDirectAuthorizationBodyPayload
|
65
65
|
): Promise<string> => {
|
66
66
|
type Jwe = ConstructorParameters<typeof EncryptJwe>[1];
|
@@ -70,19 +70,21 @@ export const buildDirectPostJwtBody = async (
|
|
70
70
|
state: requestObject.state,
|
71
71
|
...payload,
|
72
72
|
});
|
73
|
-
|
74
73
|
// Choose a suitable public key for encryption
|
75
|
-
const { keys } = getJwksFromConfig(rpConf
|
74
|
+
const { keys } = getJwksFromConfig(rpConf);
|
76
75
|
const encPublicJwk = choosePublicKeyToEncrypt(keys);
|
77
76
|
|
78
77
|
// Encrypt the authorization payload
|
79
78
|
const {
|
80
79
|
authorization_encrypted_response_alg,
|
81
80
|
authorization_encrypted_response_enc,
|
82
|
-
} = rpConf.
|
81
|
+
} = rpConf.openid_credential_verifier;
|
82
|
+
|
83
|
+
const defaultAlg: Jwe["alg"] =
|
84
|
+
encPublicJwk.kty === "EC" ? "ECDH-ES" : "RSA-OAEP-256";
|
83
85
|
|
84
86
|
const encryptedResponse = await new EncryptJwe(authzResponsePayload, {
|
85
|
-
alg: (authorization_encrypted_response_alg as Jwe["alg"]) ||
|
87
|
+
alg: (authorization_encrypted_response_alg as Jwe["alg"]) || defaultAlg,
|
86
88
|
enc:
|
87
89
|
(authorization_encrypted_response_enc as Jwe["enc"]) || "A256CBC-HS512",
|
88
90
|
kid: encPublicJwk.kid,
|
@@ -106,7 +108,7 @@ export type SendLegacyAuthorizationResponse = (
|
|
106
108
|
requestObject: Out<VerifyRequestObject>["requestObject"],
|
107
109
|
presentationDefinitionId: string,
|
108
110
|
remotePresentations: LegacyRemotePresentation[],
|
109
|
-
rpConf: RelyingPartyEntityConfiguration["payload"],
|
111
|
+
rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"],
|
110
112
|
context?: {
|
111
113
|
appFetch?: GlobalFetch["fetch"];
|
112
114
|
}
|
@@ -183,7 +185,7 @@ export const sendLegacyAuthorizationResponse: SendLegacyAuthorizationResponse =
|
|
183
185
|
export type SendAuthorizationResponse = (
|
184
186
|
requestObject: Out<VerifyRequestObject>["requestObject"],
|
185
187
|
remotePresentations: RemotePresentation[],
|
186
|
-
rpConf: RelyingPartyEntityConfiguration["payload"],
|
188
|
+
rpConf: RelyingPartyEntityConfiguration["payload"]["metadata"],
|
187
189
|
context?: {
|
188
190
|
appFetch?: GlobalFetch["fetch"];
|
189
191
|
}
|
@@ -1,3 +1,89 @@
|
|
1
|
-
# Credential
|
1
|
+
# Credential Presentation
|
2
2
|
|
3
|
-
|
3
|
+
This flow is used for remote presentation, allowing a user with a valid Wallet Instance to remotely present credentials to a Relying Party (Verifier). The presentation flow adheres to the [IT Wallet 0.9.x specification](https://italia.github.io/eid-wallet-it-docs/v0.9.3/en/relying-party-solution.html).
|
4
|
+
|
5
|
+
The Relying Party provides the Wallet with a Request Object that contains the requested credentials and claims. The Wallet validates the Request Object and asks the user for consent. Then the Wallet creates an encrypted Authorization Response that contains the Verifiable Presentation with the requested data (`vp_token`) and sends it to the Relying Party.
|
6
|
+
|
7
|
+
## Sequence Diagram
|
8
|
+
|
9
|
+
```mermaid
|
10
|
+
sequenceDiagram
|
11
|
+
autonumber
|
12
|
+
participant I as User (Wallet Instance)
|
13
|
+
participant O as Relying Party (Verifier)
|
14
|
+
|
15
|
+
O->>+I: QR-CODE: Authorization Request (`request_uri`)
|
16
|
+
I->>+O: GET: Verifier's Entity Configuration
|
17
|
+
O->>+I: Respond with metadata (including public keys)
|
18
|
+
I->>+O: GET: Request Object, resolved from the `request_uri`
|
19
|
+
O->>+I: Respond with the Request Object
|
20
|
+
I->>+O: POST: VP token encrypted response
|
21
|
+
O->>+I: Redirect: Authorization Response
|
22
|
+
```
|
23
|
+
|
24
|
+
|
25
|
+
## Examples
|
26
|
+
|
27
|
+
<details>
|
28
|
+
<summary>Remote Presentation flow</summary>
|
29
|
+
|
30
|
+
**Note:** To successfully complete a remote presentation, the Wallet Instance must be in a valid state with a valid Wallet Instance Attestation.
|
31
|
+
|
32
|
+
```ts
|
33
|
+
// Retrieve and scan the qr-code, decode it and get its parameters
|
34
|
+
const qrCodeParams = decodeQrCode(qrCode)
|
35
|
+
|
36
|
+
// Start the issuance flow
|
37
|
+
const {
|
38
|
+
requestUri,
|
39
|
+
clientId,
|
40
|
+
requestUriMethod,
|
41
|
+
state
|
42
|
+
} = Credential.Presentation.startFlowFromQR(qrCodeParams);
|
43
|
+
|
44
|
+
// Get the Relying Party's Entity Configuration and evaluate trust
|
45
|
+
const { rpConf } = await Credential.Presentation.evaluateRelyingPartyTrust(clientId);
|
46
|
+
|
47
|
+
// Get the Request Object from the RP
|
48
|
+
const { requestObjectEncodedJwt } =
|
49
|
+
await Credential.Presentation.getRequestObject(requestUri);
|
50
|
+
|
51
|
+
// Validate the Request Object
|
52
|
+
const { requestObject } = await Credential.Presentation.verifyRequestObject(
|
53
|
+
requestObjectEncodedJwt,
|
54
|
+
{ clientId, rpConf }
|
55
|
+
);
|
56
|
+
|
57
|
+
// All the credentials that might be requested by the Relying Party
|
58
|
+
const credentialsSdJwt = [
|
59
|
+
["credential1_keytag", "eyJraWQiOiItRl82VWdhOG4zVmVnalkyVTdZVUhLMXpMb2FELU5QVGM2M1JNSVNuTGF3IiwidHlwIjoidmMrc2Qtand0IiwiYWxnIjoiRVMyNTYifQ.eyJfc2"],
|
60
|
+
["credential2_keytag", "eyJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ii1GXzZVZ2E4bjNWZWdqWTJVN1lVSEsxekxvYUQtTlBUYzYzUk1JU25MYXcifQ.ew0KIC"]
|
61
|
+
];
|
62
|
+
|
63
|
+
const result = Credential.Presentation.evaluateDcqlQuery(
|
64
|
+
credentialsSdJwt,
|
65
|
+
requestObject.dcql_query as DcqlQuery
|
66
|
+
);
|
67
|
+
|
68
|
+
const credentialsToPresent = result.map(
|
69
|
+
({ requiredDisclosures, ...rest }) => ({
|
70
|
+
...rest,
|
71
|
+
requestedClaims: requiredDisclosures.map(([, claimName]) => claimName),
|
72
|
+
})
|
73
|
+
);
|
74
|
+
|
75
|
+
const remotePresentations =
|
76
|
+
await Credential.Presentation.prepareRemotePresentations(
|
77
|
+
credentialsToPresent,
|
78
|
+
requestObject.nonce,
|
79
|
+
requestObject.client_id
|
80
|
+
);
|
81
|
+
|
82
|
+
const authResponse = await Credential.Presentation.sendAuthorizationResponse(
|
83
|
+
requestObject,
|
84
|
+
remotePresentations,
|
85
|
+
rpConf
|
86
|
+
);
|
87
|
+
```
|
88
|
+
|
89
|
+
</details>
|
@@ -47,12 +47,12 @@ export class NoSuitableKeysFoundInEntityConfiguration extends IoWalletError {
|
|
47
47
|
export class InvalidQRCodeError extends IoWalletError {
|
48
48
|
code = "ERR_INVALID_QR_CODE";
|
49
49
|
|
50
|
-
/**
|
51
|
-
|
52
|
-
|
53
|
-
constructor(
|
54
|
-
|
55
|
-
|
50
|
+
/** Detailed reason for the QR code validation failure. */
|
51
|
+
reason: string;
|
52
|
+
|
53
|
+
constructor(reason: string) {
|
54
|
+
super("Invalid QR code");
|
55
|
+
this.reason = reason;
|
56
56
|
}
|
57
57
|
}
|
58
58
|
|
@@ -17,12 +17,22 @@ import {
|
|
17
17
|
type FetchPresentationDefinition,
|
18
18
|
} from "./06-fetch-presentation-definition";
|
19
19
|
import {
|
20
|
-
|
21
|
-
|
20
|
+
evaluateInputDescriptors,
|
21
|
+
prepareLegacyRemotePresentations,
|
22
|
+
type EvaluateInputDescriptors,
|
23
|
+
type PrepareLegacyRemotePresentations,
|
22
24
|
} from "./07-evaluate-input-descriptor";
|
25
|
+
import {
|
26
|
+
evaluateDcqlQuery,
|
27
|
+
prepareRemotePresentations,
|
28
|
+
type EvaluateDcqlQuery,
|
29
|
+
type PrepareRemotePresentations,
|
30
|
+
} from "./07-evaluate-dcql-query";
|
23
31
|
import {
|
24
32
|
sendAuthorizationResponse,
|
25
33
|
type SendAuthorizationResponse,
|
34
|
+
sendLegacyAuthorizationResponse,
|
35
|
+
type SendLegacyAuthorizationResponse,
|
26
36
|
} from "./08-send-authorization-response";
|
27
37
|
import * as Errors from "./errors";
|
28
38
|
|
@@ -33,8 +43,12 @@ export {
|
|
33
43
|
getJwksFromConfig,
|
34
44
|
verifyRequestObject,
|
35
45
|
fetchPresentDefinition,
|
36
|
-
|
46
|
+
evaluateInputDescriptors,
|
47
|
+
evaluateDcqlQuery,
|
48
|
+
prepareLegacyRemotePresentations,
|
49
|
+
prepareRemotePresentations,
|
37
50
|
sendAuthorizationResponse,
|
51
|
+
sendLegacyAuthorizationResponse,
|
38
52
|
Errors,
|
39
53
|
};
|
40
54
|
export type {
|
@@ -44,6 +58,10 @@ export type {
|
|
44
58
|
FetchJwks,
|
45
59
|
VerifyRequestObject,
|
46
60
|
FetchPresentationDefinition,
|
47
|
-
|
61
|
+
EvaluateInputDescriptors,
|
62
|
+
EvaluateDcqlQuery,
|
63
|
+
PrepareLegacyRemotePresentations,
|
64
|
+
PrepareRemotePresentations,
|
48
65
|
SendAuthorizationResponse,
|
66
|
+
SendLegacyAuthorizationResponse,
|
49
67
|
};
|