@pagopa/io-react-native-wallet 1.7.1 → 1.8.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 +37 -11
- package/lib/commonjs/client/generated/wallet-provider.js.map +1 -1
- package/lib/commonjs/credential/issuance/02-get-issuer-config.js +69 -3
- package/lib/commonjs/credential/issuance/02-get-issuer-config.js.map +1 -1
- package/lib/commonjs/credential/issuance/03-start-user-authorization.js +5 -7
- package/lib/commonjs/credential/issuance/03-start-user-authorization.js.map +1 -1
- package/lib/commonjs/credential/issuance/06-obtain-credential.js +27 -10
- package/lib/commonjs/credential/issuance/06-obtain-credential.js.map +1 -1
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +50 -46
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/commonjs/credential/issuance/README.md +1 -1
- package/lib/commonjs/credential/issuance/const.js +1 -1
- package/lib/commonjs/credential/issuance/const.js.map +1 -1
- package/lib/commonjs/credential/issuance/index.js +6 -0
- package/lib/commonjs/credential/issuance/index.js.map +1 -1
- package/lib/commonjs/credential/issuance/types.js +19 -10
- package/lib/commonjs/credential/issuance/types.js.map +1 -1
- package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js +10 -3
- package/lib/commonjs/credential/presentation/07-evaluate-dcql-query.js.map +1 -1
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js +11 -4
- package/lib/commonjs/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js +3 -3
- package/lib/commonjs/credential/presentation/08-send-authorization-response.js.map +1 -1
- package/lib/commonjs/credential/presentation/types.js.map +1 -1
- package/lib/commonjs/entity/openid-connect/issuer/types.js +2 -2
- package/lib/commonjs/entity/openid-connect/issuer/types.js.map +1 -1
- package/lib/commonjs/entity/trust/types.js +19 -30
- package/lib/commonjs/entity/trust/types.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/mdoc/index.js +3 -3
- package/lib/commonjs/mdoc/index.js.map +1 -1
- package/lib/commonjs/sd-jwt/index.js +2 -2
- package/lib/commonjs/sd-jwt/index.js.map +1 -1
- package/lib/commonjs/sd-jwt/types.js +1 -1
- package/lib/commonjs/sd-jwt/types.js.map +1 -1
- package/lib/commonjs/utils/credential/issuance/07-verify-and-parse-credentials-utils.js +3 -2
- package/lib/commonjs/utils/credential/issuance/07-verify-and-parse-credentials-utils.js.map +1 -1
- package/lib/commonjs/utils/misc.js +23 -1
- package/lib/commonjs/utils/misc.js.map +1 -1
- package/lib/commonjs/utils/pop.js +1 -1
- package/lib/commonjs/utils/pop.js.map +1 -1
- package/lib/commonjs/wallet-instance-attestation/issuing.js +11 -7
- package/lib/commonjs/wallet-instance-attestation/issuing.js.map +1 -1
- package/lib/commonjs/wallet-instance-attestation/types.js +14 -19
- package/lib/commonjs/wallet-instance-attestation/types.js.map +1 -1
- package/lib/module/client/generated/wallet-provider.js +29 -7
- package/lib/module/client/generated/wallet-provider.js.map +1 -1
- package/lib/module/credential/issuance/02-get-issuer-config.js +66 -1
- package/lib/module/credential/issuance/02-get-issuer-config.js.map +1 -1
- package/lib/module/credential/issuance/03-start-user-authorization.js +5 -7
- package/lib/module/credential/issuance/03-start-user-authorization.js.map +1 -1
- package/lib/module/credential/issuance/06-obtain-credential.js +28 -11
- package/lib/module/credential/issuance/06-obtain-credential.js.map +1 -1
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js +50 -46
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/module/credential/issuance/README.md +1 -1
- package/lib/module/credential/issuance/const.js +1 -1
- package/lib/module/credential/issuance/const.js.map +1 -1
- package/lib/module/credential/issuance/index.js +2 -2
- package/lib/module/credential/issuance/index.js.map +1 -1
- package/lib/module/credential/issuance/types.js +15 -8
- package/lib/module/credential/issuance/types.js.map +1 -1
- package/lib/module/credential/presentation/07-evaluate-dcql-query.js +10 -3
- package/lib/module/credential/presentation/07-evaluate-dcql-query.js.map +1 -1
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js +11 -4
- package/lib/module/credential/presentation/07-evaluate-input-descriptor.js.map +1 -1
- package/lib/module/credential/presentation/08-send-authorization-response.js +3 -3
- package/lib/module/credential/presentation/08-send-authorization-response.js.map +1 -1
- package/lib/module/credential/presentation/types.js.map +1 -1
- package/lib/module/entity/openid-connect/issuer/types.js +2 -2
- package/lib/module/entity/openid-connect/issuer/types.js.map +1 -1
- package/lib/module/entity/trust/types.js +19 -30
- package/lib/module/entity/trust/types.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/mdoc/index.js +3 -3
- package/lib/module/mdoc/index.js.map +1 -1
- package/lib/module/sd-jwt/index.js +2 -2
- package/lib/module/sd-jwt/index.js.map +1 -1
- package/lib/module/sd-jwt/types.js +1 -1
- package/lib/module/sd-jwt/types.js.map +1 -1
- package/lib/module/utils/credential/issuance/07-verify-and-parse-credentials-utils.js +3 -2
- package/lib/module/utils/credential/issuance/07-verify-and-parse-credentials-utils.js.map +1 -1
- package/lib/module/utils/misc.js +20 -0
- package/lib/module/utils/misc.js.map +1 -1
- package/lib/module/utils/pop.js +1 -1
- package/lib/module/utils/pop.js.map +1 -1
- package/lib/module/wallet-instance-attestation/issuing.js +13 -9
- package/lib/module/wallet-instance-attestation/issuing.js.map +1 -1
- package/lib/module/wallet-instance-attestation/types.js +12 -17
- package/lib/module/wallet-instance-attestation/types.js.map +1 -1
- package/lib/typescript/client/generated/wallet-provider.d.ts +146 -17
- package/lib/typescript/client/generated/wallet-provider.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/02-get-issuer-config.d.ts +16 -1
- package/lib/typescript/credential/issuance/02-get-issuer-config.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/03-start-user-authorization.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/06-obtain-credential.d.ts +7 -2
- package/lib/typescript/credential/issuance/06-obtain-credential.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/const.d.ts +1 -1
- package/lib/typescript/credential/issuance/const.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/index.d.ts +2 -2
- package/lib/typescript/credential/issuance/index.d.ts.map +1 -1
- package/lib/typescript/credential/issuance/types.d.ts +52 -21
- package/lib/typescript/credential/issuance/types.d.ts.map +1 -1
- 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.map +1 -1
- package/lib/typescript/credential/presentation/08-send-authorization-response.d.ts +1 -1
- package/lib/typescript/credential/presentation/types.d.ts +4 -2
- package/lib/typescript/credential/presentation/types.d.ts.map +1 -1
- package/lib/typescript/entity/openid-connect/issuer/types.d.ts +17 -17
- package/lib/typescript/entity/openid-connect/issuer/types.d.ts.map +1 -1
- package/lib/typescript/entity/trust/index.d.ts +150 -140
- package/lib/typescript/entity/trust/index.d.ts.map +1 -1
- package/lib/typescript/entity/trust/types.d.ts +540 -344
- package/lib/typescript/entity/trust/types.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/pid/sd-jwt/types.d.ts +2 -2
- package/lib/typescript/sd-jwt/index.d.ts +12 -12
- package/lib/typescript/sd-jwt/types.d.ts +14 -14
- package/lib/typescript/utils/credential/issuance/07-verify-and-parse-credentials-utils.d.ts.map +1 -1
- package/lib/typescript/utils/misc.d.ts +8 -0
- package/lib/typescript/utils/misc.d.ts.map +1 -1
- package/lib/typescript/wallet-instance-attestation/issuing.d.ts.map +1 -1
- package/lib/typescript/wallet-instance-attestation/types.d.ts +50 -102
- package/lib/typescript/wallet-instance-attestation/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client/generated/wallet-provider.ts +39 -7
- package/src/credential/issuance/02-get-issuer-config.ts +98 -1
- package/src/credential/issuance/03-start-user-authorization.ts +7 -8
- package/src/credential/issuance/06-obtain-credential.ts +41 -14
- package/src/credential/issuance/07-verify-and-parse-credential.ts +7 -3
- package/src/credential/issuance/README.md +1 -1
- package/src/credential/issuance/const.ts +1 -0
- package/src/credential/issuance/index.ts +6 -1
- package/src/credential/issuance/types.ts +21 -8
- package/src/credential/presentation/07-evaluate-dcql-query.ts +15 -5
- package/src/credential/presentation/07-evaluate-input-descriptor.ts +21 -4
- package/src/credential/presentation/08-send-authorization-response.ts +3 -3
- package/src/credential/presentation/types.ts +3 -0
- package/src/entity/openid-connect/issuer/types.ts +2 -1
- package/src/entity/trust/types.ts +22 -20
- package/src/index.ts +2 -0
- package/src/mdoc/index.ts +3 -3
- package/src/sd-jwt/index.ts +2 -2
- package/src/sd-jwt/types.ts +1 -1
- package/src/utils/credential/issuance/07-verify-and-parse-credentials-utils.ts +3 -2
- package/src/utils/misc.ts +24 -0
- package/src/utils/pop.ts +1 -1
- package/src/wallet-instance-attestation/issuing.ts +14 -8
- package/src/wallet-instance-attestation/types.ts +16 -22
@@ -1,5 +1,11 @@
|
|
1
1
|
import z from "zod";
|
2
2
|
|
3
|
+
export type ApplicationInfo = z.infer<typeof ApplicationInfo>;
|
4
|
+
export const ApplicationInfo = z.object({
|
5
|
+
name: z.string(),
|
6
|
+
version: z.string(),
|
7
|
+
});
|
8
|
+
|
3
9
|
export type NonceDetailView = z.infer<typeof NonceDetailView>;
|
4
10
|
export const NonceDetailView = z.object({
|
5
11
|
nonce: z.string(),
|
@@ -10,6 +16,16 @@ export const WalletAttestationView = z.object({
|
|
10
16
|
wallet_attestation: z.string(),
|
11
17
|
});
|
12
18
|
|
19
|
+
export type WalletAttestationsView = z.infer<typeof WalletAttestationsView>;
|
20
|
+
export const WalletAttestationsView = z.object({
|
21
|
+
wallet_attestations: z.array(
|
22
|
+
z.object({
|
23
|
+
format: z.union([z.literal("jwt"), z.literal("dc+sd-jwt")]),
|
24
|
+
wallet_attestation: z.string(),
|
25
|
+
}),
|
26
|
+
),
|
27
|
+
});
|
28
|
+
|
13
29
|
export type CreateWalletInstanceBody = z.infer<typeof CreateWalletInstanceBody>;
|
14
30
|
export const CreateWalletInstanceBody = z.object({
|
15
31
|
challenge: z.string(),
|
@@ -23,13 +39,9 @@ export const CreateWalletAttestationBody = z.object({
|
|
23
39
|
assertion: z.string(),
|
24
40
|
});
|
25
41
|
|
26
|
-
export type
|
27
|
-
export const
|
28
|
-
|
29
|
-
title: z.string().optional(),
|
30
|
-
status: z.number().optional(),
|
31
|
-
detail: z.string().optional(),
|
32
|
-
instance: z.string().optional(),
|
42
|
+
export type CreateWalletAttestationV2Body = z.infer<typeof CreateWalletAttestationV2Body>;
|
43
|
+
export const CreateWalletAttestationV2Body = z.object({
|
44
|
+
assertion: z.string(),
|
33
45
|
});
|
34
46
|
|
35
47
|
export type SetWalletInstanceStatusBody = z.infer<typeof SetWalletInstanceStatusBody>;
|
@@ -51,6 +63,15 @@ export const WalletInstanceData = z.object({
|
|
51
63
|
revocation_reason: z.union([RevocationReason, z.undefined()]).optional(),
|
52
64
|
});
|
53
65
|
|
66
|
+
export type ProblemDetail = z.infer<typeof ProblemDetail>;
|
67
|
+
export const ProblemDetail = z.object({
|
68
|
+
type: z.string().optional(),
|
69
|
+
title: z.string().optional(),
|
70
|
+
status: z.number().optional(),
|
71
|
+
detail: z.string().optional(),
|
72
|
+
instance: z.string().optional(),
|
73
|
+
});
|
74
|
+
|
54
75
|
export type get_GetNonce = typeof get_GetNonce;
|
55
76
|
export const get_GetNonce = {
|
56
77
|
method: z.literal("GET"),
|
@@ -104,6 +125,16 @@ export const post_CreateWalletAttestation = {
|
|
104
125
|
response: WalletAttestationView,
|
105
126
|
};
|
106
127
|
|
128
|
+
export type post_CreateWalletAttestationV2 = typeof post_CreateWalletAttestationV2;
|
129
|
+
export const post_CreateWalletAttestationV2 = {
|
130
|
+
method: z.literal("POST"),
|
131
|
+
path: z.literal("/wallet-attestations"),
|
132
|
+
parameters: z.object({
|
133
|
+
body: CreateWalletAttestationV2Body,
|
134
|
+
}),
|
135
|
+
response: WalletAttestationsView,
|
136
|
+
};
|
137
|
+
|
107
138
|
// <EndpointByMethod>
|
108
139
|
export const EndpointByMethod = {
|
109
140
|
get: {
|
@@ -113,6 +144,7 @@ export const EndpointByMethod = {
|
|
113
144
|
post: {
|
114
145
|
"/wallet-instances": post_CreateWalletInstance,
|
115
146
|
"/token": post_CreateWalletAttestation,
|
147
|
+
"/wallet-attestations": post_CreateWalletAttestationV2,
|
116
148
|
},
|
117
149
|
put: {
|
118
150
|
"/wallet-instances/{id}/status": put_SetWalletInstanceStatus,
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import type { StartFlow } from "./01-start-flow";
|
2
|
-
import type
|
2
|
+
import { pathInsert, type Out } from "../../utils/misc";
|
3
3
|
import type { JWK } from "src/utils/jwk";
|
4
4
|
import { getCredentialIssuerMetadata } from "../../entity/openid-connect/issuer";
|
5
5
|
import type { CredentialConfigurationSupported } from "../../entity/openid-connect/issuer/types";
|
6
|
+
import { getCredentialIssuerEntityConfiguration } from "@pagopa/io-react-native-wallet";
|
6
7
|
|
7
8
|
export type GetIssuerConfig = (
|
8
9
|
issuerUrl: Out<StartFlow>["issuerUrl"],
|
@@ -21,12 +22,16 @@ export type IssuerConfig = {
|
|
21
22
|
pushed_authorization_request_endpoint: string;
|
22
23
|
authorization_endpoint: string;
|
23
24
|
token_endpoint: string;
|
25
|
+
nonce_endpoint?: string;
|
24
26
|
credential_endpoint: string;
|
27
|
+
issuer: string;
|
25
28
|
keys: Array<JWK>;
|
26
29
|
};
|
27
30
|
|
28
31
|
/**
|
29
32
|
* WARNING: This function must be called after {@link startFlow}. The next function to be called is {@link startUserAuthorization}.
|
33
|
+
* WARNING: This function extracts the {@link IssuerConfig} from the OpenID Connect endpoint. For the OpenID Federation variant, use {@link getIssuerConfigOIDFED}.
|
34
|
+
* WARNING: The variants should not be used in conjunction.
|
30
35
|
* Get the Issuer's configuration from the Issuer's metadata.
|
31
36
|
* Currently it only supports a mixed configuration based on OpenID Connect partial implementation.
|
32
37
|
* @param issuerUrl The base url of the Issuer returned by {@link startFlow}
|
@@ -44,6 +49,27 @@ export const getIssuerConfig: GetIssuerConfig = async (
|
|
44
49
|
return credentialIssuerRationalization(res);
|
45
50
|
};
|
46
51
|
|
52
|
+
/**
|
53
|
+
* WARNING: This function must be called after {@link startFlow}. The next function to be called is {@link startUserAuthorization}.
|
54
|
+
* WARNING: This function extracts the {@link IssuerConfig} from the OpenID Federation EC. For the OpenID Connect variant, use {@link getIssuerConfig}.
|
55
|
+
* WARNING: The variants should not be used in conjunction.
|
56
|
+
* Get the Issuer's configuration from the Issuer's metadata fetched from the OpenID Federation system.
|
57
|
+
* Currently it only supports a mixed configuration based on OpenID Federation partial implementation.
|
58
|
+
* @param issuerUrl The base url of the Issuer returned by {@link startFlow}
|
59
|
+
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
60
|
+
* @returns The Issuer's configuration
|
61
|
+
*/
|
62
|
+
export const getIssuerConfigOIDFED: GetIssuerConfig = async (
|
63
|
+
issuerUrl,
|
64
|
+
context = {}
|
65
|
+
): ReturnType<GetIssuerConfig> => {
|
66
|
+
const res = await getCredentialIssuerEntityConfiguration(issuerUrl, {
|
67
|
+
appFetch: context.appFetch,
|
68
|
+
});
|
69
|
+
|
70
|
+
return credentialIssuerRationalizationOIDFED(res);
|
71
|
+
};
|
72
|
+
|
47
73
|
/**
|
48
74
|
* Rationalize the issuer's metadata to the issuer's configuration which is then used in our flows to interact with the issuer.
|
49
75
|
* @param issuerMetadata - The issuer's metadata
|
@@ -62,6 +88,77 @@ const credentialIssuerRationalization = (
|
|
62
88
|
token_endpoint: issuerMetadata.token_endpoint,
|
63
89
|
credential_endpoint: issuerMetadata.credential_endpoint,
|
64
90
|
keys: issuerMetadata.jwks.keys,
|
91
|
+
issuer: issuerMetadata.authorization_endpoint,
|
92
|
+
},
|
93
|
+
};
|
94
|
+
};
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Rationalize the issuer's metadata taken from OpenID Federation to the issuer's configuration which is then used in our flows to interact with the issuer.
|
98
|
+
* @param issuerMetadata - The issuer's metadata
|
99
|
+
* @returns the isssuer configuration to be used later in our flows
|
100
|
+
*/
|
101
|
+
const credentialIssuerRationalizationOIDFED = (
|
102
|
+
issuerMetadata: Awaited<
|
103
|
+
ReturnType<typeof getCredentialIssuerEntityConfiguration>
|
104
|
+
>
|
105
|
+
): Awaited<ReturnType<GetIssuerConfig>> => {
|
106
|
+
const adapted_credential_configurations_supported: CredentialConfigurationSupported =
|
107
|
+
Object.fromEntries(
|
108
|
+
Object.entries(
|
109
|
+
issuerMetadata.payload.metadata.openid_credential_issuer
|
110
|
+
.credential_configurations_supported
|
111
|
+
).map(([key, config]) => {
|
112
|
+
const claimsRaw = config.claims;
|
113
|
+
|
114
|
+
const claims: CredentialConfigurationSupported[string]["claims"] =
|
115
|
+
Object.entries(claimsRaw)
|
116
|
+
.map(([, v]) => ({
|
117
|
+
path: v.path,
|
118
|
+
details: {
|
119
|
+
mandatory: v.mandatory,
|
120
|
+
display: v.display,
|
121
|
+
},
|
122
|
+
}))
|
123
|
+
.reduce(
|
124
|
+
(cumulated, entry) =>
|
125
|
+
pathInsert(cumulated, entry.path, entry.details),
|
126
|
+
{}
|
127
|
+
);
|
128
|
+
|
129
|
+
const newConfig: CredentialConfigurationSupported[string] = {
|
130
|
+
...config,
|
131
|
+
claims,
|
132
|
+
// cryptographic_suites_supported have been renamed credential_signing_alg_values_supported.
|
133
|
+
// We mantain it for Potential compatibility
|
134
|
+
cryptographic_suites_supported:
|
135
|
+
config.credential_signing_alg_values_supported!,
|
136
|
+
};
|
137
|
+
|
138
|
+
return [key, newConfig];
|
139
|
+
})
|
140
|
+
);
|
141
|
+
|
142
|
+
return {
|
143
|
+
issuerConf: {
|
144
|
+
credential_configurations_supported:
|
145
|
+
adapted_credential_configurations_supported,
|
146
|
+
pushed_authorization_request_endpoint:
|
147
|
+
issuerMetadata.payload.metadata.oauth_authorization_server
|
148
|
+
.pushed_authorization_request_endpoint,
|
149
|
+
authorization_endpoint:
|
150
|
+
issuerMetadata.payload.metadata.oauth_authorization_server
|
151
|
+
.authorization_endpoint,
|
152
|
+
token_endpoint:
|
153
|
+
issuerMetadata.payload.metadata.oauth_authorization_server
|
154
|
+
.token_endpoint,
|
155
|
+
credential_endpoint:
|
156
|
+
issuerMetadata.payload.metadata.openid_credential_issuer
|
157
|
+
.credential_endpoint,
|
158
|
+
keys: issuerMetadata.payload.metadata.openid_credential_issuer.jwks.keys,
|
159
|
+
issuer: issuerMetadata.payload.metadata.oauth_authorization_server.issuer,
|
160
|
+
nonce_endpoint:
|
161
|
+
issuerMetadata.payload.metadata.openid_credential_issuer.nonce_endpoint,
|
65
162
|
},
|
66
163
|
};
|
67
164
|
};
|
@@ -39,18 +39,17 @@ const selectCredentialDefinition = (
|
|
39
39
|
const credential_configurations_supported =
|
40
40
|
issuerConf.credential_configurations_supported;
|
41
41
|
|
42
|
-
const
|
42
|
+
const [result] = Object.keys(credential_configurations_supported)
|
43
|
+
.filter((e) => e.includes(credentialType))
|
44
|
+
.map(() => ({
|
45
|
+
credential_configuration_id: credentialType,
|
46
|
+
type: "openid_credential" as const,
|
47
|
+
}));
|
43
48
|
|
44
|
-
if (!
|
49
|
+
if (!result) {
|
45
50
|
throw new Error(`No credential support the type '${credentialType}'`);
|
46
51
|
}
|
47
52
|
|
48
|
-
const result = {
|
49
|
-
credential_configuration_id: credentialType,
|
50
|
-
format: credential.format,
|
51
|
-
type: "openid_credential" as const,
|
52
|
-
};
|
53
|
-
|
54
53
|
return result;
|
55
54
|
};
|
56
55
|
|
@@ -14,7 +14,7 @@ import {
|
|
14
14
|
UnexpectedStatusCodeError,
|
15
15
|
ValidationFailed,
|
16
16
|
} from "../../utils/errors";
|
17
|
-
import { CredentialResponse } from "./types";
|
17
|
+
import { CredentialResponse, NonceResponse } from "./types";
|
18
18
|
import { createDPopToken } from "../../utils/dpop";
|
19
19
|
import uuid from "react-native-uuid";
|
20
20
|
|
@@ -22,13 +22,16 @@ export type ObtainCredential = (
|
|
22
22
|
issuerConf: Out<GetIssuerConfig>["issuerConf"],
|
23
23
|
accessToken: Out<AuthorizeAccess>["accessToken"],
|
24
24
|
clientId: Out<StartUserAuthorization>["clientId"],
|
25
|
-
credentialDefinition:
|
25
|
+
credentialDefinition: {
|
26
|
+
credential_configuration_id: string;
|
27
|
+
credential_identifier?: string;
|
28
|
+
},
|
26
29
|
context: {
|
27
30
|
dPopCryptoContext: CryptoContext;
|
28
31
|
credentialCryptoContext: CryptoContext;
|
29
32
|
appFetch?: GlobalFetch["fetch"];
|
30
33
|
}
|
31
|
-
) => Promise<CredentialResponse>;
|
34
|
+
) => Promise<CredentialResponse["credentials"][number] & { format: string }>;
|
32
35
|
|
33
36
|
export const createNonceProof = async (
|
34
37
|
nonce: string,
|
@@ -82,6 +85,25 @@ export const obtainCredential: ObtainCredential = async (
|
|
82
85
|
} = context;
|
83
86
|
|
84
87
|
const credentialUrl = issuerConf.credential_endpoint;
|
88
|
+
const issuerUrl = issuerConf.issuer;
|
89
|
+
const nonceUrl = issuerConf.nonce_endpoint;
|
90
|
+
|
91
|
+
// Fetch the nonce from the Credential Issuer
|
92
|
+
const { c_nonce } = nonceUrl
|
93
|
+
? await appFetch(nonceUrl, {
|
94
|
+
method: "POST",
|
95
|
+
headers: { "Content-Type": "application/json" },
|
96
|
+
})
|
97
|
+
.then(hasStatusOrThrow(200))
|
98
|
+
.then((res) => res.json())
|
99
|
+
.then((body) => NonceResponse.parse(body))
|
100
|
+
: accessToken;
|
101
|
+
if (!c_nonce) {
|
102
|
+
throw new ValidationFailed({
|
103
|
+
message:
|
104
|
+
"Nonce Endpoint not found or access token does not contain the c_nonce",
|
105
|
+
});
|
106
|
+
}
|
85
107
|
|
86
108
|
/**
|
87
109
|
* JWT proof token to bind the request nonce to the key that will bind the holder User with the Credential
|
@@ -89,17 +111,22 @@ export const obtainCredential: ObtainCredential = async (
|
|
89
111
|
* @see https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-proof-types
|
90
112
|
*/
|
91
113
|
const signedNonceProof = await createNonceProof(
|
92
|
-
|
114
|
+
c_nonce,
|
93
115
|
clientId,
|
94
|
-
|
116
|
+
issuerUrl,
|
95
117
|
credentialCryptoContext
|
96
118
|
);
|
97
119
|
|
120
|
+
// Validation of accessTokenResponse.authorization_details if contain credentialDefinition
|
98
121
|
const containsCredentialDefinition = accessToken.authorization_details.some(
|
99
|
-
(
|
100
|
-
|
122
|
+
(c) =>
|
123
|
+
c.credential_configuration_id ===
|
101
124
|
credentialDefinition.credential_configuration_id &&
|
102
|
-
|
125
|
+
(credentialDefinition.credential_identifier
|
126
|
+
? c.credential_identifiers.includes(
|
127
|
+
credentialDefinition.credential_identifier
|
128
|
+
)
|
129
|
+
: true)
|
103
130
|
);
|
104
131
|
|
105
132
|
if (!containsCredentialDefinition) {
|
@@ -131,10 +158,7 @@ export const obtainCredential: ObtainCredential = async (
|
|
131
158
|
|
132
159
|
/** The credential request body */
|
133
160
|
const credentialRequestFormBody = {
|
134
|
-
|
135
|
-
? { doctype: credentialDefinition.credential_configuration_id }
|
136
|
-
: { vct: credentialDefinition.credential_configuration_id }),
|
137
|
-
format,
|
161
|
+
credential_identifier: credentialDefinition.credential_configuration_id,
|
138
162
|
proof: {
|
139
163
|
jwt: signedNonceProof,
|
140
164
|
proof_type: "jwt",
|
@@ -171,8 +195,11 @@ export const obtainCredential: ObtainCredential = async (
|
|
171
195
|
});
|
172
196
|
}
|
173
197
|
|
174
|
-
|
175
|
-
return
|
198
|
+
// We support only one credential for now
|
199
|
+
return {
|
200
|
+
format,
|
201
|
+
...credentialRes.data.credentials.at(0)!,
|
202
|
+
};
|
176
203
|
};
|
177
204
|
|
178
205
|
/**
|
@@ -72,7 +72,9 @@ export const parseCredentialSdJwt = (
|
|
72
72
|
ignoreMissingAttributes: boolean = false,
|
73
73
|
includeUndefinedAttributes: boolean = false
|
74
74
|
): ParsedCredential => {
|
75
|
-
const credentialSubject = credentials_supported
|
75
|
+
const credentialSubject = Object.entries(credentials_supported).find(
|
76
|
+
([, vl]) => vl.vct === sdJwt.payload.vct
|
77
|
+
)?.[1];
|
76
78
|
|
77
79
|
if (!credentialSubject) {
|
78
80
|
throw new IoWalletError("Credential type not supported by the issuer");
|
@@ -388,7 +390,9 @@ type WithFormat<Format extends Parameters<VerifyAndParseCredential>[2]> = (
|
|
388
390
|
_4: Parameters<VerifyAndParseCredential>[4]
|
389
391
|
) => ReturnType<VerifyAndParseCredential>;
|
390
392
|
|
391
|
-
const verifyAndParseCredentialSdJwt: WithFormat<
|
393
|
+
const verifyAndParseCredentialSdJwt: WithFormat<
|
394
|
+
"vc+sd-jwt" | "dc+sd-jwt"
|
395
|
+
> = async (
|
392
396
|
issuerConf,
|
393
397
|
credential,
|
394
398
|
_,
|
@@ -485,7 +489,7 @@ export const verifyAndParseCredential: VerifyAndParseCredential = async (
|
|
485
489
|
credentialType,
|
486
490
|
context
|
487
491
|
) => {
|
488
|
-
if (format === "vc+sd-jwt") {
|
492
|
+
if (format === "vc+sd-jwt" || format === "dc+sd-jwt") {
|
489
493
|
return verifyAndParseCredentialSdJwt(
|
490
494
|
issuerConf,
|
491
495
|
credential,
|
@@ -248,7 +248,7 @@ const credentialCryptoContext = createCryptoContextFor(credentialKeyTag);
|
|
248
248
|
// Start the issuance flow
|
249
249
|
const startFlow: Credential.Issuance.StartFlow = () => ({
|
250
250
|
issuerUrl: WALLET_EID_PROVIDER_BASE_URL,
|
251
|
-
credentialType: "
|
251
|
+
credentialType: "dc_sd_jwt_PersonIdentificationData",
|
252
252
|
appFetch,
|
253
253
|
});
|
254
254
|
|
@@ -1,5 +1,9 @@
|
|
1
1
|
import { type StartFlow } from "./01-start-flow";
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
getIssuerConfig,
|
4
|
+
getIssuerConfigOIDFED,
|
5
|
+
type GetIssuerConfig,
|
6
|
+
} from "./02-get-issuer-config";
|
3
7
|
import {
|
4
8
|
startUserAuthorization,
|
5
9
|
type StartUserAuthorization,
|
@@ -28,6 +32,7 @@ import * as Errors from "./errors";
|
|
28
32
|
|
29
33
|
export {
|
30
34
|
getIssuerConfig,
|
35
|
+
getIssuerConfigOIDFED,
|
31
36
|
startUserAuthorization,
|
32
37
|
buildAuthorizationUrl,
|
33
38
|
completeUserAuthorizationWithQueryMode,
|
@@ -1,14 +1,20 @@
|
|
1
|
-
import { AuthorizationDetail } from "../../utils/par";
|
2
1
|
import * as z from "zod";
|
3
|
-
|
2
|
+
|
3
|
+
export type AuthorizationDetail = z.infer<typeof AuthorizationDetail>;
|
4
|
+
export const AuthorizationDetail = z.object({
|
5
|
+
type: z.literal("openid_credential"),
|
6
|
+
credential_configuration_id: z.string(),
|
7
|
+
credential_identifiers: z.array(z.string()),
|
8
|
+
});
|
4
9
|
|
5
10
|
export type TokenResponse = z.infer<typeof TokenResponse>;
|
6
11
|
|
7
12
|
export const TokenResponse = z.object({
|
8
13
|
access_token: z.string(),
|
9
14
|
authorization_details: z.array(AuthorizationDetail),
|
10
|
-
c_nonce
|
11
|
-
|
15
|
+
// IT Wallet 1.0 remove c_nonce from token, mantain optional for compatibility with Potential
|
16
|
+
c_nonce: z.string().optional(),
|
17
|
+
c_nonce_expires_in: z.number().optional(),
|
12
18
|
expires_in: z.number(),
|
13
19
|
token_type: z.string(),
|
14
20
|
});
|
@@ -16,10 +22,12 @@ export const TokenResponse = z.object({
|
|
16
22
|
export type CredentialResponse = z.infer<typeof CredentialResponse>;
|
17
23
|
|
18
24
|
export const CredentialResponse = z.object({
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
credentials: z.array(
|
26
|
+
z.object({
|
27
|
+
credential: z.string(),
|
28
|
+
})
|
29
|
+
),
|
30
|
+
notification_id: z.string().optional(),
|
23
31
|
});
|
24
32
|
|
25
33
|
/**
|
@@ -30,3 +38,8 @@ export const ResponseUriResultShape = z.object({
|
|
30
38
|
});
|
31
39
|
|
32
40
|
export type ResponseMode = "query" | "form_post.jwt";
|
41
|
+
|
42
|
+
export type NonceResponse = z.infer<typeof NonceResponse>;
|
43
|
+
export const NonceResponse = z.object({
|
44
|
+
c_nonce: z.string(),
|
45
|
+
});
|
@@ -12,6 +12,7 @@ import { ValidationFailed } from "../../utils/errors";
|
|
12
12
|
import { CredentialNotFoundError } from "./errors";
|
13
13
|
import type { CredentialFormat, EvaluatedDisclosure } from "./types";
|
14
14
|
import { CBOR } from "@pagopa/io-react-native-cbor";
|
15
|
+
import { b64utob64 } from "jsrsasign";
|
15
16
|
|
16
17
|
/**
|
17
18
|
* The purpose for the credential request by the RP.
|
@@ -80,7 +81,7 @@ const mapCredentialsMdocToObj = async (
|
|
80
81
|
return await Promise.all(
|
81
82
|
credentialsMdoc?.map(async ([type, _, credential]) => {
|
82
83
|
const issuerSigned = credential
|
83
|
-
? await CBOR.decodeIssuerSigned(credential)
|
84
|
+
? await CBOR.decodeIssuerSigned(b64utob64(credential))
|
84
85
|
: undefined;
|
85
86
|
if (!issuerSigned) {
|
86
87
|
throw new CredentialNotFoundError(
|
@@ -151,15 +152,24 @@ export const evaluateDcqlQuery: EvaluateDcqlQuery = async (
|
|
151
152
|
required: Boolean(credentialSet.required),
|
152
153
|
}));
|
153
154
|
|
154
|
-
if (
|
155
|
+
if (
|
156
|
+
match.output.credential_format === "vc+sd-jwt" ||
|
157
|
+
match.output.credential_format === "dc+sd-jwt"
|
158
|
+
) {
|
155
159
|
const { vct, claims } = match.output;
|
156
160
|
|
157
161
|
const [, keyTag, credential] = credentialsSdJwt.find(
|
158
162
|
([type]) => type === vct
|
159
163
|
)!;
|
160
|
-
|
161
|
-
|
162
|
-
|
164
|
+
|
165
|
+
const requiredDisclosures = Object.values(claims).map((item) => {
|
166
|
+
const [_, name, value] = item as [string, string, string];
|
167
|
+
return {
|
168
|
+
name,
|
169
|
+
value,
|
170
|
+
};
|
171
|
+
}) as EvaluatedDisclosure[];
|
172
|
+
|
163
173
|
return {
|
164
174
|
id,
|
165
175
|
vct,
|
@@ -5,6 +5,7 @@ import { JSONPath } from "jsonpath-plus";
|
|
5
5
|
import { MissingDataError, CredentialNotFoundError } from "./errors";
|
6
6
|
import Ajv from "ajv";
|
7
7
|
import { CBOR } from "@pagopa/io-react-native-cbor";
|
8
|
+
import { b64utob64 } from "jsrsasign";
|
8
9
|
|
9
10
|
const ajv = new Ajv({ allErrors: true });
|
10
11
|
|
@@ -253,6 +254,12 @@ export const evaluateInputDescriptorForMdoc: EvaluateInputDescriptorMdoc = (
|
|
253
254
|
);
|
254
255
|
}
|
255
256
|
|
257
|
+
if (requiredDisclosures.length === 0 && optionalDisclosures.length === 0) {
|
258
|
+
throw new MissingDataError(
|
259
|
+
"Credential validation failed: No required fields were requested and no optional field has been requested or found."
|
260
|
+
);
|
261
|
+
}
|
262
|
+
|
256
263
|
return {
|
257
264
|
requiredDisclosures,
|
258
265
|
optionalDisclosures,
|
@@ -348,6 +355,12 @@ export const evaluateInputDescriptorForSdJwt4VC: EvaluateInputDescriptorSdJwt4VC
|
|
348
355
|
);
|
349
356
|
}
|
350
357
|
|
358
|
+
if (requiredDisclosures.length === 0 && optionalDisclosures.length === 0) {
|
359
|
+
throw new MissingDataError(
|
360
|
+
"Credential validation failed: No required fields were requested and no optional field has been requested or found."
|
361
|
+
);
|
362
|
+
}
|
363
|
+
|
351
364
|
return {
|
352
365
|
requiredDisclosures,
|
353
366
|
optionalDisclosures,
|
@@ -465,7 +478,9 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
|
|
465
478
|
const decodedMdocCredentials =
|
466
479
|
(await Promise.all(
|
467
480
|
credentialsMdoc?.map(async ([, keyTag, credential]) => {
|
468
|
-
const issuerSigned = await CBOR.decodeIssuerSigned(
|
481
|
+
const issuerSigned = await CBOR.decodeIssuerSigned(
|
482
|
+
b64utob64(credential)
|
483
|
+
);
|
469
484
|
if (!issuerSigned) {
|
470
485
|
throw new CredentialNotFoundError(
|
471
486
|
"mso_mdoc credential is not present."
|
@@ -483,7 +498,6 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
|
|
483
498
|
"mso_mdoc credential is not supported."
|
484
499
|
);
|
485
500
|
}
|
486
|
-
|
487
501
|
const { matchedEvaluation, matchedKeyTag, matchedCredential } =
|
488
502
|
findCredentialMDoc(descriptor, decodedMdocCredentials);
|
489
503
|
|
@@ -495,10 +509,13 @@ export const evaluateInputDescriptors: EvaluateInputDescriptors = async (
|
|
495
509
|
};
|
496
510
|
}
|
497
511
|
|
498
|
-
if (
|
512
|
+
if (
|
513
|
+
descriptor.format?.["vc+sd-jwt"] ||
|
514
|
+
descriptor.format?.["dc+sd-jwt"]
|
515
|
+
) {
|
499
516
|
if (!decodedSdJwtCredentials.length) {
|
500
517
|
throw new CredentialNotFoundError(
|
501
|
-
"vc+sd-jwt credential is not supported."
|
518
|
+
"vc+sd-jwt or dc+sd-jwt credential is not supported."
|
502
519
|
);
|
503
520
|
}
|
504
521
|
|
@@ -338,7 +338,7 @@ export const sendAuthorizationResponseDcql: SendAuthorizationResponseDcql =
|
|
338
338
|
* Prepares remote presentations for a set of credentials.
|
339
339
|
*
|
340
340
|
* For each credential, this function:
|
341
|
-
* - Validates the credential format (currently supports 'mso_mdoc'
|
341
|
+
* - Validates the credential format (currently supports 'mso_mdoc', 'vc+sd-jwt' or 'dc+sd-jwt').
|
342
342
|
* - Generates a verifiable presentation token (vpToken) using the appropriate method.
|
343
343
|
* - For ISO 18013-7, generates a special nonce with minimum entropy of 16.
|
344
344
|
*
|
@@ -381,7 +381,7 @@ export const prepareRemotePresentations: PrepareRemotePresentations = async (
|
|
381
381
|
};
|
382
382
|
}
|
383
383
|
|
384
|
-
if (format === "vc+sd-jwt") {
|
384
|
+
if (format === "vc+sd-jwt" || format === "dc+sd-jwt") {
|
385
385
|
const { vp_token } = await prepareVpToken(
|
386
386
|
authRequestObject.nonce,
|
387
387
|
authRequestObject.clientId,
|
@@ -396,7 +396,7 @@ export const prepareRemotePresentations: PrepareRemotePresentations = async (
|
|
396
396
|
requestedClaims: [...item.requestedClaims.map(({ name }) => name)],
|
397
397
|
credentialId: credentialInputId,
|
398
398
|
vpToken: vp_token,
|
399
|
-
format
|
399
|
+
format,
|
400
400
|
};
|
401
401
|
}
|
402
402
|
|
@@ -24,6 +24,7 @@ export const CredentialClaimDisplay = z.object({
|
|
24
24
|
|
25
25
|
export const CredentialFormat = z.union([
|
26
26
|
z.literal("vc+sd-jwt"),
|
27
|
+
z.literal("dc+sd-jwt"),
|
27
28
|
z.literal("mso_mdoc"),
|
28
29
|
]);
|
29
30
|
|
@@ -41,7 +42,7 @@ export type CredentialConfigurationSupported = z.infer<
|
|
41
42
|
>;
|
42
43
|
export const CredentialConfigurationSupported = z.record(
|
43
44
|
z.object({
|
44
|
-
cryptographic_suites_supported: z.array(z.string()),
|
45
|
+
cryptographic_suites_supported: z.array(z.string()).optional(),
|
45
46
|
vct: z.string().optional(),
|
46
47
|
scope: z.string().optional(),
|
47
48
|
cryptographic_binding_methods_supported: z.array(z.string()),
|