@openid4vc/openid4vci 0.3.0-alpha-20251001121503 → 0.3.0-alpha-20251017092354
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/dist/index.d.mts +44480 -47059
- package/dist/index.d.ts +44479 -47058
- package/dist/index.js +1819 -2450
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1778 -2451
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1,2632 +1,1959 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
Oauth2Error,
|
|
5
|
-
authorizationCodeGrantIdentifier,
|
|
6
|
-
getAuthorizationServerMetadataFromList,
|
|
7
|
-
preAuthorizedCodeGrantIdentifier as preAuthorizedCodeGrantIdentifier2
|
|
8
|
-
} from "@openid4vc/oauth2";
|
|
9
|
-
import {
|
|
10
|
-
ContentType,
|
|
11
|
-
URL,
|
|
12
|
-
URLSearchParams,
|
|
13
|
-
ValidationError,
|
|
14
|
-
createZodFetcher,
|
|
15
|
-
encodeToBase64Url,
|
|
16
|
-
getQueryParams,
|
|
17
|
-
objectToQueryParams,
|
|
18
|
-
parseWithErrorHandling
|
|
19
|
-
} from "@openid4vc/utils";
|
|
1
|
+
import { ContentType, URL, URLSearchParams, ValidationError, arrayEqualsIgnoreOrder, createZodFetcher, dateToSeconds, encodeToBase64Url, formatZodError, getGlobalConfig, getQueryParams, isResponseContentType, joinUriParts, objectToQueryParams, parseWithErrorHandling, setGlobalConfig, zHttpsUrl, zInteger, zIs } from "@openid4vc/utils";
|
|
2
|
+
import { InvalidFetchResponseError, Oauth2AuthorizationServer, Oauth2Client, Oauth2ClientAuthorizationChallengeError, Oauth2Error, Oauth2ErrorCodes, Oauth2JwtVerificationError, Oauth2ServerErrorResponseError, authorizationCodeGrantIdentifier, createClientAttestationJwt, decodeJwt, fetchAuthorizationServerMetadata, fetchWellKnownMetadata, getAuthorizationServerMetadataFromList, isJwkInSet, jwtHeaderFromJwtSigner, jwtSignerFromJwt, preAuthorizedCodeGrantIdentifier, resourceRequest, verifyJwt, zAuthorizationServerMetadata, zCompactJwt, zJwk, zJwtHeader, zJwtPayload } from "@openid4vc/oauth2";
|
|
3
|
+
import z from "zod";
|
|
20
4
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
5
|
+
//#region src/version.ts
|
|
6
|
+
let Openid4vciDraftVersion = /* @__PURE__ */ function(Openid4vciDraftVersion$1) {
|
|
7
|
+
Openid4vciDraftVersion$1["Draft16"] = "Draft16";
|
|
8
|
+
Openid4vciDraftVersion$1["Draft15"] = "Draft15";
|
|
9
|
+
Openid4vciDraftVersion$1["Draft14"] = "Draft14";
|
|
10
|
+
Openid4vciDraftVersion$1["Draft11"] = "Draft11";
|
|
11
|
+
return Openid4vciDraftVersion$1;
|
|
12
|
+
}({});
|
|
29
13
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
var zTxCode = z.object({
|
|
37
|
-
input_mode: z.union([z.literal("numeric"), z.literal("text")]).optional(),
|
|
38
|
-
length: z.number().int().optional(),
|
|
39
|
-
description: z.string().max(300).optional()
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/credential-offer/z-credential-offer.ts
|
|
16
|
+
const zTxCode = z.object({
|
|
17
|
+
input_mode: z.union([z.literal("numeric"), z.literal("text")]).optional(),
|
|
18
|
+
length: z.number().int().optional(),
|
|
19
|
+
description: z.string().max(300).optional()
|
|
40
20
|
}).passthrough();
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
21
|
+
const zCredentialOfferGrants = z.object({
|
|
22
|
+
authorization_code: z.object({
|
|
23
|
+
issuer_state: z.string().optional(),
|
|
24
|
+
authorization_server: zHttpsUrl.optional()
|
|
25
|
+
}).passthrough().optional(),
|
|
26
|
+
[preAuthorizedCodeGrantIdentifier]: z.object({
|
|
27
|
+
"pre-authorized_code": z.string(),
|
|
28
|
+
tx_code: zTxCode.optional(),
|
|
29
|
+
authorization_server: zHttpsUrl.optional()
|
|
30
|
+
}).passthrough().optional()
|
|
51
31
|
}).passthrough();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
32
|
+
const zCredentialOfferObjectDraft14 = z.object({
|
|
33
|
+
credential_issuer: zHttpsUrl,
|
|
34
|
+
credential_configuration_ids: z.array(z.string()),
|
|
35
|
+
grants: z.optional(zCredentialOfferGrants)
|
|
56
36
|
}).passthrough();
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const { user_pin_required, ...restGrants } = grants[preAuthorizedCodeGrantIdentifier];
|
|
82
|
-
v14.grants[preAuthorizedCodeGrantIdentifier] = {
|
|
83
|
-
...restGrants
|
|
84
|
-
};
|
|
85
|
-
if (user_pin_required) {
|
|
86
|
-
v14.grants[preAuthorizedCodeGrantIdentifier].tx_code = {
|
|
87
|
-
input_mode: "text"
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return v14;
|
|
37
|
+
const zCredentialOfferObjectDraft11To14 = z.object({
|
|
38
|
+
credential_issuer: zHttpsUrl,
|
|
39
|
+
credentials: z.array(z.string({ message: "Only string credential identifiers are supported for draft 11 credential offers" })),
|
|
40
|
+
grants: z.optional(z.object({
|
|
41
|
+
authorization_code: zCredentialOfferGrants.shape.authorization_code,
|
|
42
|
+
[preAuthorizedCodeGrantIdentifier]: z.object({
|
|
43
|
+
"pre-authorized_code": z.string(),
|
|
44
|
+
user_pin_required: z.optional(z.boolean())
|
|
45
|
+
}).passthrough().optional()
|
|
46
|
+
}))
|
|
47
|
+
}).passthrough().transform(({ credentials, grants,...rest }) => {
|
|
48
|
+
const v14 = {
|
|
49
|
+
...rest,
|
|
50
|
+
credential_configuration_ids: credentials
|
|
51
|
+
};
|
|
52
|
+
if (grants) {
|
|
53
|
+
v14.grants = { ...grants };
|
|
54
|
+
if (grants[preAuthorizedCodeGrantIdentifier]) {
|
|
55
|
+
const { user_pin_required,...restGrants } = grants[preAuthorizedCodeGrantIdentifier];
|
|
56
|
+
v14.grants[preAuthorizedCodeGrantIdentifier] = { ...restGrants };
|
|
57
|
+
if (user_pin_required) v14.grants[preAuthorizedCodeGrantIdentifier].tx_code = { input_mode: "text" };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return v14;
|
|
93
61
|
}).pipe(zCredentialOfferObjectDraft14);
|
|
94
|
-
|
|
95
|
-
// First prioritize draft 14 (and 13)
|
|
96
|
-
zCredentialOfferObjectDraft14,
|
|
97
|
-
// Then try parsing draft 11 and transform into draft 14
|
|
98
|
-
zCredentialOfferObjectDraft11To14
|
|
99
|
-
]);
|
|
62
|
+
const zCredentialOfferObject = z.union([zCredentialOfferObjectDraft14, zCredentialOfferObjectDraft11To14]);
|
|
100
63
|
|
|
101
|
-
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/credential-offer/credential-offer.ts
|
|
66
|
+
/**
|
|
67
|
+
* Resolve a credential offer, optionally fetching it if the credential_offer_uri is provided.
|
|
68
|
+
*/
|
|
102
69
|
async function resolveCredentialOffer(credentialOffer, options) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
} else if (parsedQueryParams.credential_offer) {
|
|
121
|
-
let credentialOfferJson;
|
|
122
|
-
try {
|
|
123
|
-
credentialOfferJson = JSON.parse(decodeURIComponent(parsedQueryParams.credential_offer));
|
|
124
|
-
} catch (error) {
|
|
125
|
-
throw new Oauth2Error(`Error parsing JSON from 'credential_offer' param in credential offer '${credentialOffer}'`);
|
|
126
|
-
}
|
|
127
|
-
credentialOfferParseResult = zCredentialOfferObject.safeParse(credentialOfferJson);
|
|
128
|
-
} else {
|
|
129
|
-
throw new Oauth2Error(`Credential offer did not contain either 'credential_offer' or 'credential_offer_uri' param.`);
|
|
130
|
-
}
|
|
131
|
-
if (credentialOfferParseResult.error) {
|
|
132
|
-
throw new ValidationError(
|
|
133
|
-
`Error parsing credential offer in draft 11, 13 or 14 format extracted from credential offer '${credentialOffer}'`,
|
|
134
|
-
credentialOfferParseResult.error
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
return credentialOfferParseResult.data;
|
|
70
|
+
const parsedQueryParams = getQueryParams(credentialOffer);
|
|
71
|
+
let credentialOfferParseResult;
|
|
72
|
+
if (parsedQueryParams.credential_offer_uri) {
|
|
73
|
+
const { response, result } = await createZodFetcher(options?.fetch)(zCredentialOfferObject, ContentType.Json, parsedQueryParams.credential_offer_uri);
|
|
74
|
+
if (!response.ok || !result) throw new InvalidFetchResponseError(`Fetching credential offer from '${parsedQueryParams.credential_offer_uri}' resulted in an unsuccessful response with status '${response.status}'`, await response.clone().text(), response);
|
|
75
|
+
credentialOfferParseResult = result;
|
|
76
|
+
} else if (parsedQueryParams.credential_offer) {
|
|
77
|
+
let credentialOfferJson;
|
|
78
|
+
try {
|
|
79
|
+
credentialOfferJson = JSON.parse(decodeURIComponent(parsedQueryParams.credential_offer));
|
|
80
|
+
} catch (_error) {
|
|
81
|
+
throw new Oauth2Error(`Error parsing JSON from 'credential_offer' param in credential offer '${credentialOffer}'`);
|
|
82
|
+
}
|
|
83
|
+
credentialOfferParseResult = zCredentialOfferObject.safeParse(credentialOfferJson);
|
|
84
|
+
} else throw new Oauth2Error(`Credential offer did not contain either 'credential_offer' or 'credential_offer_uri' param.`);
|
|
85
|
+
if (credentialOfferParseResult.error) throw new ValidationError(`Error parsing credential offer in draft 11, 13 or 14 format extracted from credential offer '${credentialOffer}'`, credentialOfferParseResult.error);
|
|
86
|
+
return credentialOfferParseResult.data;
|
|
138
87
|
}
|
|
139
88
|
function determineAuthorizationServerForCredentialOffer(options) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
} else if (!authorizationServers) {
|
|
155
|
-
authorizationServer = options.issuerMetadata.credentialIssuer.credential_issuer;
|
|
156
|
-
} else {
|
|
157
|
-
if (authorizationServers.length === 0) {
|
|
158
|
-
throw new Oauth2Error(`Credential issuer metadata has 'authorization_servers' value with length of 0`);
|
|
159
|
-
}
|
|
160
|
-
if (authorizationServers.length > 1) {
|
|
161
|
-
throw new Oauth2Error(
|
|
162
|
-
`Credential issuer metadata has 'authorization_server' with multiple entries, but the credential offer grant did not specify which authorization server to use.`
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
authorizationServer = authorizationServers[0];
|
|
166
|
-
}
|
|
167
|
-
return authorizationServer;
|
|
89
|
+
const authorizationServers = options.issuerMetadata.credentialIssuer.authorization_servers;
|
|
90
|
+
let authorizationServer;
|
|
91
|
+
if (options.grantAuthorizationServer) {
|
|
92
|
+
authorizationServer = options.grantAuthorizationServer;
|
|
93
|
+
if (!authorizationServers) throw new Oauth2Error(`Credential offer grant contains 'authorization_server' with value '${options.grantAuthorizationServer}' but credential issuer metadata does not have an 'authorization_servers' property to match the value against.`);
|
|
94
|
+
if (!authorizationServers.includes(authorizationServer)) throw new Oauth2Error(`Credential offer grant contains 'authorization_server' with value '${options.grantAuthorizationServer}' but credential issuer metadata does not include this authorization server. Available 'authorization_server' values are ${authorizationServers.join(", ")}.`);
|
|
95
|
+
} else if (!authorizationServers) authorizationServer = options.issuerMetadata.credentialIssuer.credential_issuer;
|
|
96
|
+
else {
|
|
97
|
+
if (authorizationServers.length === 0) throw new Oauth2Error(`Credential issuer metadata has 'authorization_servers' value with length of 0`);
|
|
98
|
+
if (authorizationServers.length > 1) throw new Oauth2Error(`Credential issuer metadata has 'authorization_server' with multiple entries, but the credential offer grant did not specify which authorization server to use.`);
|
|
99
|
+
authorizationServer = authorizationServers[0];
|
|
100
|
+
}
|
|
101
|
+
return authorizationServer;
|
|
168
102
|
}
|
|
169
103
|
async function createCredentialOffer(options) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
...options.additionalPayload
|
|
211
|
-
});
|
|
212
|
-
if (options.issuerMetadata.originalDraftVersion === "Draft11" /* Draft11 */) {
|
|
213
|
-
credentialOfferObject.credentials = credentialOfferObject.credential_configuration_ids;
|
|
214
|
-
}
|
|
215
|
-
const url = new URL(credentialOfferScheme);
|
|
216
|
-
url.search = `?${new URLSearchParams([
|
|
217
|
-
...url.searchParams.entries(),
|
|
218
|
-
...objectToQueryParams({
|
|
219
|
-
credential_offer_uri: options.credentialOfferUri,
|
|
220
|
-
// Only add credential_offer is uri is undefined
|
|
221
|
-
credential_offer: options.credentialOfferUri ? void 0 : credentialOfferObject
|
|
222
|
-
}).entries()
|
|
223
|
-
]).toString()}`;
|
|
224
|
-
return {
|
|
225
|
-
credentialOffer: url.toString(),
|
|
226
|
-
credentialOfferObject
|
|
227
|
-
};
|
|
104
|
+
const { [preAuthorizedCodeGrantIdentifier]: preAuthorizedCodeGrant, [authorizationCodeGrantIdentifier]: authorizationCodeGrant,...restGrants } = options.grants;
|
|
105
|
+
const grants = { ...restGrants };
|
|
106
|
+
if (authorizationCodeGrant) {
|
|
107
|
+
determineAuthorizationServerForCredentialOffer({
|
|
108
|
+
issuerMetadata: options.issuerMetadata,
|
|
109
|
+
grantAuthorizationServer: authorizationCodeGrant.authorization_server
|
|
110
|
+
});
|
|
111
|
+
grants[authorizationCodeGrantIdentifier] = authorizationCodeGrant;
|
|
112
|
+
}
|
|
113
|
+
if (preAuthorizedCodeGrant) {
|
|
114
|
+
determineAuthorizationServerForCredentialOffer({
|
|
115
|
+
issuerMetadata: options.issuerMetadata,
|
|
116
|
+
grantAuthorizationServer: preAuthorizedCodeGrant.authorization_server
|
|
117
|
+
});
|
|
118
|
+
grants[preAuthorizedCodeGrantIdentifier] = {
|
|
119
|
+
...preAuthorizedCodeGrant,
|
|
120
|
+
"pre-authorized_code": preAuthorizedCodeGrant["pre-authorized_code"] ?? encodeToBase64Url(await options.callbacks.generateRandom(32))
|
|
121
|
+
};
|
|
122
|
+
const txCode = grants[preAuthorizedCodeGrantIdentifier].tx_code;
|
|
123
|
+
if (txCode && options.issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft11) grants[preAuthorizedCodeGrantIdentifier].user_pin_required = txCode !== void 0;
|
|
124
|
+
}
|
|
125
|
+
const idsNotInMetadata = options.credentialConfigurationIds.filter((id) => options.issuerMetadata.credentialIssuer.credential_configurations_supported[id] === void 0);
|
|
126
|
+
if (idsNotInMetadata.length > 0) throw new Oauth2Error(`Credential configuration ids ${idsNotInMetadata} not found in the credential issuer metadata 'credential_configurations_supported'. Available ids are ${Object.keys(options.issuerMetadata.credentialIssuer.credential_configurations_supported).join(", ")}.`);
|
|
127
|
+
const credentialOfferScheme = options.credentialOfferScheme ?? "openid-credential-offer://";
|
|
128
|
+
const credentialOfferObject = parseWithErrorHandling(zCredentialOfferObject, {
|
|
129
|
+
credential_issuer: options.issuerMetadata.credentialIssuer.credential_issuer,
|
|
130
|
+
credential_configuration_ids: options.credentialConfigurationIds,
|
|
131
|
+
grants,
|
|
132
|
+
...options.additionalPayload
|
|
133
|
+
});
|
|
134
|
+
if (options.issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft11) credentialOfferObject.credentials = credentialOfferObject.credential_configuration_ids;
|
|
135
|
+
const url = new URL(credentialOfferScheme);
|
|
136
|
+
url.search = `?${new URLSearchParams([...url.searchParams.entries(), ...objectToQueryParams({
|
|
137
|
+
credential_offer_uri: options.credentialOfferUri,
|
|
138
|
+
credential_offer: options.credentialOfferUri ? void 0 : credentialOfferObject
|
|
139
|
+
}).entries()]).toString()}`;
|
|
140
|
+
return {
|
|
141
|
+
credentialOffer: url.toString(),
|
|
142
|
+
credentialOfferObject
|
|
143
|
+
};
|
|
228
144
|
}
|
|
229
145
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
// src/metadata/credential-issuer/z-credential-issuer-metadata.ts
|
|
241
|
-
import { zCompactJwt } from "@openid4vc/oauth2";
|
|
242
|
-
import { zHttpsUrl as zHttpsUrl2 } from "@openid4vc/utils";
|
|
243
|
-
import z13 from "zod";
|
|
244
|
-
|
|
245
|
-
// src/formats/credential/mso-mdoc/z-mso-mdoc.ts
|
|
246
|
-
import z5 from "zod";
|
|
247
|
-
|
|
248
|
-
// src/metadata/credential-issuer/z-claims-description.ts
|
|
249
|
-
import z2 from "zod";
|
|
250
|
-
var zCredentialConfigurationSupportedClaimsDescriptionDraft14 = z2.object({
|
|
251
|
-
mandatory: z2.boolean().optional(),
|
|
252
|
-
value_type: z2.string().optional(),
|
|
253
|
-
display: z2.array(
|
|
254
|
-
z2.object({
|
|
255
|
-
name: z2.string().optional(),
|
|
256
|
-
locale: z2.string().optional()
|
|
257
|
-
}).passthrough()
|
|
258
|
-
).optional()
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/metadata/credential-issuer/z-claims-description.ts
|
|
148
|
+
const zCredentialConfigurationSupportedClaimsDescriptionDraft14 = z.object({
|
|
149
|
+
mandatory: z.boolean().optional(),
|
|
150
|
+
value_type: z.string().optional(),
|
|
151
|
+
display: z.array(z.object({
|
|
152
|
+
name: z.string().optional(),
|
|
153
|
+
locale: z.string().optional()
|
|
154
|
+
}).passthrough()).optional()
|
|
259
155
|
}).passthrough();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
display: z2.array(
|
|
275
|
-
z2.object({
|
|
276
|
-
name: z2.string().optional(),
|
|
277
|
-
locale: z2.string().optional()
|
|
278
|
-
}).passthrough()
|
|
279
|
-
).optional()
|
|
156
|
+
const zCredentialConfigurationSupportedClaimsDraft14 = z.record(z.string(), z.union([zCredentialConfigurationSupportedClaimsDescriptionDraft14, z.lazy(() => zCredentialConfigurationSupportedClaimsDraft14)]));
|
|
157
|
+
const zClaimsDescriptionPath = z.array(z.union([
|
|
158
|
+
z.string(),
|
|
159
|
+
z.number().int().nonnegative(),
|
|
160
|
+
z.null()
|
|
161
|
+
])).nonempty();
|
|
162
|
+
const zMsoMdocClaimsDescriptionPath = z.tuple([z.string(), z.string()], { message: "mso_mdoc claims description path MUST be an array with exactly two string elements, pointing to the namespace and element identifier within an mdoc credential" });
|
|
163
|
+
const zIssuerMetadataClaimsDescription = z.object({
|
|
164
|
+
path: zClaimsDescriptionPath,
|
|
165
|
+
mandatory: z.boolean().optional(),
|
|
166
|
+
display: z.array(z.object({
|
|
167
|
+
name: z.string().optional(),
|
|
168
|
+
locale: z.string().optional()
|
|
169
|
+
}).passthrough()).optional()
|
|
280
170
|
}).passthrough();
|
|
281
|
-
|
|
282
|
-
path: zMsoMdocClaimsDescriptionPath
|
|
283
|
-
});
|
|
171
|
+
const zMsoMdocIssuerMetadataClaimsDescription = zIssuerMetadataClaimsDescription.extend({ path: zMsoMdocClaimsDescriptionPath });
|
|
284
172
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
var zKeyAttestationJwtPayload = z3.object({
|
|
306
|
-
...zJwtPayload.shape,
|
|
307
|
-
iat: zInteger,
|
|
308
|
-
attested_keys: z3.array(zJwk),
|
|
309
|
-
key_storage: z3.optional(zIso18045OrStringArray),
|
|
310
|
-
user_authentication: z3.optional(zIso18045OrStringArray),
|
|
311
|
-
certification: z3.optional(z3.string().url())
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/key-attestation/z-key-attestation.ts
|
|
175
|
+
const zKeyAttestationJwtHeader = z.object({
|
|
176
|
+
...zJwtHeader.shape,
|
|
177
|
+
typ: z.literal("keyattestation+jwt").or(z.literal("key-attestation+jwt"))
|
|
178
|
+
}).passthrough().refine(({ kid, jwk }) => jwk === void 0 || kid === void 0, { message: `Both 'jwk' and 'kid' are defined. Only one is allowed` }).refine(({ trust_chain, kid }) => !trust_chain || !kid, { message: `When 'trust_chain' is provided, 'kid' is required` });
|
|
179
|
+
const zIso18045 = z.enum([
|
|
180
|
+
"iso_18045_high",
|
|
181
|
+
"iso_18045_moderate",
|
|
182
|
+
"iso_18045_enhanced-basic",
|
|
183
|
+
"iso_18045_basic"
|
|
184
|
+
]);
|
|
185
|
+
const zIso18045OrStringArray = z.array(z.union([zIso18045, z.string()]));
|
|
186
|
+
const zKeyAttestationJwtPayload = z.object({
|
|
187
|
+
...zJwtPayload.shape,
|
|
188
|
+
iat: zInteger,
|
|
189
|
+
attested_keys: z.array(zJwk),
|
|
190
|
+
key_storage: z.optional(zIso18045OrStringArray),
|
|
191
|
+
user_authentication: z.optional(zIso18045OrStringArray),
|
|
192
|
+
certification: z.optional(z.string().url())
|
|
312
193
|
}).passthrough();
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
message: `Nonce must be defined when key attestation is used as 'proof_type.attestation' directly`
|
|
318
|
-
}) : z3.optional(z3.string()),
|
|
319
|
-
// REQUIRED when used within header of proof_type.jwt
|
|
320
|
-
exp: use === "proof_type.jwt" ? zInteger : z3.optional(zInteger)
|
|
194
|
+
const zKeyAttestationJwtPayloadForUse = (use) => z.object({
|
|
195
|
+
...zKeyAttestationJwtPayload.shape,
|
|
196
|
+
nonce: use === "proof_type.attestation" ? z.string({ message: `Nonce must be defined when key attestation is used as 'proof_type.attestation' directly` }) : z.optional(z.string()),
|
|
197
|
+
exp: use === "proof_type.jwt" ? zInteger : z.optional(zInteger)
|
|
321
198
|
}).passthrough();
|
|
322
199
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
uri: z4.string().optional()
|
|
337
|
-
}).passthrough().optional(),
|
|
338
|
-
text_color: z4.string().optional()
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/metadata/credential-issuer/z-credential-configuration-supported-common.ts
|
|
202
|
+
const zCredentialConfigurationSupportedDisplayEntry = z.object({
|
|
203
|
+
name: z.string(),
|
|
204
|
+
locale: z.string().optional(),
|
|
205
|
+
logo: z.object({
|
|
206
|
+
uri: z.string().optional(),
|
|
207
|
+
alt_text: z.string().optional()
|
|
208
|
+
}).passthrough().optional(),
|
|
209
|
+
description: z.string().optional(),
|
|
210
|
+
background_color: z.string().optional(),
|
|
211
|
+
background_image: z.object({ uri: z.string().optional() }).passthrough().optional(),
|
|
212
|
+
text_color: z.string().optional()
|
|
339
213
|
}).passthrough();
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
// For typing purposes. Can be removed once we drop support for draft <= 15.
|
|
360
|
-
claims: z4.optional(z4.never())
|
|
214
|
+
const zCredentialConfigurationSupportedCommonCredentialMetadata = z.object({ display: z.array(zCredentialConfigurationSupportedDisplayEntry).optional() });
|
|
215
|
+
const zCredentialConfigurationSupportedCommon = z.object({
|
|
216
|
+
format: z.string(),
|
|
217
|
+
scope: z.string().optional(),
|
|
218
|
+
cryptographic_binding_methods_supported: z.array(z.string()).optional(),
|
|
219
|
+
credential_signing_alg_values_supported: z.array(z.string()).or(z.array(z.number())).optional(),
|
|
220
|
+
proof_types_supported: z.record(z.union([
|
|
221
|
+
z.literal("jwt"),
|
|
222
|
+
z.literal("attestation"),
|
|
223
|
+
z.string()
|
|
224
|
+
]), z.object({
|
|
225
|
+
proof_signing_alg_values_supported: z.array(z.string()),
|
|
226
|
+
key_attestations_required: z.object({
|
|
227
|
+
key_storage: zIso18045OrStringArray.optional(),
|
|
228
|
+
user_authentication: zIso18045OrStringArray.optional()
|
|
229
|
+
}).passthrough().optional()
|
|
230
|
+
})).optional(),
|
|
231
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.optional(),
|
|
232
|
+
claims: z.optional(z.never())
|
|
361
233
|
}).passthrough();
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
234
|
+
const zCredentialConfigurationSupportedCommonDraft15 = z.object({
|
|
235
|
+
format: z.string(),
|
|
236
|
+
scope: z.string().optional(),
|
|
237
|
+
cryptographic_binding_methods_supported: z.array(z.string()).optional(),
|
|
238
|
+
credential_signing_alg_values_supported: z.array(z.string()).or(z.array(z.number())).optional(),
|
|
239
|
+
proof_types_supported: z.record(z.union([
|
|
240
|
+
z.literal("jwt"),
|
|
241
|
+
z.literal("attestation"),
|
|
242
|
+
z.string()
|
|
243
|
+
]), z.object({
|
|
244
|
+
proof_signing_alg_values_supported: z.array(z.string()),
|
|
245
|
+
key_attestations_required: z.object({
|
|
246
|
+
key_storage: zIso18045OrStringArray.optional(),
|
|
247
|
+
user_authentication: zIso18045OrStringArray.optional()
|
|
248
|
+
}).passthrough().optional()
|
|
249
|
+
})).optional(),
|
|
250
|
+
display: z.array(zCredentialConfigurationSupportedDisplayEntry).optional(),
|
|
251
|
+
credential_metadata: z.optional(z.never())
|
|
380
252
|
}).passthrough();
|
|
381
253
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}).optional()
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/formats/credential/mso-mdoc/z-mso-mdoc.ts
|
|
256
|
+
const zMsoMdocFormatIdentifier = z.literal("mso_mdoc");
|
|
257
|
+
const zMsoMdocCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
258
|
+
format: zMsoMdocFormatIdentifier,
|
|
259
|
+
doctype: z.string(),
|
|
260
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zMsoMdocIssuerMetadataClaimsDescription).optional() }).optional()
|
|
390
261
|
});
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
262
|
+
const zMsoMdocCredentialIssuerMetadataDraft15 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
263
|
+
format: zMsoMdocFormatIdentifier,
|
|
264
|
+
doctype: z.string(),
|
|
265
|
+
claims: z.array(zMsoMdocIssuerMetadataClaimsDescription).optional()
|
|
395
266
|
});
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
267
|
+
const zMsoMdocCredentialIssuerMetadataDraft14 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
268
|
+
format: zMsoMdocFormatIdentifier,
|
|
269
|
+
doctype: z.string(),
|
|
270
|
+
claims: zCredentialConfigurationSupportedClaimsDraft14.optional(),
|
|
271
|
+
order: z.optional(z.array(z.string()))
|
|
401
272
|
});
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
claims: zCredentialConfigurationSupportedClaimsDraft14.optional()
|
|
273
|
+
const zMsoMdocCredentialRequestFormatDraft14 = z.object({
|
|
274
|
+
format: zMsoMdocFormatIdentifier,
|
|
275
|
+
doctype: z.string(),
|
|
276
|
+
claims: zCredentialConfigurationSupportedClaimsDraft14.optional()
|
|
407
277
|
});
|
|
408
278
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({
|
|
417
|
-
claims: z6.array(zIssuerMetadataClaimsDescription).optional()
|
|
418
|
-
}).optional(),
|
|
419
|
-
credential_definition: z6.optional(z6.never())
|
|
420
|
-
});
|
|
421
|
-
var zLegacySdJwtVcCredentialIssuerMetadataDraft14 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
422
|
-
vct: z6.string(),
|
|
423
|
-
format: zLegacySdJwtVcFormatIdentifier,
|
|
424
|
-
claims: z6.optional(zCredentialConfigurationSupportedClaimsDraft14),
|
|
425
|
-
order: z6.optional(z6.array(z6.string())),
|
|
426
|
-
credential_definition: z6.optional(z6.never())
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/formats/credential/sd-jwt-dc/z-sd-jwt-dc.ts
|
|
281
|
+
const zSdJwtDcFormatIdentifier = z.literal("dc+sd-jwt");
|
|
282
|
+
const zSdJwtDcCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
283
|
+
vct: z.string(),
|
|
284
|
+
format: zSdJwtDcFormatIdentifier,
|
|
285
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zIssuerMetadataClaimsDescription).optional() }).optional()
|
|
427
286
|
});
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
credential_definition: z6.optional(z6.never())
|
|
287
|
+
const zSdJwtDcCredentialIssuerMetadataDraft15 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
288
|
+
vct: z.string(),
|
|
289
|
+
format: zSdJwtDcFormatIdentifier,
|
|
290
|
+
claims: z.array(zIssuerMetadataClaimsDescription).optional()
|
|
433
291
|
});
|
|
434
292
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region src/formats/credential/sd-jwt-vc/z-sd-jwt-vc.ts
|
|
295
|
+
/**
|
|
296
|
+
* @deprecated format has been deprecated in favor of "dc+sd-jwt" since Draft 23
|
|
297
|
+
* of the OpenID for Verifiable Presentations specification. Please update your
|
|
298
|
+
* implementations accordingly.
|
|
299
|
+
*/
|
|
300
|
+
const zLegacySdJwtVcFormatIdentifier = z.literal("vc+sd-jwt");
|
|
301
|
+
/**
|
|
302
|
+
* @deprecated format has been deprecated in favor of "dc+sd-jwt" since Draft 23
|
|
303
|
+
* of the OpenID for Verifiable Presentations specification. Please update your
|
|
304
|
+
* implementations accordingly.
|
|
305
|
+
*/
|
|
306
|
+
const zLegacySdJwtVcCredentialIssuerMetadataDraft16 = zCredentialConfigurationSupportedCommon.extend({
|
|
307
|
+
vct: z.string(),
|
|
308
|
+
format: zLegacySdJwtVcFormatIdentifier,
|
|
309
|
+
order: z.optional(z.array(z.string())),
|
|
310
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zIssuerMetadataClaimsDescription).optional() }).optional(),
|
|
311
|
+
credential_definition: z.optional(z.never())
|
|
444
312
|
});
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
313
|
+
/**
|
|
314
|
+
* @deprecated format has been deprecated in favor of "dc+sd-jwt" since Draft 23
|
|
315
|
+
* of the OpenID for Verifiable Presentations specification. Please update your
|
|
316
|
+
* implementations accordingly.
|
|
317
|
+
*/
|
|
318
|
+
const zLegacySdJwtVcCredentialIssuerMetadataDraft14 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
319
|
+
vct: z.string(),
|
|
320
|
+
format: zLegacySdJwtVcFormatIdentifier,
|
|
321
|
+
claims: z.optional(zCredentialConfigurationSupportedClaimsDraft14),
|
|
322
|
+
order: z.optional(z.array(z.string())),
|
|
323
|
+
credential_definition: z.optional(z.never())
|
|
324
|
+
});
|
|
325
|
+
/**
|
|
326
|
+
* @deprecated format has been deprecated in favor of "dc+sd-jwt" since Draft 23
|
|
327
|
+
* of the OpenID for Verifiable Presentations specification. Please update your
|
|
328
|
+
* implementations accordingly.
|
|
329
|
+
*/
|
|
330
|
+
const zLegacySdJwtVcCredentialRequestFormatDraft14 = z.object({
|
|
331
|
+
format: zLegacySdJwtVcFormatIdentifier,
|
|
332
|
+
vct: z.string(),
|
|
333
|
+
claims: z.optional(zCredentialConfigurationSupportedClaimsDraft14),
|
|
334
|
+
credential_definition: z.optional(z.never())
|
|
449
335
|
});
|
|
450
336
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
z8.object({
|
|
461
|
-
name: z8.string().optional(),
|
|
462
|
-
locale: z8.string().optional()
|
|
463
|
-
}).passthrough()
|
|
464
|
-
).optional()
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/formats/credential/w3c-vc/z-w3c-vc-common.ts
|
|
339
|
+
const zCredentialSubjectLeafTypeDraft14 = z.object({
|
|
340
|
+
mandatory: z.boolean().optional(),
|
|
341
|
+
value_type: z.string().optional(),
|
|
342
|
+
display: z.array(z.object({
|
|
343
|
+
name: z.string().optional(),
|
|
344
|
+
locale: z.string().optional()
|
|
345
|
+
}).passthrough()).optional()
|
|
465
346
|
}).passthrough();
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
347
|
+
const zClaimValueSchemaDraft14 = z.union([
|
|
348
|
+
z.array(z.any()),
|
|
349
|
+
z.record(z.string(), z.any()),
|
|
350
|
+
zCredentialSubjectLeafTypeDraft14
|
|
470
351
|
]);
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
352
|
+
const zW3cVcCredentialSubjectDraft14 = z.record(z.string(), zClaimValueSchemaDraft14);
|
|
353
|
+
const zW3cVcJsonLdCredentialDefinition = z.object({
|
|
354
|
+
"@context": z.array(z.string()),
|
|
355
|
+
type: z.array(z.string()).nonempty()
|
|
475
356
|
}).passthrough();
|
|
476
|
-
|
|
477
|
-
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
478
|
-
});
|
|
357
|
+
const zW3cVcJsonLdCredentialDefinitionDraft14 = zW3cVcJsonLdCredentialDefinition.extend({ credentialSubject: zW3cVcCredentialSubjectDraft14.optional() });
|
|
479
358
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region src/formats/credential/w3c-vc/z-w3c-jwt-vc-json.ts
|
|
361
|
+
const zJwtVcJsonFormatIdentifier = z.literal("jwt_vc_json");
|
|
362
|
+
const zJwtVcJsonCredentialDefinition = z.object({ type: z.array(z.string()).nonempty() }).passthrough();
|
|
363
|
+
const zJwtVcJsonCredentialDefinitionDraft14 = zJwtVcJsonCredentialDefinition.extend({ credentialSubject: zW3cVcCredentialSubjectDraft14.optional() });
|
|
364
|
+
const zJwtVcJsonCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
365
|
+
format: zJwtVcJsonFormatIdentifier,
|
|
366
|
+
credential_definition: zJwtVcJsonCredentialDefinition,
|
|
367
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zIssuerMetadataClaimsDescription).optional() }).optional()
|
|
488
368
|
});
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
369
|
+
const zJwtVcJsonCredentialIssuerMetadataDraft15 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
370
|
+
format: zJwtVcJsonFormatIdentifier,
|
|
371
|
+
credential_definition: zJwtVcJsonCredentialDefinition,
|
|
372
|
+
claims: z.array(zIssuerMetadataClaimsDescription).optional()
|
|
493
373
|
});
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
374
|
+
const zJwtVcJsonCredentialIssuerMetadataDraft14 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
375
|
+
format: zJwtVcJsonFormatIdentifier,
|
|
376
|
+
credential_definition: zJwtVcJsonCredentialDefinitionDraft14,
|
|
377
|
+
order: z.array(z.string()).optional()
|
|
498
378
|
});
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
"@context": z9.array(z9.string()),
|
|
505
|
-
types: z9.array(z9.string()),
|
|
506
|
-
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
379
|
+
const zJwtVcJsonCredentialIssuerMetadataDraft11 = z.object({
|
|
380
|
+
format: zJwtVcJsonFormatIdentifier,
|
|
381
|
+
order: z.array(z.string()).optional(),
|
|
382
|
+
types: z.array(z.string()),
|
|
383
|
+
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
507
384
|
}).passthrough();
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
})).pipe(zLdpVcCredentialIssuerMetadataDraft11);
|
|
524
|
-
var zLdpVcCredentialRequestFormatDraft14 = z9.object({
|
|
525
|
-
format: zLdpVcFormatIdentifier,
|
|
526
|
-
credential_definition: zW3cVcJsonLdCredentialDefinitionDraft14
|
|
385
|
+
const zJwtVcJsonCredentialIssuerMetadataDraft11To14 = zJwtVcJsonCredentialIssuerMetadataDraft11.transform(({ types, credentialSubject,...rest }) => ({
|
|
386
|
+
...rest,
|
|
387
|
+
credential_definition: {
|
|
388
|
+
type: types,
|
|
389
|
+
...credentialSubject ? { credentialSubject } : {}
|
|
390
|
+
}
|
|
391
|
+
}));
|
|
392
|
+
const zJwtVcJsonCredentialIssuerMetadataDraft14To11 = zJwtVcJsonCredentialIssuerMetadataDraft14.passthrough().transform(({ credential_definition: { type,...credentialDefinition },...rest }) => ({
|
|
393
|
+
...rest,
|
|
394
|
+
types: type,
|
|
395
|
+
...credentialDefinition
|
|
396
|
+
})).pipe(zJwtVcJsonCredentialIssuerMetadataDraft11);
|
|
397
|
+
const zJwtVcJsonCredentialRequestFormatDraft14 = z.object({
|
|
398
|
+
format: zJwtVcJsonFormatIdentifier,
|
|
399
|
+
credential_definition: zJwtVcJsonCredentialDefinition
|
|
527
400
|
});
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
// credential_definition was using types instead of type in v11
|
|
533
|
-
types: z9.array(z9.string()),
|
|
534
|
-
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
535
|
-
})
|
|
401
|
+
const zJwtVcJsonCredentialRequestDraft11 = z.object({
|
|
402
|
+
format: zJwtVcJsonFormatIdentifier,
|
|
403
|
+
types: z.array(z.string()),
|
|
404
|
+
credentialSubject: z.optional(zW3cVcCredentialSubjectDraft14)
|
|
536
405
|
}).passthrough();
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
);
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
})).pipe(zLdpVcCredentialRequestDraft11);
|
|
406
|
+
const zJwtVcJsonCredentialRequestDraft11To14 = zJwtVcJsonCredentialRequestDraft11.transform(({ types, credentialSubject,...rest }) => {
|
|
407
|
+
return {
|
|
408
|
+
...rest,
|
|
409
|
+
credential_definition: {
|
|
410
|
+
type: types,
|
|
411
|
+
...credentialSubject ? { credentialSubject } : {}
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
});
|
|
415
|
+
const zJwtVcJsonCredentialRequestDraft14To11 = zJwtVcJsonCredentialRequestFormatDraft14.passthrough().transform(({ credential_definition: { type,...credentialDefinition },...rest }) => ({
|
|
416
|
+
...rest,
|
|
417
|
+
types: type,
|
|
418
|
+
...credentialDefinition
|
|
419
|
+
})).pipe(zJwtVcJsonCredentialRequestDraft11);
|
|
553
420
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
claims: z10.array(zIssuerMetadataClaimsDescription).optional()
|
|
562
|
-
}).optional()
|
|
421
|
+
//#endregion
|
|
422
|
+
//#region src/formats/credential/w3c-vc/z-w3c-jwt-vc-json-ld.ts
|
|
423
|
+
const zJwtVcJsonLdFormatIdentifier = z.literal("jwt_vc_json-ld");
|
|
424
|
+
const zJwtVcJsonLdCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
425
|
+
format: zJwtVcJsonLdFormatIdentifier,
|
|
426
|
+
credential_definition: zW3cVcJsonLdCredentialDefinition,
|
|
427
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zIssuerMetadataClaimsDescription).optional() }).optional()
|
|
563
428
|
});
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
429
|
+
const zJwtVcJsonLdCredentialIssuerMetadataDraft15 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
430
|
+
format: zJwtVcJsonLdFormatIdentifier,
|
|
431
|
+
credential_definition: zW3cVcJsonLdCredentialDefinition,
|
|
432
|
+
claims: z.array(zIssuerMetadataClaimsDescription).optional()
|
|
568
433
|
});
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
434
|
+
const zJwtVcJsonLdCredentialIssuerMetadataDraft14 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
435
|
+
format: zJwtVcJsonLdFormatIdentifier,
|
|
436
|
+
credential_definition: zW3cVcJsonLdCredentialDefinitionDraft14,
|
|
437
|
+
order: z.optional(z.array(z.string()))
|
|
573
438
|
});
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
types: z10.array(z10.string()),
|
|
581
|
-
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
439
|
+
const zJwtVcJsonLdCredentialIssuerMetadataDraft11 = z.object({
|
|
440
|
+
order: z.array(z.string()).optional(),
|
|
441
|
+
format: zJwtVcJsonLdFormatIdentifier,
|
|
442
|
+
"@context": z.array(z.string()),
|
|
443
|
+
types: z.array(z.string()),
|
|
444
|
+
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
582
445
|
}).passthrough();
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
...rest,
|
|
596
|
-
...credentialDefinition,
|
|
597
|
-
types: type
|
|
446
|
+
const zJwtVcJsonLdCredentialIssuerMetadataDraft11To14 = zJwtVcJsonLdCredentialIssuerMetadataDraft11.transform(({ "@context": context, types, credentialSubject,...rest }) => ({
|
|
447
|
+
...rest,
|
|
448
|
+
credential_definition: {
|
|
449
|
+
"@context": context,
|
|
450
|
+
type: types,
|
|
451
|
+
...credentialSubject ? { credentialSubject } : {}
|
|
452
|
+
}
|
|
453
|
+
}));
|
|
454
|
+
const zJwtVcJsonLdCredentialIssuerMetadataDraft14To11 = zJwtVcJsonLdCredentialIssuerMetadataDraft14.passthrough().transform(({ credential_definition: { type,...credentialDefinition },...rest }) => ({
|
|
455
|
+
...rest,
|
|
456
|
+
...credentialDefinition,
|
|
457
|
+
types: type
|
|
598
458
|
})).pipe(zJwtVcJsonLdCredentialIssuerMetadataDraft11);
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
459
|
+
const zJwtVcJsonLdCredentialRequestFormatDraft14 = z.object({
|
|
460
|
+
format: zJwtVcJsonLdFormatIdentifier,
|
|
461
|
+
credential_definition: zW3cVcJsonLdCredentialDefinition
|
|
602
462
|
});
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}).passthrough()
|
|
463
|
+
const zJwtVcJsonLdCredentialRequestDraft11 = z.object({
|
|
464
|
+
format: zJwtVcJsonLdFormatIdentifier,
|
|
465
|
+
credential_definition: z.object({
|
|
466
|
+
"@context": z.array(z.string()),
|
|
467
|
+
types: z.array(z.string()),
|
|
468
|
+
credentialSubject: z.optional(zW3cVcCredentialSubjectDraft14)
|
|
469
|
+
}).passthrough()
|
|
611
470
|
}).passthrough();
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
types: type
|
|
626
|
-
}
|
|
471
|
+
const zJwtVcJsonLdCredentialRequestDraft11To14 = zJwtVcJsonLdCredentialRequestDraft11.transform(({ credential_definition: { types,...restCredentialDefinition },...rest }) => ({
|
|
472
|
+
...rest,
|
|
473
|
+
credential_definition: {
|
|
474
|
+
...restCredentialDefinition,
|
|
475
|
+
type: types
|
|
476
|
+
}
|
|
477
|
+
}));
|
|
478
|
+
const zJwtVcJsonLdCredentialRequestDraft14To11 = zJwtVcJsonLdCredentialRequestFormatDraft14.passthrough().transform(({ credential_definition: { type,...restCredentialDefinition },...rest }) => ({
|
|
479
|
+
...rest,
|
|
480
|
+
credential_definition: {
|
|
481
|
+
...restCredentialDefinition,
|
|
482
|
+
types: type
|
|
483
|
+
}
|
|
627
484
|
})).pipe(zJwtVcJsonLdCredentialRequestDraft11);
|
|
628
485
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
637
|
-
});
|
|
638
|
-
var zJwtVcJsonCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
639
|
-
format: zJwtVcJsonFormatIdentifier,
|
|
640
|
-
credential_definition: zJwtVcJsonCredentialDefinition,
|
|
641
|
-
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({
|
|
642
|
-
claims: z11.array(zIssuerMetadataClaimsDescription).optional()
|
|
643
|
-
}).optional()
|
|
486
|
+
//#endregion
|
|
487
|
+
//#region src/formats/credential/w3c-vc/z-w3c-ldp-vc.ts
|
|
488
|
+
const zLdpVcFormatIdentifier = z.literal("ldp_vc");
|
|
489
|
+
const zLdpVcCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
490
|
+
format: zLdpVcFormatIdentifier,
|
|
491
|
+
credential_definition: zW3cVcJsonLdCredentialDefinition,
|
|
492
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zIssuerMetadataClaimsDescription).optional() }).optional()
|
|
644
493
|
});
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
494
|
+
const zLdpVcCredentialIssuerMetadataDraft15 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
495
|
+
format: zLdpVcFormatIdentifier,
|
|
496
|
+
credential_definition: zW3cVcJsonLdCredentialDefinition,
|
|
497
|
+
claims: z.array(zIssuerMetadataClaimsDescription).optional()
|
|
649
498
|
});
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
499
|
+
const zLdpVcCredentialIssuerMetadataDraft14 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
500
|
+
format: zLdpVcFormatIdentifier,
|
|
501
|
+
credential_definition: zW3cVcJsonLdCredentialDefinitionDraft14,
|
|
502
|
+
order: z.array(z.string()).optional()
|
|
654
503
|
});
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
504
|
+
const zLdpVcCredentialIssuerMetadataDraft11 = z.object({
|
|
505
|
+
order: z.array(z.string()).optional(),
|
|
506
|
+
format: zLdpVcFormatIdentifier,
|
|
507
|
+
"@context": z.array(z.string()),
|
|
508
|
+
types: z.array(z.string()),
|
|
509
|
+
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
662
510
|
}).passthrough();
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
format: zJwtVcJsonFormatIdentifier,
|
|
680
|
-
credential_definition: zJwtVcJsonCredentialDefinition
|
|
511
|
+
const zLdpVcCredentialIssuerMetadataDraft11To14 = zLdpVcCredentialIssuerMetadataDraft11.transform(({ "@context": context, types, credentialSubject,...rest }) => ({
|
|
512
|
+
...rest,
|
|
513
|
+
credential_definition: {
|
|
514
|
+
"@context": context,
|
|
515
|
+
type: types,
|
|
516
|
+
...credentialSubject ? { credentialSubject } : {}
|
|
517
|
+
}
|
|
518
|
+
}));
|
|
519
|
+
const zLdpVcCredentialIssuerMetadataDraft14To11 = zLdpVcCredentialIssuerMetadataDraft14.passthrough().transform(({ credential_definition: { type,...credentialDefinition },...rest }) => ({
|
|
520
|
+
...rest,
|
|
521
|
+
...credentialDefinition,
|
|
522
|
+
types: type
|
|
523
|
+
})).pipe(zLdpVcCredentialIssuerMetadataDraft11);
|
|
524
|
+
const zLdpVcCredentialRequestFormatDraft14 = z.object({
|
|
525
|
+
format: zLdpVcFormatIdentifier,
|
|
526
|
+
credential_definition: zW3cVcJsonLdCredentialDefinitionDraft14
|
|
681
527
|
});
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
528
|
+
const zLdpVcCredentialRequestDraft11 = z.object({
|
|
529
|
+
format: zLdpVcFormatIdentifier,
|
|
530
|
+
credential_definition: z.object({
|
|
531
|
+
"@context": z.array(z.string()),
|
|
532
|
+
types: z.array(z.string()),
|
|
533
|
+
credentialSubject: zW3cVcCredentialSubjectDraft14.optional()
|
|
534
|
+
})
|
|
688
535
|
}).passthrough();
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
types: type,
|
|
704
|
-
...credentialDefinition
|
|
705
|
-
})).pipe(zJwtVcJsonCredentialRequestDraft11);
|
|
536
|
+
const zLdpVcCredentialRequestDraft11To14 = zLdpVcCredentialRequestDraft11.transform(({ credential_definition: { types,...restCredentialDefinition },...rest }) => ({
|
|
537
|
+
...rest,
|
|
538
|
+
credential_definition: {
|
|
539
|
+
...restCredentialDefinition,
|
|
540
|
+
type: types
|
|
541
|
+
}
|
|
542
|
+
}));
|
|
543
|
+
const zLdpVcCredentialRequestDraft14To11 = zLdpVcCredentialRequestFormatDraft14.passthrough().transform(({ credential_definition: { type,...restCredentialDefinition },...rest }) => ({
|
|
544
|
+
...rest,
|
|
545
|
+
credential_definition: {
|
|
546
|
+
...restCredentialDefinition,
|
|
547
|
+
types: type
|
|
548
|
+
}
|
|
549
|
+
})).pipe(zLdpVcCredentialRequestDraft11);
|
|
706
550
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({
|
|
717
|
-
claims: z12.array(zIssuerMetadataClaimsDescription).optional()
|
|
718
|
-
}).optional(),
|
|
719
|
-
// FIXME(vc+sd-jwt): remove when dropping support for legacy vc+sd-jwt. Allows type narrowing.
|
|
720
|
-
vct: z12.optional(z12.never())
|
|
551
|
+
//#endregion
|
|
552
|
+
//#region src/formats/credential/w3c-vc/z-w3c-sd-jwt-vc.ts
|
|
553
|
+
const zSdJwtW3VcFormatIdentifier = z.literal("vc+sd-jwt");
|
|
554
|
+
const zSdJwtW3VcCredentialDefinition = z.object({ type: z.array(z.string()).nonempty() }).passthrough();
|
|
555
|
+
const zSdJwtW3VcCredentialIssuerMetadata = zCredentialConfigurationSupportedCommon.extend({
|
|
556
|
+
format: zSdJwtW3VcFormatIdentifier,
|
|
557
|
+
credential_definition: zSdJwtW3VcCredentialDefinition,
|
|
558
|
+
credential_metadata: zCredentialConfigurationSupportedCommonCredentialMetadata.extend({ claims: z.array(zIssuerMetadataClaimsDescription).optional() }).optional(),
|
|
559
|
+
vct: z.optional(z.never())
|
|
721
560
|
});
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
vct: z12.optional(z12.never())
|
|
561
|
+
const zSdJwtW3VcCredentialIssuerMetadataDraft15 = zCredentialConfigurationSupportedCommonDraft15.extend({
|
|
562
|
+
format: zSdJwtW3VcFormatIdentifier,
|
|
563
|
+
credential_definition: zSdJwtW3VcCredentialDefinition,
|
|
564
|
+
claims: z.array(zIssuerMetadataClaimsDescription).optional(),
|
|
565
|
+
vct: z.optional(z.never())
|
|
728
566
|
});
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
vct: z12.optional(z12.never())
|
|
567
|
+
const zSdJwtW3VcCredentialRequestFormatDraft14 = z.object({
|
|
568
|
+
format: zSdJwtW3VcFormatIdentifier,
|
|
569
|
+
credential_definition: zSdJwtW3VcCredentialDefinition,
|
|
570
|
+
vct: z.optional(z.never())
|
|
734
571
|
});
|
|
735
572
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region src/metadata/credential-issuer/z-credential-issuer-metadata.ts
|
|
575
|
+
const allCredentialIssuerMetadataFormats = [
|
|
576
|
+
zSdJwtDcCredentialIssuerMetadata,
|
|
577
|
+
zMsoMdocCredentialIssuerMetadata,
|
|
578
|
+
zJwtVcJsonLdCredentialIssuerMetadata,
|
|
579
|
+
zLdpVcCredentialIssuerMetadata,
|
|
580
|
+
zJwtVcJsonCredentialIssuerMetadata,
|
|
581
|
+
zSdJwtW3VcCredentialIssuerMetadata,
|
|
582
|
+
zSdJwtW3VcCredentialIssuerMetadataDraft15,
|
|
583
|
+
zLegacySdJwtVcCredentialIssuerMetadataDraft16,
|
|
584
|
+
zSdJwtDcCredentialIssuerMetadataDraft15,
|
|
585
|
+
zMsoMdocCredentialIssuerMetadataDraft15,
|
|
586
|
+
zJwtVcJsonLdCredentialIssuerMetadataDraft15,
|
|
587
|
+
zLdpVcCredentialIssuerMetadataDraft15,
|
|
588
|
+
zJwtVcJsonCredentialIssuerMetadataDraft15,
|
|
589
|
+
zMsoMdocCredentialIssuerMetadataDraft14,
|
|
590
|
+
zLegacySdJwtVcCredentialIssuerMetadataDraft14,
|
|
591
|
+
zJwtVcJsonLdCredentialIssuerMetadataDraft14,
|
|
592
|
+
zLdpVcCredentialIssuerMetadataDraft14,
|
|
593
|
+
zJwtVcJsonCredentialIssuerMetadataDraft14
|
|
756
594
|
];
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
);
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
const result = z13.object({}).passthrough().and(
|
|
766
|
-
validators.length > 1 ? z13.union(
|
|
767
|
-
validators
|
|
768
|
-
) : validators[0]
|
|
769
|
-
).safeParse(data);
|
|
770
|
-
if (result.success) {
|
|
771
|
-
return result.data;
|
|
772
|
-
}
|
|
773
|
-
for (const issue of result.error.issues) {
|
|
774
|
-
ctx.addIssue(issue);
|
|
775
|
-
}
|
|
776
|
-
return z13.NEVER;
|
|
595
|
+
const allCredentialIssuerMetadataFormatIdentifiers = allCredentialIssuerMetadataFormats.map((format) => format.shape.format.value);
|
|
596
|
+
const zCredentialConfigurationSupportedWithFormats = z.union([zCredentialConfigurationSupportedCommon, zCredentialConfigurationSupportedCommonDraft15]).transform((data, ctx) => {
|
|
597
|
+
if (!allCredentialIssuerMetadataFormatIdentifiers.includes(data.format)) return data;
|
|
598
|
+
const validators = allCredentialIssuerMetadataFormats.filter((formatValidator) => formatValidator.shape.format.value === data.format);
|
|
599
|
+
const result = z.object({}).passthrough().and(validators.length > 1 ? z.union(validators) : validators[0]).safeParse(data);
|
|
600
|
+
if (result.success) return result.data;
|
|
601
|
+
for (const issue of result.error.issues) ctx.addIssue(issue);
|
|
602
|
+
return z.NEVER;
|
|
777
603
|
});
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
}).passthrough().optional()
|
|
604
|
+
const zCredentialIssuerMetadataDisplayEntry = z.object({
|
|
605
|
+
name: z.string().optional(),
|
|
606
|
+
locale: z.string().optional(),
|
|
607
|
+
logo: z.object({
|
|
608
|
+
uri: z.string().optional(),
|
|
609
|
+
alt_text: z.string().optional()
|
|
610
|
+
}).passthrough().optional()
|
|
786
611
|
}).passthrough();
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
signed_metadata: zCompactJwt.optional(),
|
|
804
|
-
display: z13.array(zCredentialIssuerMetadataDisplayEntry).optional(),
|
|
805
|
-
credential_configurations_supported: z13.record(z13.string(), zCredentialConfigurationSupportedWithFormats)
|
|
612
|
+
const zCredentialIssuerMetadataDraft14Draft15Draft16 = z.object({
|
|
613
|
+
credential_issuer: zHttpsUrl,
|
|
614
|
+
authorization_servers: z.array(zHttpsUrl).optional(),
|
|
615
|
+
credential_endpoint: zHttpsUrl,
|
|
616
|
+
deferred_credential_endpoint: zHttpsUrl.optional(),
|
|
617
|
+
notification_endpoint: zHttpsUrl.optional(),
|
|
618
|
+
nonce_endpoint: zHttpsUrl.optional(),
|
|
619
|
+
credential_response_encryption: z.object({
|
|
620
|
+
alg_values_supported: z.array(z.string()),
|
|
621
|
+
enc_values_supported: z.array(z.string()),
|
|
622
|
+
encryption_required: z.boolean()
|
|
623
|
+
}).passthrough().optional(),
|
|
624
|
+
batch_credential_issuance: z.object({ batch_size: z.number().positive() }).passthrough().optional(),
|
|
625
|
+
signed_metadata: zCompactJwt.optional(),
|
|
626
|
+
display: z.array(zCredentialIssuerMetadataDisplayEntry).optional(),
|
|
627
|
+
credential_configurations_supported: z.record(z.string(), zCredentialConfigurationSupportedWithFormats)
|
|
806
628
|
}).passthrough();
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
...claims ? { claims } : {},
|
|
828
|
-
...display ? {
|
|
829
|
-
display: display.map(({ logo, background_image, ...displayRest }) => ({
|
|
830
|
-
...displayRest,
|
|
831
|
-
// url became uri and also required
|
|
832
|
-
// so if there's no url in the logo, we remove the whole logo object
|
|
833
|
-
...logo?.url ? {
|
|
834
|
-
// TODO: we should add the other params from logo as well
|
|
835
|
-
logo: {
|
|
836
|
-
uri: logo.url
|
|
837
|
-
}
|
|
838
|
-
} : {},
|
|
839
|
-
// TODO: we should add the other params from background_image as well
|
|
840
|
-
// url became uri and also required
|
|
841
|
-
// so if there's no url in the background_image, we remove the whole logo object
|
|
842
|
-
...background_image?.url ? {
|
|
843
|
-
background_image: {
|
|
844
|
-
uri: background_image.url
|
|
845
|
-
}
|
|
846
|
-
} : {}
|
|
847
|
-
}))
|
|
848
|
-
} : {}
|
|
849
|
-
}
|
|
850
|
-
} : {}
|
|
629
|
+
const zCredentialConfigurationSupportedDraft11To16 = z.object({
|
|
630
|
+
id: z.string().optional(),
|
|
631
|
+
format: z.string(),
|
|
632
|
+
cryptographic_suites_supported: z.array(z.string()).optional(),
|
|
633
|
+
display: z.array(z.object({
|
|
634
|
+
logo: z.object({ url: z.string().url().optional() }).passthrough().optional(),
|
|
635
|
+
background_image: z.object({ url: z.string().url().optional() }).passthrough().optional()
|
|
636
|
+
}).passthrough()).optional(),
|
|
637
|
+
claims: z.any().optional()
|
|
638
|
+
}).passthrough().transform(({ cryptographic_suites_supported, display, claims, id,...rest }) => ({
|
|
639
|
+
...rest,
|
|
640
|
+
...cryptographic_suites_supported ? { credential_signing_alg_values_supported: cryptographic_suites_supported } : {},
|
|
641
|
+
...claims || display ? { credential_metadata: {
|
|
642
|
+
...claims ? { claims } : {},
|
|
643
|
+
...display ? { display: display.map(({ logo, background_image,...displayRest }) => ({
|
|
644
|
+
...displayRest,
|
|
645
|
+
...logo?.url ? { logo: { uri: logo.url } } : {},
|
|
646
|
+
...background_image?.url ? { background_image: { uri: background_image.url } } : {}
|
|
647
|
+
})) } : {}
|
|
648
|
+
} } : {}
|
|
851
649
|
})).transform((data, ctx) => {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
ctx.addIssue(issue);
|
|
863
|
-
}
|
|
864
|
-
return z13.NEVER;
|
|
650
|
+
const formatSpecificTransformations = {
|
|
651
|
+
[zLdpVcFormatIdentifier.value]: zLdpVcCredentialIssuerMetadataDraft11To14,
|
|
652
|
+
[zJwtVcJsonFormatIdentifier.value]: zJwtVcJsonCredentialIssuerMetadataDraft11To14,
|
|
653
|
+
[zJwtVcJsonLdFormatIdentifier.value]: zJwtVcJsonLdCredentialIssuerMetadataDraft11To14
|
|
654
|
+
};
|
|
655
|
+
if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
|
|
656
|
+
const result = formatSpecificTransformations[data.format].safeParse(data);
|
|
657
|
+
if (result.success) return result.data;
|
|
658
|
+
for (const issue of result.error.issues) ctx.addIssue(issue);
|
|
659
|
+
return z.NEVER;
|
|
865
660
|
}).pipe(zCredentialConfigurationSupportedWithFormats);
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
)
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
...issuerMetadata.authorization_servers ? { authorization_server: issuerMetadata.authorization_servers[0] } : {},
|
|
937
|
-
credentials_supported: Object.entries(issuerMetadata.credential_configurations_supported).map(([id, value]) => ({
|
|
938
|
-
...value,
|
|
939
|
-
id
|
|
940
|
-
}))
|
|
941
|
-
})).pipe(
|
|
942
|
-
zCredentialIssuerMetadataDraft14Draft15Draft16.extend({
|
|
943
|
-
credentials_supported: z13.array(zCredentialConfigurationSupportedDraft16To11)
|
|
944
|
-
})
|
|
945
|
-
);
|
|
946
|
-
var zCredentialIssuerMetadata = z13.union([
|
|
947
|
-
// First prioritize draft 16/15/14 (and 13)
|
|
948
|
-
zCredentialIssuerMetadataDraft14Draft15Draft16,
|
|
949
|
-
// Then try parsing draft 11 and transform into draft 16
|
|
950
|
-
zCredentialIssuerMetadataDraft11To16
|
|
951
|
-
]);
|
|
952
|
-
var zCredentialIssuerMetadataWithDraftVersion = z13.union([
|
|
953
|
-
zCredentialIssuerMetadataDraft14Draft15Draft16.transform((credentialIssuerMetadata) => {
|
|
954
|
-
const credentialConfigurations = Object.values(credentialIssuerMetadata.credential_configurations_supported);
|
|
955
|
-
const isDraft15 = credentialConfigurations.some((configuration) => {
|
|
956
|
-
const knownConfiguration = configuration;
|
|
957
|
-
if (knownConfiguration.format === zSdJwtDcFormatIdentifier.value) return true;
|
|
958
|
-
if (Array.isArray(knownConfiguration.claims)) return true;
|
|
959
|
-
if (Object.values(knownConfiguration.proof_types_supported ?? {}).some(
|
|
960
|
-
(proofType) => proofType.key_attestations_required !== void 0
|
|
961
|
-
))
|
|
962
|
-
return true;
|
|
963
|
-
return false;
|
|
964
|
-
});
|
|
965
|
-
const isDraft16 = credentialConfigurations.some((configuration) => {
|
|
966
|
-
return configuration.credential_metadata;
|
|
967
|
-
});
|
|
968
|
-
return {
|
|
969
|
-
credentialIssuerMetadata,
|
|
970
|
-
originalDraftVersion: isDraft16 ? "Draft16" /* Draft16 */ : isDraft15 ? "Draft15" /* Draft15 */ : "Draft14" /* Draft14 */
|
|
971
|
-
};
|
|
972
|
-
}),
|
|
973
|
-
// Then try parsing draft 11 and transform into draft 14
|
|
974
|
-
zCredentialIssuerMetadataDraft11To16.transform((credentialIssuerMetadata) => ({
|
|
975
|
-
credentialIssuerMetadata,
|
|
976
|
-
originalDraftVersion: "Draft11" /* Draft11 */
|
|
977
|
-
}))
|
|
978
|
-
]);
|
|
661
|
+
const zCredentialConfigurationSupportedDraft16To11 = zCredentialConfigurationSupportedWithFormats.transform(({ credential_metadata,...rest }) => ({
|
|
662
|
+
...credential_metadata,
|
|
663
|
+
...rest
|
|
664
|
+
})).and(z.object({ id: z.string() }).passthrough()).transform(({ id, credential_signing_alg_values_supported, display, proof_types_supported, scope,...rest }) => ({
|
|
665
|
+
...rest,
|
|
666
|
+
...credential_signing_alg_values_supported ? { cryptographic_suites_supported: credential_signing_alg_values_supported } : {},
|
|
667
|
+
...display ? { display: display.map(({ logo, background_image,...displayRest }) => {
|
|
668
|
+
const { uri: logoUri,...logoRest } = logo ?? {};
|
|
669
|
+
const { uri: backgroundImageUri,...backgroundImageRest } = background_image ?? {};
|
|
670
|
+
return {
|
|
671
|
+
...displayRest,
|
|
672
|
+
...logoUri ? { logo: {
|
|
673
|
+
url: logoUri,
|
|
674
|
+
...logoRest
|
|
675
|
+
} } : {},
|
|
676
|
+
...backgroundImageUri ? { logo: {
|
|
677
|
+
url: backgroundImageUri,
|
|
678
|
+
...backgroundImageRest
|
|
679
|
+
} } : {}
|
|
680
|
+
};
|
|
681
|
+
}) } : {},
|
|
682
|
+
id
|
|
683
|
+
})).pipe(z.union([
|
|
684
|
+
zLdpVcCredentialIssuerMetadataDraft14To11,
|
|
685
|
+
zJwtVcJsonCredentialIssuerMetadataDraft14To11,
|
|
686
|
+
zJwtVcJsonLdCredentialIssuerMetadataDraft14To11,
|
|
687
|
+
z.object({ format: z.string().refine((input) => ![
|
|
688
|
+
zLdpVcFormatIdentifier.value,
|
|
689
|
+
zJwtVcJsonFormatIdentifier.value,
|
|
690
|
+
zJwtVcJsonLdFormatIdentifier.value
|
|
691
|
+
].includes(input)) }).passthrough()
|
|
692
|
+
]));
|
|
693
|
+
const zCredentialIssuerMetadataDraft11To16 = z.object({
|
|
694
|
+
authorization_server: z.string().optional(),
|
|
695
|
+
credentials_supported: z.array(z.object({ id: z.string().optional() }).passthrough())
|
|
696
|
+
}).passthrough().transform(({ authorization_server, credentials_supported,...rest }) => {
|
|
697
|
+
return {
|
|
698
|
+
...rest,
|
|
699
|
+
...authorization_server ? { authorization_servers: [authorization_server] } : {},
|
|
700
|
+
credential_configurations_supported: Object.fromEntries(credentials_supported.map((supported) => supported.id ? [supported.id, supported] : void 0).filter((i) => i !== void 0))
|
|
701
|
+
};
|
|
702
|
+
}).pipe(z.object({ credential_configurations_supported: z.record(z.string(), zCredentialConfigurationSupportedDraft11To16) }).passthrough()).pipe(zCredentialIssuerMetadataDraft14Draft15Draft16);
|
|
703
|
+
const zCredentialIssuerMetadataWithDraft11 = zCredentialIssuerMetadataDraft14Draft15Draft16.transform((issuerMetadata) => ({
|
|
704
|
+
...issuerMetadata,
|
|
705
|
+
...issuerMetadata.authorization_servers ? { authorization_server: issuerMetadata.authorization_servers[0] } : {},
|
|
706
|
+
credentials_supported: Object.entries(issuerMetadata.credential_configurations_supported).map(([id, value]) => ({
|
|
707
|
+
...value,
|
|
708
|
+
id
|
|
709
|
+
}))
|
|
710
|
+
})).pipe(zCredentialIssuerMetadataDraft14Draft15Draft16.extend({ credentials_supported: z.array(zCredentialConfigurationSupportedDraft16To11) }));
|
|
711
|
+
const zCredentialIssuerMetadata = z.union([zCredentialIssuerMetadataDraft14Draft15Draft16, zCredentialIssuerMetadataDraft11To16]);
|
|
712
|
+
const zCredentialIssuerMetadataWithDraftVersion = z.union([zCredentialIssuerMetadataDraft14Draft15Draft16.transform((credentialIssuerMetadata) => {
|
|
713
|
+
const credentialConfigurations = Object.values(credentialIssuerMetadata.credential_configurations_supported);
|
|
714
|
+
const isDraft15 = credentialConfigurations.some((configuration) => {
|
|
715
|
+
const knownConfiguration = configuration;
|
|
716
|
+
if (knownConfiguration.format === zSdJwtDcFormatIdentifier.value) return true;
|
|
717
|
+
if (Array.isArray(knownConfiguration.claims)) return true;
|
|
718
|
+
if (Object.values(knownConfiguration.proof_types_supported ?? {}).some((proofType) => proofType.key_attestations_required !== void 0)) return true;
|
|
719
|
+
return false;
|
|
720
|
+
});
|
|
721
|
+
return {
|
|
722
|
+
credentialIssuerMetadata,
|
|
723
|
+
originalDraftVersion: credentialConfigurations.some((configuration) => {
|
|
724
|
+
return configuration.credential_metadata;
|
|
725
|
+
}) ? Openid4vciDraftVersion.Draft16 : isDraft15 ? Openid4vciDraftVersion.Draft15 : Openid4vciDraftVersion.Draft14
|
|
726
|
+
};
|
|
727
|
+
}), zCredentialIssuerMetadataDraft11To16.transform((credentialIssuerMetadata) => ({
|
|
728
|
+
credentialIssuerMetadata,
|
|
729
|
+
originalDraftVersion: Openid4vciDraftVersion.Draft11
|
|
730
|
+
}))]);
|
|
979
731
|
|
|
980
|
-
|
|
981
|
-
|
|
732
|
+
//#endregion
|
|
733
|
+
//#region src/metadata/credential-issuer/credential-issuer-metadata.ts
|
|
734
|
+
const wellKnownCredentialIssuerSuffix = ".well-known/openid-credential-issuer";
|
|
735
|
+
/**
|
|
736
|
+
* @inheritdoc {@link fetchWellKnownMetadata}
|
|
737
|
+
*/
|
|
982
738
|
async function fetchCredentialIssuerMetadata(credentialIssuer, fetch) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
`The 'credential_issuer' parameter '${result.credentialIssuerMetadata.credential_issuer}' in the well known credential issuer metadata at '${wellKnownMetadataUrl}' does not match the provided credential issuer '${credentialIssuer}'.`
|
|
988
|
-
);
|
|
989
|
-
}
|
|
990
|
-
return result;
|
|
739
|
+
const wellKnownMetadataUrl = joinUriParts(credentialIssuer, [wellKnownCredentialIssuerSuffix]);
|
|
740
|
+
const result = await fetchWellKnownMetadata(wellKnownMetadataUrl, zCredentialIssuerMetadataWithDraftVersion, fetch);
|
|
741
|
+
if (result && result.credentialIssuerMetadata.credential_issuer !== credentialIssuer) throw new Oauth2Error(`The 'credential_issuer' parameter '${result.credentialIssuerMetadata.credential_issuer}' in the well known credential issuer metadata at '${wellKnownMetadataUrl}' does not match the provided credential issuer '${credentialIssuer}'.`);
|
|
742
|
+
return result;
|
|
991
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* Extract credential configuration supported entries where the `format` is known to this
|
|
746
|
+
* library. Should be ran only after verifying the credential issuer metadata structure, so
|
|
747
|
+
* we can be certain that if the `format` matches the other format specific requirements are also met.
|
|
748
|
+
*
|
|
749
|
+
* Validation is done when resolving issuer metadata, or when calling `createIssuerMetadata`.
|
|
750
|
+
*/
|
|
992
751
|
function extractKnownCredentialConfigurationSupportedFormats(credentialConfigurationsSupported) {
|
|
993
|
-
|
|
994
|
-
Object.entries(credentialConfigurationsSupported).filter(
|
|
995
|
-
(entry) => allCredentialIssuerMetadataFormatIdentifiers.includes(entry[1].format)
|
|
996
|
-
)
|
|
997
|
-
);
|
|
752
|
+
return Object.fromEntries(Object.entries(credentialConfigurationsSupported).filter((entry) => allCredentialIssuerMetadataFormatIdentifiers.includes(entry[1].format)));
|
|
998
753
|
}
|
|
999
754
|
function getCredentialConfigurationSupportedById(credentialConfigurations, credentialConfigurationId) {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
`Credential configuration with id '${credentialConfigurationId}' not found in credential configurations supported.`
|
|
1004
|
-
);
|
|
1005
|
-
}
|
|
1006
|
-
return configuration;
|
|
755
|
+
const configuration = credentialConfigurations[credentialConfigurationId];
|
|
756
|
+
if (!configuration) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in credential configurations supported.`);
|
|
757
|
+
return configuration;
|
|
1007
758
|
}
|
|
1008
759
|
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
if (c.format === "vc+sd-jwt" && r.format === c.format) {
|
|
1027
|
-
if (r.vct && c.vct) {
|
|
1028
|
-
return r.vct === c.vct;
|
|
1029
|
-
}
|
|
1030
|
-
if (c.credential_definition && r.credential_definition) {
|
|
1031
|
-
return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
if (c.format === "mso_mdoc" && r.format === c.format) {
|
|
1035
|
-
return r.doctype === c.doctype;
|
|
1036
|
-
}
|
|
1037
|
-
return false;
|
|
1038
|
-
})
|
|
1039
|
-
);
|
|
760
|
+
//#endregion
|
|
761
|
+
//#region src/credential-request/credential-request-configurations.ts
|
|
762
|
+
function getCredentialConfigurationsMatchingRequestFormat({ requestFormat, credentialConfigurations }) {
|
|
763
|
+
const knownCredentialConfigurations = extractKnownCredentialConfigurationSupportedFormats(credentialConfigurations);
|
|
764
|
+
return Object.fromEntries(Object.entries(knownCredentialConfigurations).filter(([, credentialConfiguration]) => {
|
|
765
|
+
if (credentialConfiguration.format !== requestFormat.format) return false;
|
|
766
|
+
const r = requestFormat;
|
|
767
|
+
const c = credentialConfiguration;
|
|
768
|
+
if ((c.format === "ldp_vc" || c.format === "jwt_vc_json-ld") && r.format === c.format) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type) && arrayEqualsIgnoreOrder(r.credential_definition["@context"], c.credential_definition["@context"]);
|
|
769
|
+
if (c.format === "jwt_vc_json" && r.format === c.format) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
770
|
+
if (c.format === "vc+sd-jwt" && r.format === c.format) {
|
|
771
|
+
if (r.vct && c.vct) return r.vct === c.vct;
|
|
772
|
+
if (c.credential_definition && r.credential_definition) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
773
|
+
}
|
|
774
|
+
if (c.format === "mso_mdoc" && r.format === c.format) return r.doctype === c.doctype;
|
|
775
|
+
return false;
|
|
776
|
+
}));
|
|
1040
777
|
}
|
|
1041
778
|
|
|
1042
|
-
|
|
779
|
+
//#endregion
|
|
780
|
+
//#region src/error/Openid4vciError.ts
|
|
1043
781
|
var Openid4vciError = class extends Error {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
782
|
+
constructor(message, options) {
|
|
783
|
+
const errorMessage = message ?? "Unknown error occured.";
|
|
784
|
+
const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
|
|
785
|
+
super(`${errorMessage}${causeMessage}`);
|
|
786
|
+
this.cause = options?.cause;
|
|
787
|
+
}
|
|
1050
788
|
};
|
|
1051
789
|
|
|
1052
|
-
|
|
1053
|
-
|
|
790
|
+
//#endregion
|
|
791
|
+
//#region src/error/Openid4vciRetrieveCredentialsError.ts
|
|
1054
792
|
var Openid4vciRetrieveCredentialsError = class extends Openid4vciError {
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
793
|
+
constructor(message, response, responseText) {
|
|
794
|
+
const errorData = response.credentialResponseResult?.data ?? response.credentialErrorResponseResult?.data ?? (response.credentialResponseResult?.error ? formatZodError(response.credentialResponseResult.error) : void 0) ?? responseText;
|
|
795
|
+
super(`${message}\n${JSON.stringify(errorData, null, 2)}`);
|
|
796
|
+
this.response = response;
|
|
797
|
+
}
|
|
1061
798
|
};
|
|
1062
799
|
|
|
1063
|
-
|
|
800
|
+
//#endregion
|
|
801
|
+
//#region src/error/Openid4vciSendNotificationError.ts
|
|
1064
802
|
var Openid4vciSendNotificationError = class extends Openid4vciError {
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
803
|
+
constructor(message, response) {
|
|
804
|
+
super(message);
|
|
805
|
+
this.response = response;
|
|
806
|
+
}
|
|
1069
807
|
};
|
|
1070
808
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
import { jwtSignerFromJwt, verifyJwt } from "@openid4vc/oauth2";
|
|
1074
|
-
import { dateToSeconds, parseWithErrorHandling as parseWithErrorHandling2 } from "@openid4vc/utils";
|
|
809
|
+
//#endregion
|
|
810
|
+
//#region src/key-attestation/key-attestation.ts
|
|
1075
811
|
async function createKeyAttestationJwt(options) {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
812
|
+
const header = parseWithErrorHandling(zKeyAttestationJwtHeader, {
|
|
813
|
+
...jwtHeaderFromJwtSigner(options.signer),
|
|
814
|
+
typ: "keyattestation+jwt"
|
|
815
|
+
});
|
|
816
|
+
const payload = parseWithErrorHandling(zKeyAttestationJwtPayloadForUse(options.use), {
|
|
817
|
+
iat: dateToSeconds(options.issuedAt),
|
|
818
|
+
exp: options.expiresAt ? dateToSeconds(options.expiresAt) : void 0,
|
|
819
|
+
nonce: options.nonce,
|
|
820
|
+
attested_keys: options.attestedKeys,
|
|
821
|
+
user_authentication: options.userAuthentication,
|
|
822
|
+
key_storage: options.keyStorage,
|
|
823
|
+
certification: options.certification,
|
|
824
|
+
...options.additionalPayload
|
|
825
|
+
});
|
|
826
|
+
const { jwt } = await options.callbacks.signJwt(options.signer, {
|
|
827
|
+
header,
|
|
828
|
+
payload
|
|
829
|
+
});
|
|
830
|
+
return jwt;
|
|
1092
831
|
}
|
|
1093
832
|
function parseKeyAttestationJwt({ keyAttestationJwt, use }) {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
833
|
+
return decodeJwt({
|
|
834
|
+
jwt: keyAttestationJwt,
|
|
835
|
+
headerSchema: zKeyAttestationJwtHeader,
|
|
836
|
+
payloadSchema: zKeyAttestationJwtPayloadForUse(use)
|
|
837
|
+
});
|
|
1099
838
|
}
|
|
1100
839
|
async function verifyKeyAttestationJwt(options) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
840
|
+
const { header, payload } = parseKeyAttestationJwt({
|
|
841
|
+
keyAttestationJwt: options.keyAttestationJwt,
|
|
842
|
+
use: options.use
|
|
843
|
+
});
|
|
844
|
+
const now = options.now?.getTime() ?? Date.now();
|
|
845
|
+
if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) throw new Openid4vciError("Nonce used for key attestation jwt expired");
|
|
846
|
+
const { signer } = await verifyJwt({
|
|
847
|
+
compact: options.keyAttestationJwt,
|
|
848
|
+
header,
|
|
849
|
+
payload,
|
|
850
|
+
signer: jwtSignerFromJwt({
|
|
851
|
+
header,
|
|
852
|
+
payload
|
|
853
|
+
}),
|
|
854
|
+
verifyJwtCallback: options.callbacks.verifyJwt,
|
|
855
|
+
errorMessage: "Error verifiying key attestation jwt",
|
|
856
|
+
expectedNonce: options.expectedNonce,
|
|
857
|
+
now: options.now
|
|
858
|
+
});
|
|
859
|
+
return {
|
|
860
|
+
header,
|
|
861
|
+
payload,
|
|
862
|
+
signer
|
|
863
|
+
};
|
|
1121
864
|
}
|
|
1122
865
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
import { ValidationError as ValidationError2 } from "@openid4vc/utils";
|
|
866
|
+
//#endregion
|
|
867
|
+
//#region src/metadata/credential-issuer/credential-configurations.ts
|
|
1126
868
|
function extractScopesForCredentialConfigurationIds(options) {
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if (scope) scopes.add(scope);
|
|
1137
|
-
else if (!scope && options.throwOnConfigurationWithoutScope) {
|
|
1138
|
-
throw new Oauth2Error3(
|
|
1139
|
-
`Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`
|
|
1140
|
-
);
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
return scopes.size > 0 ? Array.from(scopes) : void 0;
|
|
869
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
870
|
+
for (const credentialConfigurationId of options.credentialConfigurationIds) {
|
|
871
|
+
const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
872
|
+
if (!credentialConfiguration) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in metadata from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
873
|
+
const scope = credentialConfiguration.scope;
|
|
874
|
+
if (scope) scopes.add(scope);
|
|
875
|
+
else if (!scope && options.throwOnConfigurationWithoutScope) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`);
|
|
876
|
+
}
|
|
877
|
+
return scopes.size > 0 ? Array.from(scopes) : void 0;
|
|
1144
878
|
}
|
|
879
|
+
/**
|
|
880
|
+
* Transforms draft 11 credentials supported syntax to credential configurations supported
|
|
881
|
+
*
|
|
882
|
+
* @throws if a credentials supported entry without id is passed
|
|
883
|
+
* @throws if a credentials supported entry with invalid structure or format specific properties is passed
|
|
884
|
+
*/
|
|
1145
885
|
function credentialsSupportedToCredentialConfigurationsSupported(credentialsSupported) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
if (!parseResult.success) {
|
|
1156
|
-
throw new ValidationError2(
|
|
1157
|
-
`Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`,
|
|
1158
|
-
parseResult.error
|
|
1159
|
-
);
|
|
1160
|
-
}
|
|
1161
|
-
credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
|
|
1162
|
-
}
|
|
1163
|
-
return credentialConfigurationsSupported;
|
|
886
|
+
const credentialConfigurationsSupported = {};
|
|
887
|
+
for (let index = 0; index < credentialsSupported.length; index++) {
|
|
888
|
+
const credentialSupported = credentialsSupported[index];
|
|
889
|
+
if (!credentialSupported.id) throw new Openid4vciError(`Credential supported at index '${index}' does not have an 'id' property. Credential configuration requires the 'id' property as key`);
|
|
890
|
+
const parseResult = zCredentialConfigurationSupportedDraft11To16.safeParse(credentialSupported);
|
|
891
|
+
if (!parseResult.success) throw new ValidationError(`Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`, parseResult.error);
|
|
892
|
+
credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
|
|
893
|
+
}
|
|
894
|
+
return credentialConfigurationsSupported;
|
|
1164
895
|
}
|
|
1165
896
|
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
Oauth2Client,
|
|
1169
|
-
Oauth2ClientAuthorizationChallengeError,
|
|
1170
|
-
Oauth2Error as Oauth2Error7,
|
|
1171
|
-
Oauth2ErrorCodes as Oauth2ErrorCodes2,
|
|
1172
|
-
authorizationCodeGrantIdentifier as authorizationCodeGrantIdentifier2,
|
|
1173
|
-
getAuthorizationServerMetadataFromList as getAuthorizationServerMetadataFromList2,
|
|
1174
|
-
preAuthorizedCodeGrantIdentifier as preAuthorizedCodeGrantIdentifier3
|
|
1175
|
-
} from "@openid4vc/oauth2";
|
|
1176
|
-
|
|
1177
|
-
// src/credential-request/format-payload.ts
|
|
1178
|
-
import { zIs } from "@openid4vc/utils";
|
|
897
|
+
//#endregion
|
|
898
|
+
//#region src/credential-request/format-payload.ts
|
|
1179
899
|
function getCredentialRequestFormatPayloadForCredentialConfigurationId(options) {
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
}
|
|
1214
|
-
if (zIs(zJwtVcJsonCredentialIssuerMetadata, credentialConfiguration) || zIs(zJwtVcJsonCredentialIssuerMetadataDraft14, credentialConfiguration)) {
|
|
1215
|
-
return {
|
|
1216
|
-
format: credentialConfiguration.format,
|
|
1217
|
-
credential_definition: {
|
|
1218
|
-
type: credentialConfiguration.credential_definition.type
|
|
1219
|
-
}
|
|
1220
|
-
};
|
|
1221
|
-
}
|
|
1222
|
-
if (zIs(zSdJwtDcCredentialIssuerMetadata, credentialConfiguration)) {
|
|
1223
|
-
throw new Openid4vciError(
|
|
1224
|
-
`Credential configuration id '${options.credentialConfigurationId}' with format ${zLegacySdJwtVcFormatIdentifier.value} does not support credential request based on 'format'. Use 'credential_configuration_id' directly.`
|
|
1225
|
-
);
|
|
1226
|
-
}
|
|
1227
|
-
if (zIs(zSdJwtW3VcCredentialIssuerMetadata, credentialConfiguration)) {
|
|
1228
|
-
return {
|
|
1229
|
-
format: credentialConfiguration.format,
|
|
1230
|
-
credential_definition: {
|
|
1231
|
-
type: credentialConfiguration.credential_definition.type
|
|
1232
|
-
}
|
|
1233
|
-
};
|
|
1234
|
-
}
|
|
1235
|
-
throw new Openid4vciError(
|
|
1236
|
-
`Unknown format '${credentialConfiguration.format}' in credential configuration with id '${options.credentialConfigurationId}' for credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`
|
|
1237
|
-
);
|
|
900
|
+
const credentialConfiguration = getCredentialConfigurationSupportedById(options.issuerMetadata.credentialIssuer.credential_configurations_supported, options.credentialConfigurationId);
|
|
901
|
+
if (zIs(zLegacySdJwtVcCredentialIssuerMetadataDraft16, credentialConfiguration) || zIs(zLegacySdJwtVcCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
902
|
+
format: credentialConfiguration.format,
|
|
903
|
+
vct: credentialConfiguration.vct
|
|
904
|
+
};
|
|
905
|
+
if (zIs(zMsoMdocCredentialIssuerMetadata, credentialConfiguration) || zIs(zMsoMdocCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
906
|
+
format: credentialConfiguration.format,
|
|
907
|
+
doctype: credentialConfiguration.doctype
|
|
908
|
+
};
|
|
909
|
+
if (zIs(zLdpVcCredentialIssuerMetadata, credentialConfiguration) || zIs(zLdpVcCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
910
|
+
format: credentialConfiguration.format,
|
|
911
|
+
credential_definition: {
|
|
912
|
+
"@context": credentialConfiguration.credential_definition["@context"],
|
|
913
|
+
type: credentialConfiguration.credential_definition.type
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
if (zIs(zJwtVcJsonLdCredentialIssuerMetadata, credentialConfiguration) || zIs(zJwtVcJsonLdCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
917
|
+
format: credentialConfiguration.format,
|
|
918
|
+
credential_definition: {
|
|
919
|
+
"@context": credentialConfiguration.credential_definition["@context"],
|
|
920
|
+
type: credentialConfiguration.credential_definition.type
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
if (zIs(zJwtVcJsonCredentialIssuerMetadata, credentialConfiguration) || zIs(zJwtVcJsonCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
924
|
+
format: credentialConfiguration.format,
|
|
925
|
+
credential_definition: { type: credentialConfiguration.credential_definition.type }
|
|
926
|
+
};
|
|
927
|
+
if (zIs(zSdJwtDcCredentialIssuerMetadata, credentialConfiguration)) throw new Openid4vciError(`Credential configuration id '${options.credentialConfigurationId}' with format ${zLegacySdJwtVcFormatIdentifier.value} does not support credential request based on 'format'. Use 'credential_configuration_id' directly.`);
|
|
928
|
+
if (zIs(zSdJwtW3VcCredentialIssuerMetadata, credentialConfiguration)) return {
|
|
929
|
+
format: credentialConfiguration.format,
|
|
930
|
+
credential_definition: { type: credentialConfiguration.credential_definition.type }
|
|
931
|
+
};
|
|
932
|
+
throw new Openid4vciError(`Unknown format '${credentialConfiguration.format}' in credential configuration with id '${options.credentialConfigurationId}' for credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
1238
933
|
}
|
|
1239
934
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
// src/credential-request/z-credential-request.ts
|
|
1248
|
-
import { zJwk as zJwk3 } from "@openid4vc/oauth2";
|
|
1249
|
-
import z17 from "zod";
|
|
1250
|
-
|
|
1251
|
-
// src/credential-request/z-credential-request-common.ts
|
|
1252
|
-
import { zJwk as zJwk2 } from "@openid4vc/oauth2";
|
|
1253
|
-
import z16 from "zod";
|
|
1254
|
-
|
|
1255
|
-
// src/formats/proof-type/jwt/z-jwt-proof-type.ts
|
|
1256
|
-
import { zCompactJwt as zCompactJwt2, zJwtHeader as zJwtHeader2, zJwtPayload as zJwtPayload2 } from "@openid4vc/oauth2";
|
|
1257
|
-
import { zHttpsUrl as zHttpsUrl3, zInteger as zInteger2 } from "@openid4vc/utils";
|
|
1258
|
-
import z14 from "zod";
|
|
1259
|
-
var zJwtProofTypeIdentifier = z14.literal("jwt");
|
|
1260
|
-
var jwtProofTypeIdentifier = zJwtProofTypeIdentifier.value;
|
|
1261
|
-
var zCredentialRequestProofJwt = z14.object({
|
|
1262
|
-
proof_type: zJwtProofTypeIdentifier,
|
|
1263
|
-
jwt: zCompactJwt2
|
|
935
|
+
//#endregion
|
|
936
|
+
//#region src/formats/proof-type/attestation/z-attestation-proof-type.ts
|
|
937
|
+
const zAttestationProofTypeIdentifier = z.literal("attestation");
|
|
938
|
+
const attestationProofTypeIdentifier = zAttestationProofTypeIdentifier.value;
|
|
939
|
+
const zCredentialRequestProofAttestation = z.object({
|
|
940
|
+
proof_type: zAttestationProofTypeIdentifier,
|
|
941
|
+
attestation: zCompactJwt
|
|
1264
942
|
});
|
|
1265
|
-
|
|
1266
|
-
z14.object({
|
|
1267
|
-
key_attestation: z14.optional(zCompactJwt2),
|
|
1268
|
-
typ: z14.literal("openid4vci-proof+jwt")
|
|
1269
|
-
})
|
|
1270
|
-
).passthrough().refine(({ kid, jwk }) => jwk === void 0 || kid === void 0, {
|
|
1271
|
-
message: `Both 'jwk' and 'kid' are defined. Only one is allowed`
|
|
1272
|
-
}).refine(({ trust_chain, kid }) => !trust_chain || !kid, {
|
|
1273
|
-
message: `When 'trust_chain' is provided, 'kid' is required`
|
|
1274
|
-
});
|
|
1275
|
-
var zCredentialRequestJwtProofTypePayload = z14.object({
|
|
1276
|
-
...zJwtPayload2.shape,
|
|
1277
|
-
aud: zHttpsUrl3,
|
|
1278
|
-
iat: zInteger2
|
|
1279
|
-
}).passthrough();
|
|
943
|
+
const zCredentialRequestAttestationProofTypePayload = zKeyAttestationJwtPayloadForUse("proof_type.attestation");
|
|
1280
944
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
attestation: zCompactJwt3
|
|
945
|
+
//#endregion
|
|
946
|
+
//#region src/formats/proof-type/jwt/z-jwt-proof-type.ts
|
|
947
|
+
const zJwtProofTypeIdentifier = z.literal("jwt");
|
|
948
|
+
const jwtProofTypeIdentifier = zJwtProofTypeIdentifier.value;
|
|
949
|
+
const zCredentialRequestProofJwt = z.object({
|
|
950
|
+
proof_type: zJwtProofTypeIdentifier,
|
|
951
|
+
jwt: zCompactJwt
|
|
1289
952
|
});
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
953
|
+
const zCredentialRequestJwtProofTypeHeader = zJwtHeader.merge(z.object({
|
|
954
|
+
key_attestation: z.optional(zCompactJwt),
|
|
955
|
+
typ: z.literal("openid4vci-proof+jwt")
|
|
956
|
+
})).passthrough().refine(({ kid, jwk }) => jwk === void 0 || kid === void 0, { message: `Both 'jwk' and 'kid' are defined. Only one is allowed` }).refine(({ trust_chain, kid }) => !trust_chain || !kid, { message: `When 'trust_chain' is provided, 'kid' is required` });
|
|
957
|
+
const zCredentialRequestJwtProofTypePayload = z.object({
|
|
958
|
+
...zJwtPayload.shape,
|
|
959
|
+
aud: zHttpsUrl,
|
|
960
|
+
iat: zInteger
|
|
1295
961
|
}).passthrough();
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
]
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
var zCredentialRequestCommon = z16.object({
|
|
1307
|
-
proof: zCredentialRequestProof.optional(),
|
|
1308
|
-
proofs: z16.optional(
|
|
1309
|
-
z16.intersection(zCredentialRequestProofsCommon, zCredentialRequestProofs).refine((proofs) => Object.values(proofs).length === 1, {
|
|
1310
|
-
message: `The 'proofs' object in a credential request should contain exactly one attribute`
|
|
1311
|
-
})
|
|
1312
|
-
),
|
|
1313
|
-
credential_response_encryption: z16.object({
|
|
1314
|
-
jwk: zJwk2,
|
|
1315
|
-
alg: z16.string(),
|
|
1316
|
-
enc: z16.string()
|
|
1317
|
-
}).passthrough().optional()
|
|
1318
|
-
}).passthrough().refine(({ proof, proofs }) => !(proof !== void 0 && proofs !== void 0), {
|
|
1319
|
-
message: `Both 'proof' and 'proofs' are defined. Only one is allowed`
|
|
962
|
+
|
|
963
|
+
//#endregion
|
|
964
|
+
//#region src/credential-request/z-credential-request-common.ts
|
|
965
|
+
const zCredentialRequestProofCommon = z.object({ proof_type: z.string() }).passthrough();
|
|
966
|
+
const allCredentialRequestProofs = [zCredentialRequestProofJwt, zCredentialRequestProofAttestation];
|
|
967
|
+
const zCredentialRequestProof = z.union([zCredentialRequestProofCommon, z.discriminatedUnion("proof_type", allCredentialRequestProofs)]);
|
|
968
|
+
const zCredentialRequestProofsCommon = z.record(z.string(), z.array(z.unknown()));
|
|
969
|
+
const zCredentialRequestProofs = z.object({
|
|
970
|
+
[zJwtProofTypeIdentifier.value]: z.optional(z.array(zCredentialRequestProofJwt.shape.jwt)),
|
|
971
|
+
[zAttestationProofTypeIdentifier.value]: z.optional(z.array(zCredentialRequestProofAttestation.shape.attestation))
|
|
1320
972
|
});
|
|
973
|
+
const zCredentialRequestCommon = z.object({
|
|
974
|
+
proof: zCredentialRequestProof.optional(),
|
|
975
|
+
proofs: z.optional(z.intersection(zCredentialRequestProofsCommon, zCredentialRequestProofs).refine((proofs) => Object.values(proofs).length === 1, { message: `The 'proofs' object in a credential request should contain exactly one attribute` })),
|
|
976
|
+
credential_response_encryption: z.object({
|
|
977
|
+
jwk: zJwk,
|
|
978
|
+
alg: z.string(),
|
|
979
|
+
enc: z.string()
|
|
980
|
+
}).passthrough().optional()
|
|
981
|
+
}).passthrough().refine(({ proof, proofs }) => !(proof !== void 0 && proofs !== void 0), { message: `Both 'proof' and 'proofs' are defined. Only one is allowed` });
|
|
1321
982
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
983
|
+
//#endregion
|
|
984
|
+
//#region src/credential-request/z-credential-request.ts
|
|
985
|
+
const allCredentialRequestFormats = [
|
|
986
|
+
zSdJwtW3VcCredentialRequestFormatDraft14,
|
|
987
|
+
zMsoMdocCredentialRequestFormatDraft14,
|
|
988
|
+
zLdpVcCredentialRequestFormatDraft14,
|
|
989
|
+
zJwtVcJsonLdCredentialRequestFormatDraft14,
|
|
990
|
+
zJwtVcJsonCredentialRequestFormatDraft14,
|
|
991
|
+
zLegacySdJwtVcCredentialRequestFormatDraft14
|
|
1330
992
|
];
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
)
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
format: z17.never({ message: "'format' cannot be defined when 'credential_configuration_id' is set." }).optional(),
|
|
1337
|
-
credential_identifier: z17.never({ message: "'credential_identifier' cannot be defined when 'credential_configuration_id' is set." }).optional()
|
|
993
|
+
const allCredentialRequestFormatIdentifiers = allCredentialRequestFormats.map((format) => format.shape.format.value);
|
|
994
|
+
const zCredentialRequestCredentialConfigurationId = z.object({
|
|
995
|
+
credential_configuration_id: z.string(),
|
|
996
|
+
format: z.never({ message: "'format' cannot be defined when 'credential_configuration_id' is set." }).optional(),
|
|
997
|
+
credential_identifier: z.never({ message: "'credential_identifier' cannot be defined when 'credential_configuration_id' is set." }).optional()
|
|
1338
998
|
});
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
format: z17.never({ message: "'format' cannot be defined when 'credential_identifier' is set." }).optional()
|
|
999
|
+
const zAuthorizationDetailsCredentialRequest = z.object({
|
|
1000
|
+
credential_identifier: z.string(),
|
|
1001
|
+
credential_configuration_id: z.never({ message: "'credential_configuration_id' cannot be defined when 'credential_identifier' is set." }).optional(),
|
|
1002
|
+
format: z.never({ message: "'format' cannot be defined when 'credential_identifier' is set." }).optional()
|
|
1344
1003
|
});
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1004
|
+
const zCredentialRequestFormat = z.object({
|
|
1005
|
+
format: z.string(),
|
|
1006
|
+
credential_identifier: z.never({ message: "'credential_identifier' cannot be defined when 'format' is set." }).optional(),
|
|
1007
|
+
credential_configuration_id: z.never({ message: "'credential_configuration_id' cannot be defined when 'format' is set." }).optional()
|
|
1349
1008
|
}).passthrough();
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
if (result.success) {
|
|
1357
|
-
return result.data;
|
|
1358
|
-
}
|
|
1359
|
-
for (const issue of result.error.issues) {
|
|
1360
|
-
ctx.addIssue(issue);
|
|
1361
|
-
}
|
|
1362
|
-
return z17.NEVER;
|
|
1009
|
+
const zCredentialRequestDraft14WithFormat = zCredentialRequestCommon.and(zCredentialRequestFormat).transform((data, ctx) => {
|
|
1010
|
+
if (!allCredentialRequestFormatIdentifiers.includes(data.format)) return data;
|
|
1011
|
+
const result = z.object({}).passthrough().and(z.union(allCredentialRequestFormats)).safeParse(data);
|
|
1012
|
+
if (result.success) return result.data;
|
|
1013
|
+
for (const issue of result.error.issues) ctx.addIssue(issue);
|
|
1014
|
+
return z.NEVER;
|
|
1363
1015
|
});
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
};
|
|
1378
|
-
if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
|
|
1379
|
-
const schema = formatSpecificTransformations[data.format];
|
|
1380
|
-
const result = schema.safeParse(data);
|
|
1381
|
-
if (result.success) return result.data;
|
|
1382
|
-
for (const issue of result.error.issues) {
|
|
1383
|
-
ctx.addIssue(issue);
|
|
1384
|
-
}
|
|
1385
|
-
return z17.NEVER;
|
|
1016
|
+
const zCredentialRequestDraft15 = z.union([zCredentialRequestCommon.and(zAuthorizationDetailsCredentialRequest), zCredentialRequestCommon.and(zCredentialRequestCredentialConfigurationId)]);
|
|
1017
|
+
const zCredentialRequestDraft14 = z.union([zCredentialRequestDraft14WithFormat, zCredentialRequestCommon.and(zAuthorizationDetailsCredentialRequest)]);
|
|
1018
|
+
const zCredentialRequestDraft11To14 = zCredentialRequestCommon.and(zCredentialRequestFormat).transform((data, ctx) => {
|
|
1019
|
+
const formatSpecificTransformations = {
|
|
1020
|
+
[zLdpVcFormatIdentifier.value]: zLdpVcCredentialRequestDraft11To14,
|
|
1021
|
+
[zJwtVcJsonFormatIdentifier.value]: zJwtVcJsonCredentialRequestDraft11To14,
|
|
1022
|
+
[zJwtVcJsonLdFormatIdentifier.value]: zJwtVcJsonLdCredentialRequestDraft11To14
|
|
1023
|
+
};
|
|
1024
|
+
if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
|
|
1025
|
+
const result = formatSpecificTransformations[data.format].safeParse(data);
|
|
1026
|
+
if (result.success) return result.data;
|
|
1027
|
+
for (const issue of result.error.issues) ctx.addIssue(issue);
|
|
1028
|
+
return z.NEVER;
|
|
1386
1029
|
}).pipe(zCredentialRequestDraft14);
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
const result = schema.safeParse(data);
|
|
1399
|
-
if (result.success) return result.data;
|
|
1400
|
-
for (const issue of result.error.issues) {
|
|
1401
|
-
ctx.addIssue(issue);
|
|
1402
|
-
}
|
|
1403
|
-
return z17.NEVER;
|
|
1030
|
+
const zCredentialRequestDraft14To11 = zCredentialRequestDraft14.refine((data) => data.credential_identifier === void 0, `'credential_identifier' is not supported in OpenID4VCI draft 11`).transform((data, ctx) => {
|
|
1031
|
+
const formatSpecificTransformations = {
|
|
1032
|
+
[zLdpVcFormatIdentifier.value]: zLdpVcCredentialRequestDraft14To11,
|
|
1033
|
+
[zJwtVcJsonFormatIdentifier.value]: zJwtVcJsonCredentialRequestDraft14To11,
|
|
1034
|
+
[zJwtVcJsonLdFormatIdentifier.value]: zJwtVcJsonLdCredentialRequestDraft14To11
|
|
1035
|
+
};
|
|
1036
|
+
if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
|
|
1037
|
+
const result = formatSpecificTransformations[data.format].safeParse(data);
|
|
1038
|
+
if (result.success) return result.data;
|
|
1039
|
+
for (const issue of result.error.issues) ctx.addIssue(issue);
|
|
1040
|
+
return z.NEVER;
|
|
1404
1041
|
});
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1042
|
+
const zCredentialRequest = z.union([
|
|
1043
|
+
zCredentialRequestDraft15,
|
|
1044
|
+
zCredentialRequestDraft14,
|
|
1045
|
+
zCredentialRequestDraft11To14
|
|
1409
1046
|
]);
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1047
|
+
const zDeferredCredentialRequest = z.object({
|
|
1048
|
+
transaction_id: z.string().nonempty(),
|
|
1049
|
+
credential_response_encryption: z.object({
|
|
1050
|
+
jwk: zJwk,
|
|
1051
|
+
alg: z.string(),
|
|
1052
|
+
enc: z.string()
|
|
1053
|
+
}).passthrough().optional()
|
|
1417
1054
|
});
|
|
1418
1055
|
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
error: z18.union([z18.nativeEnum(Oauth2ErrorCodes), z18.string()]),
|
|
1465
|
-
error_description: z18.string().optional(),
|
|
1466
|
-
error_uri: z18.string().optional()
|
|
1056
|
+
//#endregion
|
|
1057
|
+
//#region ../oauth2/src/common/z-oauth2-error.ts
|
|
1058
|
+
let Oauth2ErrorCodes$1 = /* @__PURE__ */ function(Oauth2ErrorCodes$2) {
|
|
1059
|
+
Oauth2ErrorCodes$2["ServerError"] = "server_error";
|
|
1060
|
+
Oauth2ErrorCodes$2["InvalidTarget"] = "invalid_target";
|
|
1061
|
+
Oauth2ErrorCodes$2["InvalidRequest"] = "invalid_request";
|
|
1062
|
+
Oauth2ErrorCodes$2["InvalidToken"] = "invalid_token";
|
|
1063
|
+
Oauth2ErrorCodes$2["InsufficientScope"] = "insufficient_scope";
|
|
1064
|
+
Oauth2ErrorCodes$2["InvalidGrant"] = "invalid_grant";
|
|
1065
|
+
Oauth2ErrorCodes$2["InvalidClient"] = "invalid_client";
|
|
1066
|
+
Oauth2ErrorCodes$2["UnauthorizedClient"] = "unauthorized_client";
|
|
1067
|
+
Oauth2ErrorCodes$2["UnsupportedGrantType"] = "unsupported_grant_type";
|
|
1068
|
+
Oauth2ErrorCodes$2["InvalidScope"] = "invalid_scope";
|
|
1069
|
+
Oauth2ErrorCodes$2["InvalidDpopProof"] = "invalid_dpop_proof";
|
|
1070
|
+
Oauth2ErrorCodes$2["UseDpopNonce"] = "use_dpop_nonce";
|
|
1071
|
+
Oauth2ErrorCodes$2["RedirectToWeb"] = "redirect_to_web";
|
|
1072
|
+
Oauth2ErrorCodes$2["InvalidSession"] = "invalid_session";
|
|
1073
|
+
Oauth2ErrorCodes$2["InsufficientAuthorization"] = "insufficient_authorization";
|
|
1074
|
+
Oauth2ErrorCodes$2["InvalidCredentialRequest"] = "invalid_credential_request";
|
|
1075
|
+
Oauth2ErrorCodes$2["CredentialRequestDenied"] = "credential_request_denied";
|
|
1076
|
+
Oauth2ErrorCodes$2["InvalidProof"] = "invalid_proof";
|
|
1077
|
+
Oauth2ErrorCodes$2["InvalidNonce"] = "invalid_nonce";
|
|
1078
|
+
Oauth2ErrorCodes$2["InvalidEncryptionParameters"] = "invalid_encryption_parameters";
|
|
1079
|
+
Oauth2ErrorCodes$2["UnknownCredentialConfiguration"] = "unknown_credential_configuration";
|
|
1080
|
+
Oauth2ErrorCodes$2["UnknownCredentialIdentifier"] = "unknown_credential_identifier";
|
|
1081
|
+
Oauth2ErrorCodes$2["InvalidTransactionId"] = "invalid_transaction_id";
|
|
1082
|
+
Oauth2ErrorCodes$2["UnsupportedCredentialType"] = "unsupported_credential_type";
|
|
1083
|
+
Oauth2ErrorCodes$2["UnsupportedCredentialFormat"] = "unsupported_credential_format";
|
|
1084
|
+
Oauth2ErrorCodes$2["InvalidRequestUri"] = "invalid_request_uri";
|
|
1085
|
+
Oauth2ErrorCodes$2["InvalidRequestObject"] = "invalid_request_object";
|
|
1086
|
+
Oauth2ErrorCodes$2["RequestNotSupported"] = "request_not_supported";
|
|
1087
|
+
Oauth2ErrorCodes$2["RequestUriNotSupported"] = "request_uri_not_supported";
|
|
1088
|
+
Oauth2ErrorCodes$2["VpFormatsNotSupported"] = "vp_formats_not_supported";
|
|
1089
|
+
Oauth2ErrorCodes$2["AccessDenied"] = "access_denied";
|
|
1090
|
+
Oauth2ErrorCodes$2["InvalidPresentationDefinitionUri"] = "invalid_presentation_definition_uri";
|
|
1091
|
+
Oauth2ErrorCodes$2["InvalidPresentationDefinitionReference"] = "invalid_presentation_definition_reference";
|
|
1092
|
+
Oauth2ErrorCodes$2["InvalidRequestUriMethod"] = "invalid_request_uri_method";
|
|
1093
|
+
Oauth2ErrorCodes$2["InvalidTransactionData"] = "invalid_transaction_data";
|
|
1094
|
+
Oauth2ErrorCodes$2["WalletUnavailable"] = "wallet_unavailable";
|
|
1095
|
+
return Oauth2ErrorCodes$2;
|
|
1096
|
+
}({});
|
|
1097
|
+
const zOauth2ErrorResponse = z.object({
|
|
1098
|
+
error: z.union([z.nativeEnum(Oauth2ErrorCodes$1), z.string()]),
|
|
1099
|
+
error_description: z.string().optional(),
|
|
1100
|
+
error_uri: z.string().optional()
|
|
1467
1101
|
}).passthrough();
|
|
1468
1102
|
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
z19.array(zCredentialEncoding)
|
|
1477
|
-
]).optional(),
|
|
1478
|
-
interval: z19.number().int().positive().optional(),
|
|
1479
|
-
notification_id: z19.string().optional()
|
|
1103
|
+
//#endregion
|
|
1104
|
+
//#region src/credential-request/z-credential-response.ts
|
|
1105
|
+
const zCredentialEncoding = z.union([z.string(), z.record(z.string(), z.any())]);
|
|
1106
|
+
const zBaseCredentialResponse = z.object({
|
|
1107
|
+
credentials: z.union([z.array(z.object({ credential: zCredentialEncoding })), z.array(zCredentialEncoding)]).optional(),
|
|
1108
|
+
interval: z.number().int().positive().optional(),
|
|
1109
|
+
notification_id: z.string().optional()
|
|
1480
1110
|
}).passthrough();
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1111
|
+
const zCredentialResponse = zBaseCredentialResponse.extend({
|
|
1112
|
+
credential: z.optional(zCredentialEncoding),
|
|
1113
|
+
transaction_id: z.string().optional(),
|
|
1114
|
+
c_nonce: z.string().optional(),
|
|
1115
|
+
c_nonce_expires_in: z.number().int().optional()
|
|
1486
1116
|
}).passthrough().superRefine((value, ctx) => {
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
});
|
|
1505
|
-
}
|
|
1117
|
+
const { credential, credentials, transaction_id, interval, notification_id } = value;
|
|
1118
|
+
if ([
|
|
1119
|
+
credential,
|
|
1120
|
+
credentials,
|
|
1121
|
+
transaction_id
|
|
1122
|
+
].filter((i) => i !== void 0).length !== 1) ctx.addIssue({
|
|
1123
|
+
code: z.ZodIssueCode.custom,
|
|
1124
|
+
message: `Exactly one of 'credential', 'credentials', or 'transaction_id' MUST be defined.`
|
|
1125
|
+
});
|
|
1126
|
+
if (transaction_id && !interval) ctx.addIssue({
|
|
1127
|
+
code: z.ZodIssueCode.custom,
|
|
1128
|
+
message: `'interval' MUST be defined when 'transaction_id' is defined.`
|
|
1129
|
+
});
|
|
1130
|
+
if (notification_id && !(credentials || credential)) ctx.addIssue({
|
|
1131
|
+
code: z.ZodIssueCode.custom,
|
|
1132
|
+
message: `'notification_id' MUST NOT be defined when 'credential' or 'credentials' are not defined.`
|
|
1133
|
+
});
|
|
1506
1134
|
});
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1135
|
+
const zCredentialErrorResponse = z.object({
|
|
1136
|
+
...zOauth2ErrorResponse.shape,
|
|
1137
|
+
c_nonce: z.string().optional(),
|
|
1138
|
+
c_nonce_expires_in: z.number().int().optional()
|
|
1511
1139
|
}).passthrough();
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
},
|
|
1517
|
-
{
|
|
1518
|
-
message: `Exactly one of 'credentials' or 'interval' MUST be defined.`
|
|
1519
|
-
}
|
|
1520
|
-
);
|
|
1140
|
+
const zDeferredCredentialResponse = zBaseCredentialResponse.refine((value) => {
|
|
1141
|
+
const { credentials, interval } = value;
|
|
1142
|
+
return [credentials, interval].filter((i) => i !== void 0).length === 1;
|
|
1143
|
+
}, { message: `Exactly one of 'credentials' or 'interval' MUST be defined.` });
|
|
1521
1144
|
|
|
1522
|
-
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/credential-request/retrieve-credentials.ts
|
|
1523
1147
|
async function retrieveCredentialsWithCredentialConfigurationId(options) {
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
return retrieveCredentials({
|
|
1540
|
-
callbacks: options.callbacks,
|
|
1541
|
-
credentialRequest,
|
|
1542
|
-
issuerMetadata: options.issuerMetadata,
|
|
1543
|
-
accessToken: options.accessToken,
|
|
1544
|
-
dpop: options.dpop
|
|
1545
|
-
});
|
|
1148
|
+
if (options.issuerMetadata.originalDraftVersion !== Openid4vciDraftVersion.Draft15 && options.issuerMetadata.originalDraftVersion !== Openid4vciDraftVersion.Draft16) throw new Openid4vciError("Requesting credentials based on credential configuration ID is not supported in OpenID4VCI below draft 15. Make sure to provide the format and format specific claims in the request.");
|
|
1149
|
+
getCredentialConfigurationSupportedById(options.issuerMetadata.credentialIssuer.credential_configurations_supported, options.credentialConfigurationId);
|
|
1150
|
+
const credentialRequest = {
|
|
1151
|
+
...options.additionalRequestPayload,
|
|
1152
|
+
credential_configuration_id: options.credentialConfigurationId,
|
|
1153
|
+
proof: options.proof,
|
|
1154
|
+
proofs: options.proofs
|
|
1155
|
+
};
|
|
1156
|
+
return retrieveCredentials({
|
|
1157
|
+
callbacks: options.callbacks,
|
|
1158
|
+
credentialRequest,
|
|
1159
|
+
issuerMetadata: options.issuerMetadata,
|
|
1160
|
+
accessToken: options.accessToken,
|
|
1161
|
+
dpop: options.dpop
|
|
1162
|
+
});
|
|
1546
1163
|
}
|
|
1547
1164
|
async function retrieveCredentialsWithFormat(options) {
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
issuerMetadata: options.issuerMetadata,
|
|
1563
|
-
accessToken: options.accessToken,
|
|
1564
|
-
dpop: options.dpop
|
|
1565
|
-
});
|
|
1165
|
+
if (options.issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft15 || options.issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft16) throw new Openid4vciError("Requesting credentials based on format is not supported in OpenID4VCI draft 15. Provide the credential configuration id directly in the request.");
|
|
1166
|
+
const credentialRequest = {
|
|
1167
|
+
...options.formatPayload,
|
|
1168
|
+
...options.additionalRequestPayload,
|
|
1169
|
+
proof: options.proof,
|
|
1170
|
+
proofs: options.proofs
|
|
1171
|
+
};
|
|
1172
|
+
return retrieveCredentials({
|
|
1173
|
+
callbacks: options.callbacks,
|
|
1174
|
+
credentialRequest,
|
|
1175
|
+
issuerMetadata: options.issuerMetadata,
|
|
1176
|
+
accessToken: options.accessToken,
|
|
1177
|
+
dpop: options.dpop
|
|
1178
|
+
});
|
|
1566
1179
|
}
|
|
1180
|
+
/**
|
|
1181
|
+
* internal method
|
|
1182
|
+
*/
|
|
1567
1183
|
async function retrieveCredentials(options) {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
body: JSON.stringify(credentialRequest)
|
|
1606
|
-
}
|
|
1607
|
-
});
|
|
1608
|
-
if (!resourceResponse.ok) {
|
|
1609
|
-
const credentialErrorResponseResult = isResponseContentType(ContentType2.Json, resourceResponse.response) ? zCredentialErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1610
|
-
return {
|
|
1611
|
-
...resourceResponse,
|
|
1612
|
-
credentialErrorResponseResult
|
|
1613
|
-
};
|
|
1614
|
-
}
|
|
1615
|
-
const credentialResponseResult = isResponseContentType(ContentType2.Json, resourceResponse.response) ? zCredentialResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1616
|
-
if (!credentialResponseResult?.success) {
|
|
1617
|
-
return {
|
|
1618
|
-
...resourceResponse,
|
|
1619
|
-
ok: false,
|
|
1620
|
-
credentialResponseResult
|
|
1621
|
-
};
|
|
1622
|
-
}
|
|
1623
|
-
return {
|
|
1624
|
-
...resourceResponse,
|
|
1625
|
-
credentialResponse: credentialResponseResult.data
|
|
1626
|
-
};
|
|
1184
|
+
const credentialEndpoint = options.issuerMetadata.credentialIssuer.credential_endpoint;
|
|
1185
|
+
let credentialRequest = parseWithErrorHandling(zCredentialRequest, options.credentialRequest, "Error validating credential request");
|
|
1186
|
+
if (credentialRequest.proofs) {
|
|
1187
|
+
const { batch_credential_issuance } = options.issuerMetadata.credentialIssuer;
|
|
1188
|
+
if (options.issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft11) throw new Oauth2Error(`Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not support batch credential issuance using the 'proofs' request property. Only 'proof' is supported.`);
|
|
1189
|
+
const proofs = Object.values(credentialRequest.proofs)[0];
|
|
1190
|
+
if (proofs.length > (batch_credential_issuance?.batch_size ?? 1)) throw new Oauth2Error(`Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' supports batch issuance, but the max batch size is '${batch_credential_issuance?.batch_size ?? 1}'. A total of '${proofs.length}' proofs were provided.`);
|
|
1191
|
+
}
|
|
1192
|
+
if (options.issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft11) credentialRequest = parseWithErrorHandling(zCredentialRequestDraft14To11, credentialRequest, `Error transforming credential request from ${Openid4vciDraftVersion.Draft14} to ${Openid4vciDraftVersion.Draft11}`);
|
|
1193
|
+
const resourceResponse = await resourceRequest({
|
|
1194
|
+
dpop: options.dpop,
|
|
1195
|
+
accessToken: options.accessToken,
|
|
1196
|
+
callbacks: options.callbacks,
|
|
1197
|
+
url: credentialEndpoint,
|
|
1198
|
+
requestOptions: {
|
|
1199
|
+
method: "POST",
|
|
1200
|
+
headers: { "Content-Type": ContentType.Json },
|
|
1201
|
+
body: JSON.stringify(credentialRequest)
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
if (!resourceResponse.ok) {
|
|
1205
|
+
const credentialErrorResponseResult = isResponseContentType(ContentType.Json, resourceResponse.response) ? zCredentialErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1206
|
+
return {
|
|
1207
|
+
...resourceResponse,
|
|
1208
|
+
credentialErrorResponseResult
|
|
1209
|
+
};
|
|
1210
|
+
}
|
|
1211
|
+
const credentialResponseResult = isResponseContentType(ContentType.Json, resourceResponse.response) ? zCredentialResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1212
|
+
if (!credentialResponseResult?.success) return {
|
|
1213
|
+
...resourceResponse,
|
|
1214
|
+
ok: false,
|
|
1215
|
+
credentialResponseResult
|
|
1216
|
+
};
|
|
1217
|
+
return {
|
|
1218
|
+
...resourceResponse,
|
|
1219
|
+
credentialResponse: credentialResponseResult.data
|
|
1220
|
+
};
|
|
1627
1221
|
}
|
|
1628
1222
|
async function retrieveDeferredCredentials(options) {
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
const deferredCredentialResponseResult = isResponseContentType(ContentType2.Json, resourceResponse.response) ? zDeferredCredentialResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1664
|
-
if (!deferredCredentialResponseResult?.success) {
|
|
1665
|
-
return {
|
|
1666
|
-
...resourceResponse,
|
|
1667
|
-
ok: false,
|
|
1668
|
-
deferredCredentialResponseResult
|
|
1669
|
-
};
|
|
1670
|
-
}
|
|
1671
|
-
return {
|
|
1672
|
-
...resourceResponse,
|
|
1673
|
-
deferredCredentialResponse: deferredCredentialResponseResult.data
|
|
1674
|
-
};
|
|
1223
|
+
const credentialEndpoint = options.issuerMetadata.credentialIssuer.deferred_credential_endpoint;
|
|
1224
|
+
if (!credentialEndpoint) throw new Openid4vciError(`Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not support deferred credential retrieval.`);
|
|
1225
|
+
const deferredCredentialRequest = parseWithErrorHandling(zDeferredCredentialRequest, {
|
|
1226
|
+
transaction_id: options.transactionId,
|
|
1227
|
+
...options.additionalRequestPayload
|
|
1228
|
+
}, "Error validating deferred credential request");
|
|
1229
|
+
const resourceResponse = await resourceRequest({
|
|
1230
|
+
dpop: options.dpop,
|
|
1231
|
+
accessToken: options.accessToken,
|
|
1232
|
+
callbacks: options.callbacks,
|
|
1233
|
+
url: credentialEndpoint,
|
|
1234
|
+
requestOptions: {
|
|
1235
|
+
method: "POST",
|
|
1236
|
+
headers: { "Content-Type": ContentType.Json },
|
|
1237
|
+
body: JSON.stringify(deferredCredentialRequest)
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
if (!resourceResponse.ok) {
|
|
1241
|
+
const deferredCredentialErrorResponseResult = isResponseContentType(ContentType.Json, resourceResponse.response) ? zCredentialErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1242
|
+
return {
|
|
1243
|
+
...resourceResponse,
|
|
1244
|
+
deferredCredentialErrorResponseResult
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
const deferredCredentialResponseResult = isResponseContentType(ContentType.Json, resourceResponse.response) ? zDeferredCredentialResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1248
|
+
if (!deferredCredentialResponseResult?.success) return {
|
|
1249
|
+
...resourceResponse,
|
|
1250
|
+
ok: false,
|
|
1251
|
+
deferredCredentialResponseResult
|
|
1252
|
+
};
|
|
1253
|
+
return {
|
|
1254
|
+
...resourceResponse,
|
|
1255
|
+
deferredCredentialResponse: deferredCredentialResponseResult.data
|
|
1256
|
+
};
|
|
1675
1257
|
}
|
|
1676
1258
|
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
import { jwtSignerFromJwt as jwtSignerFromJwt2, verifyJwt as verifyJwt2 } from "@openid4vc/oauth2";
|
|
1680
|
-
import { dateToSeconds as dateToSeconds2, parseWithErrorHandling as parseWithErrorHandling4 } from "@openid4vc/utils";
|
|
1259
|
+
//#endregion
|
|
1260
|
+
//#region src/formats/proof-type/jwt/jwt-proof-type.ts
|
|
1681
1261
|
async function createCredentialRequestJwtProof(options) {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
return jwt;
|
|
1262
|
+
const header = parseWithErrorHandling(zCredentialRequestJwtProofTypeHeader, {
|
|
1263
|
+
...jwtHeaderFromJwtSigner(options.signer),
|
|
1264
|
+
key_attestation: options.keyAttestationJwt,
|
|
1265
|
+
typ: "openid4vci-proof+jwt"
|
|
1266
|
+
});
|
|
1267
|
+
const payload = parseWithErrorHandling(zCredentialRequestJwtProofTypePayload, {
|
|
1268
|
+
nonce: options.nonce,
|
|
1269
|
+
aud: options.credentialIssuer,
|
|
1270
|
+
iat: dateToSeconds(options.issuedAt),
|
|
1271
|
+
iss: options.clientId
|
|
1272
|
+
});
|
|
1273
|
+
const { jwt, signerJwk } = await options.callbacks.signJwt(options.signer, {
|
|
1274
|
+
header,
|
|
1275
|
+
payload
|
|
1276
|
+
});
|
|
1277
|
+
if (options.keyAttestationJwt) {
|
|
1278
|
+
if (!await isJwkInSet({
|
|
1279
|
+
jwk: signerJwk,
|
|
1280
|
+
jwks: decodeJwt({
|
|
1281
|
+
jwt: options.keyAttestationJwt,
|
|
1282
|
+
headerSchema: zKeyAttestationJwtHeader,
|
|
1283
|
+
payloadSchema: zKeyAttestationJwtPayload
|
|
1284
|
+
}).payload.attested_keys,
|
|
1285
|
+
callbacks: options.callbacks
|
|
1286
|
+
})) throw new Openid4vciError(`Credential request jwt proof is not signed with a key in the 'key_attestation' jwt payload 'attested_keys'`);
|
|
1287
|
+
}
|
|
1288
|
+
return jwt;
|
|
1712
1289
|
}
|
|
1713
1290
|
async function verifyCredentialRequestJwtProof(options) {
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
payload,
|
|
1756
|
-
signer,
|
|
1757
|
-
keyAttestation: keyAttestationResult
|
|
1758
|
-
};
|
|
1291
|
+
const { header, payload } = decodeJwt({
|
|
1292
|
+
jwt: options.jwt,
|
|
1293
|
+
headerSchema: zCredentialRequestJwtProofTypeHeader,
|
|
1294
|
+
payloadSchema: zCredentialRequestJwtProofTypePayload
|
|
1295
|
+
});
|
|
1296
|
+
const now = options.now?.getTime() ?? Date.now();
|
|
1297
|
+
if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) throw new Openid4vciError("Nonce used for credential request proof expired");
|
|
1298
|
+
const { signer } = await verifyJwt({
|
|
1299
|
+
compact: options.jwt,
|
|
1300
|
+
header,
|
|
1301
|
+
payload,
|
|
1302
|
+
signer: jwtSignerFromJwt({
|
|
1303
|
+
header,
|
|
1304
|
+
payload
|
|
1305
|
+
}),
|
|
1306
|
+
verifyJwtCallback: options.callbacks.verifyJwt,
|
|
1307
|
+
errorMessage: "Error verifiying credential request proof jwt.",
|
|
1308
|
+
expectedNonce: options.expectedNonce,
|
|
1309
|
+
expectedAudience: options.credentialIssuer,
|
|
1310
|
+
expectedIssuer: options.clientId,
|
|
1311
|
+
now: options.now
|
|
1312
|
+
});
|
|
1313
|
+
let keyAttestationResult;
|
|
1314
|
+
if (header.key_attestation) {
|
|
1315
|
+
keyAttestationResult = await verifyKeyAttestationJwt({
|
|
1316
|
+
callbacks: options.callbacks,
|
|
1317
|
+
keyAttestationJwt: header.key_attestation,
|
|
1318
|
+
use: "proof_type.jwt"
|
|
1319
|
+
});
|
|
1320
|
+
if (!await isJwkInSet({
|
|
1321
|
+
jwk: signer.publicJwk,
|
|
1322
|
+
jwks: keyAttestationResult.payload.attested_keys,
|
|
1323
|
+
callbacks: options.callbacks
|
|
1324
|
+
})) throw new Openid4vciError(`Credential request jwt proof is not signed with a key in the 'key_attestation' jwt payload 'attested_keys'`);
|
|
1325
|
+
}
|
|
1326
|
+
return {
|
|
1327
|
+
header,
|
|
1328
|
+
payload,
|
|
1329
|
+
signer,
|
|
1330
|
+
keyAttestation: keyAttestationResult
|
|
1331
|
+
};
|
|
1759
1332
|
}
|
|
1760
1333
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
Oauth2Error as Oauth2Error5,
|
|
1764
|
-
fetchAuthorizationServerMetadata,
|
|
1765
|
-
zAuthorizationServerMetadata
|
|
1766
|
-
} from "@openid4vc/oauth2";
|
|
1767
|
-
import { parseWithErrorHandling as parseWithErrorHandling5 } from "@openid4vc/utils";
|
|
1334
|
+
//#endregion
|
|
1335
|
+
//#region src/metadata/fetch-issuer-metadata.ts
|
|
1768
1336
|
async function resolveIssuerMetadata(credentialIssuer, options) {
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
);
|
|
1791
|
-
}
|
|
1792
|
-
if (!authorizationServerMetadata) {
|
|
1793
|
-
throw new Oauth2Error5(
|
|
1794
|
-
`Well known openid configuration or authorization server metadata for authorization server '${authorizationServer}' not found.`
|
|
1795
|
-
);
|
|
1796
|
-
}
|
|
1797
|
-
authoriationServersMetadata.push(authorizationServerMetadata);
|
|
1798
|
-
}
|
|
1799
|
-
return {
|
|
1800
|
-
originalDraftVersion,
|
|
1801
|
-
credentialIssuer: credentialIssuerMetadata,
|
|
1802
|
-
authorizationServers: authoriationServersMetadata
|
|
1803
|
-
};
|
|
1337
|
+
const allowAuthorizationMetadataFromCredentialIssuerMetadata = options?.allowAuthorizationMetadataFromCredentialIssuerMetadata ?? true;
|
|
1338
|
+
const credentialIssuerMetadataWithDraftVersion = await fetchCredentialIssuerMetadata(credentialIssuer, options?.fetch);
|
|
1339
|
+
if (!credentialIssuerMetadataWithDraftVersion) throw new Oauth2Error(`Well known credential issuer metadata for issuer '${credentialIssuer}' not found.`);
|
|
1340
|
+
const { credentialIssuerMetadata, originalDraftVersion } = credentialIssuerMetadataWithDraftVersion;
|
|
1341
|
+
const authorizationServers = credentialIssuerMetadata.authorization_servers ?? [credentialIssuer];
|
|
1342
|
+
const authoriationServersMetadata = [];
|
|
1343
|
+
for (const authorizationServer of authorizationServers) {
|
|
1344
|
+
if (options?.restrictToAuthorizationServers && !options.restrictToAuthorizationServers.includes(authorizationServer)) continue;
|
|
1345
|
+
let authorizationServerMetadata = await fetchAuthorizationServerMetadata(authorizationServer, options?.fetch);
|
|
1346
|
+
if (!authorizationServerMetadata && authorizationServer === credentialIssuer && allowAuthorizationMetadataFromCredentialIssuerMetadata) authorizationServerMetadata = parseWithErrorHandling(zAuthorizationServerMetadata, {
|
|
1347
|
+
token_endpoint: credentialIssuerMetadata.token_endpoint,
|
|
1348
|
+
issuer: credentialIssuer
|
|
1349
|
+
}, `Well known authorization server metadata for authorization server '${authorizationServer}' not found, and could also not extract required values from the credential issuer metadata as a fallback.`);
|
|
1350
|
+
if (!authorizationServerMetadata) throw new Oauth2Error(`Well known openid configuration or authorization server metadata for authorization server '${authorizationServer}' not found.`);
|
|
1351
|
+
authoriationServersMetadata.push(authorizationServerMetadata);
|
|
1352
|
+
}
|
|
1353
|
+
return {
|
|
1354
|
+
originalDraftVersion,
|
|
1355
|
+
credentialIssuer: credentialIssuerMetadata,
|
|
1356
|
+
authorizationServers: authoriationServersMetadata
|
|
1357
|
+
};
|
|
1804
1358
|
}
|
|
1805
1359
|
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
import { zInteger as zInteger3 } from "@openid4vc/utils";
|
|
1812
|
-
import z20 from "zod";
|
|
1813
|
-
var zNonceResponse = z20.object({
|
|
1814
|
-
c_nonce: z20.string(),
|
|
1815
|
-
c_nonce_expires_in: z20.optional(zInteger3)
|
|
1360
|
+
//#endregion
|
|
1361
|
+
//#region src/nonce/z-nonce.ts
|
|
1362
|
+
const zNonceResponse = z.object({
|
|
1363
|
+
c_nonce: z.string(),
|
|
1364
|
+
c_nonce_expires_in: z.optional(zInteger)
|
|
1816
1365
|
}).passthrough();
|
|
1817
1366
|
|
|
1818
|
-
|
|
1367
|
+
//#endregion
|
|
1368
|
+
//#region src/nonce/nonce-request.ts
|
|
1369
|
+
/**
|
|
1370
|
+
* Request a nonce from the `nonce_endpoint`
|
|
1371
|
+
*
|
|
1372
|
+
* @throws Openid4vciError - if no `nonce_endpoint` is configured in the issuer metadata
|
|
1373
|
+
* @throws InvalidFetchResponseError - if the nonce endpoint did not return a successful response
|
|
1374
|
+
* @throws ValidationError - if validating the nonce response failed
|
|
1375
|
+
*/
|
|
1819
1376
|
async function requestNonce(options) {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
const { response, result } = await fetchWithZod(zNonceResponse, ContentType3.Json, nonceEndpoint, {
|
|
1828
|
-
method: "POST"
|
|
1829
|
-
});
|
|
1830
|
-
if (!response.ok || !result) {
|
|
1831
|
-
throw new InvalidFetchResponseError2(
|
|
1832
|
-
`Requesting nonce from '${nonceEndpoint}' resulted in an unsuccessful response with status '${response.status}'`,
|
|
1833
|
-
await response.clone().text(),
|
|
1834
|
-
response
|
|
1835
|
-
);
|
|
1836
|
-
}
|
|
1837
|
-
if (!result.success) {
|
|
1838
|
-
throw new ValidationError3("Error parsing nonce response", result.error);
|
|
1839
|
-
}
|
|
1840
|
-
return result.data;
|
|
1377
|
+
const fetchWithZod = createZodFetcher(options?.fetch);
|
|
1378
|
+
const nonceEndpoint = options.issuerMetadata.credentialIssuer.nonce_endpoint;
|
|
1379
|
+
if (!nonceEndpoint) throw new Openid4vciError(`Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not have a nonce endpoint.`);
|
|
1380
|
+
const { response, result } = await fetchWithZod(zNonceResponse, ContentType.Json, nonceEndpoint, { method: "POST" });
|
|
1381
|
+
if (!response.ok || !result) throw new InvalidFetchResponseError(`Requesting nonce from '${nonceEndpoint}' resulted in an unsuccessful response with status '${response.status}'`, await response.clone().text(), response);
|
|
1382
|
+
if (!result.success) throw new ValidationError("Error parsing nonce response", result.error);
|
|
1383
|
+
return result.data;
|
|
1841
1384
|
}
|
|
1842
1385
|
function createNonceResponse(options) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1386
|
+
return parseWithErrorHandling(zNonceResponse, {
|
|
1387
|
+
c_nonce: options.cNonce,
|
|
1388
|
+
c_nonce_expires_in: options.cNonceExpiresIn,
|
|
1389
|
+
...options.additionalPayload
|
|
1390
|
+
});
|
|
1848
1391
|
}
|
|
1849
1392
|
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
notification_id: z21.string(),
|
|
1862
|
-
event: zNotificationEvent,
|
|
1863
|
-
event_description: z21.optional(z21.string())
|
|
1864
|
-
}).passthrough();
|
|
1865
|
-
var zNotificationErrorResponse = z21.object({
|
|
1866
|
-
error: z21.enum(["invalid_notification_id", "invalid_notification_request"])
|
|
1393
|
+
//#endregion
|
|
1394
|
+
//#region src/notification/z-notification.ts
|
|
1395
|
+
const zNotificationEvent = z.enum([
|
|
1396
|
+
"credential_accepted",
|
|
1397
|
+
"credential_failure",
|
|
1398
|
+
"credential_deleted"
|
|
1399
|
+
]);
|
|
1400
|
+
const zNotificationRequest = z.object({
|
|
1401
|
+
notification_id: z.string(),
|
|
1402
|
+
event: zNotificationEvent,
|
|
1403
|
+
event_description: z.optional(z.string())
|
|
1867
1404
|
}).passthrough();
|
|
1405
|
+
const zNotificationErrorResponse = z.object({ error: z.enum(["invalid_notification_id", "invalid_notification_request"]) }).passthrough();
|
|
1868
1406
|
|
|
1869
|
-
|
|
1407
|
+
//#endregion
|
|
1408
|
+
//#region src/notification/notification.ts
|
|
1870
1409
|
async function sendNotification(options) {
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
}
|
|
1898
|
-
});
|
|
1899
|
-
if (!resourceResponse.ok) {
|
|
1900
|
-
const notificationErrorResponseResult = isResponseContentType2(ContentType4.Json, resourceResponse.response) ? zNotificationErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1901
|
-
return {
|
|
1902
|
-
...resourceResponse,
|
|
1903
|
-
notificationErrorResponseResult
|
|
1904
|
-
};
|
|
1905
|
-
}
|
|
1906
|
-
return resourceResponse;
|
|
1410
|
+
const notificationEndpoint = options.issuerMetadata.credentialIssuer.notification_endpoint;
|
|
1411
|
+
if (!notificationEndpoint) throw new Oauth2Error(`Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not have a notification endpiont configured.`);
|
|
1412
|
+
const notificationRequest = parseWithErrorHandling(zNotificationRequest, {
|
|
1413
|
+
event: options.notification.event,
|
|
1414
|
+
notification_id: options.notification.notificationId,
|
|
1415
|
+
event_description: options.notification.eventDescription
|
|
1416
|
+
}, "Error validating notification request");
|
|
1417
|
+
const resourceResponse = await resourceRequest({
|
|
1418
|
+
dpop: options.dpop,
|
|
1419
|
+
accessToken: options.accessToken,
|
|
1420
|
+
callbacks: options.callbacks,
|
|
1421
|
+
url: notificationEndpoint,
|
|
1422
|
+
requestOptions: {
|
|
1423
|
+
method: "POST",
|
|
1424
|
+
headers: { "Content-Type": ContentType.Json },
|
|
1425
|
+
body: JSON.stringify(notificationRequest)
|
|
1426
|
+
}
|
|
1427
|
+
});
|
|
1428
|
+
if (!resourceResponse.ok) {
|
|
1429
|
+
const notificationErrorResponseResult = isResponseContentType(ContentType.Json, resourceResponse.response) ? zNotificationErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
|
|
1430
|
+
return {
|
|
1431
|
+
...resourceResponse,
|
|
1432
|
+
notificationErrorResponseResult
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
return resourceResponse;
|
|
1907
1436
|
}
|
|
1908
1437
|
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1438
|
+
//#endregion
|
|
1439
|
+
//#region src/Openid4vciClient.ts
|
|
1440
|
+
let AuthorizationFlow = /* @__PURE__ */ function(AuthorizationFlow$1) {
|
|
1441
|
+
AuthorizationFlow$1["Oauth2Redirect"] = "Oauth2Redirect";
|
|
1442
|
+
AuthorizationFlow$1["PresentationDuringIssuance"] = "PresentationDuringIssuance";
|
|
1443
|
+
return AuthorizationFlow$1;
|
|
1444
|
+
}({});
|
|
1915
1445
|
var Openid4vciClient = class {
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
);
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
const jwt = await createCredentialRequestJwtProof({
|
|
2193
|
-
credentialIssuer: options.issuerMetadata.credentialIssuer.credential_issuer,
|
|
2194
|
-
signer: options.signer,
|
|
2195
|
-
clientId: options.clientId,
|
|
2196
|
-
issuedAt: options.issuedAt,
|
|
2197
|
-
nonce: options.nonce,
|
|
2198
|
-
keyAttestationJwt: options.keyAttestationJwt,
|
|
2199
|
-
callbacks: this.options.callbacks
|
|
2200
|
-
});
|
|
2201
|
-
return {
|
|
2202
|
-
jwt
|
|
2203
|
-
};
|
|
2204
|
-
}
|
|
2205
|
-
/**
|
|
2206
|
-
* @throws Openid4vciRetrieveCredentialsError - if an unsuccessful response or the response couldn't be parsed as credential response
|
|
2207
|
-
* @throws ValidationError - if validation of the credential request failed
|
|
2208
|
-
* @throws Openid4vciError - if the `credentialConfigurationId` couldn't be found, or if the the format specific request couldn't be constructed
|
|
2209
|
-
*/
|
|
2210
|
-
async retrieveCredentials({
|
|
2211
|
-
issuerMetadata,
|
|
2212
|
-
proof,
|
|
2213
|
-
proofs,
|
|
2214
|
-
credentialConfigurationId,
|
|
2215
|
-
additionalRequestPayload,
|
|
2216
|
-
accessToken,
|
|
2217
|
-
dpop
|
|
2218
|
-
}) {
|
|
2219
|
-
let credentialResponse;
|
|
2220
|
-
if (issuerMetadata.originalDraftVersion === "Draft15" /* Draft15 */ || issuerMetadata.originalDraftVersion === "Draft16" /* Draft16 */) {
|
|
2221
|
-
credentialResponse = await retrieveCredentialsWithCredentialConfigurationId({
|
|
2222
|
-
accessToken,
|
|
2223
|
-
credentialConfigurationId,
|
|
2224
|
-
issuerMetadata,
|
|
2225
|
-
additionalRequestPayload,
|
|
2226
|
-
proof,
|
|
2227
|
-
proofs,
|
|
2228
|
-
callbacks: this.options.callbacks,
|
|
2229
|
-
dpop
|
|
2230
|
-
});
|
|
2231
|
-
} else {
|
|
2232
|
-
const formatPayload = getCredentialRequestFormatPayloadForCredentialConfigurationId({
|
|
2233
|
-
credentialConfigurationId,
|
|
2234
|
-
issuerMetadata
|
|
2235
|
-
});
|
|
2236
|
-
credentialResponse = await retrieveCredentialsWithFormat({
|
|
2237
|
-
accessToken,
|
|
2238
|
-
formatPayload,
|
|
2239
|
-
issuerMetadata,
|
|
2240
|
-
additionalRequestPayload,
|
|
2241
|
-
proof,
|
|
2242
|
-
proofs,
|
|
2243
|
-
callbacks: this.options.callbacks,
|
|
2244
|
-
dpop
|
|
2245
|
-
});
|
|
2246
|
-
}
|
|
2247
|
-
if (!credentialResponse.ok) {
|
|
2248
|
-
throw new Openid4vciRetrieveCredentialsError(
|
|
2249
|
-
`Error retrieving credentials from '${issuerMetadata.credentialIssuer.credential_issuer}'`,
|
|
2250
|
-
credentialResponse,
|
|
2251
|
-
await credentialResponse.response.clone().text()
|
|
2252
|
-
);
|
|
2253
|
-
}
|
|
2254
|
-
return credentialResponse;
|
|
2255
|
-
}
|
|
2256
|
-
/**
|
|
2257
|
-
* @throws Openid4vciRetrieveCredentialsError - if an unsuccessful response or the response couldn't be parsed as credential response
|
|
2258
|
-
* @throws ValidationError - if validation of the credential request failed
|
|
2259
|
-
*/
|
|
2260
|
-
async retrieveDeferredCredentials(options) {
|
|
2261
|
-
const credentialResponse = await retrieveDeferredCredentials({
|
|
2262
|
-
...options,
|
|
2263
|
-
callbacks: this.options.callbacks
|
|
2264
|
-
});
|
|
2265
|
-
if (!credentialResponse.ok) {
|
|
2266
|
-
throw new Openid4vciRetrieveCredentialsError(
|
|
2267
|
-
`Error retrieving deferred credentials from '${options.issuerMetadata.credentialIssuer.credential_issuer}'`,
|
|
2268
|
-
credentialResponse,
|
|
2269
|
-
await credentialResponse.response.clone().text()
|
|
2270
|
-
);
|
|
2271
|
-
}
|
|
2272
|
-
return credentialResponse;
|
|
2273
|
-
}
|
|
2274
|
-
/**
|
|
2275
|
-
* @throws Openid4vciSendNotificationError - if an unsuccessful response
|
|
2276
|
-
* @throws ValidationError - if validation of the notification request failed
|
|
2277
|
-
*/
|
|
2278
|
-
async sendNotification({
|
|
2279
|
-
issuerMetadata,
|
|
2280
|
-
notification,
|
|
2281
|
-
additionalRequestPayload,
|
|
2282
|
-
accessToken,
|
|
2283
|
-
dpop
|
|
2284
|
-
}) {
|
|
2285
|
-
const notificationResponse = await sendNotification({
|
|
2286
|
-
accessToken,
|
|
2287
|
-
issuerMetadata,
|
|
2288
|
-
additionalRequestPayload,
|
|
2289
|
-
callbacks: this.options.callbacks,
|
|
2290
|
-
dpop,
|
|
2291
|
-
notification
|
|
2292
|
-
});
|
|
2293
|
-
if (!notificationResponse.ok) {
|
|
2294
|
-
throw new Openid4vciSendNotificationError(
|
|
2295
|
-
`Error sending notification to '${issuerMetadata.credentialIssuer.credential_issuer}'`,
|
|
2296
|
-
notificationResponse
|
|
2297
|
-
);
|
|
2298
|
-
}
|
|
2299
|
-
return notificationResponse;
|
|
2300
|
-
}
|
|
1446
|
+
constructor(options) {
|
|
1447
|
+
this.options = options;
|
|
1448
|
+
this.oauth2Client = new Oauth2Client({ callbacks: this.options.callbacks });
|
|
1449
|
+
}
|
|
1450
|
+
getKnownCredentialConfigurationsSupported(credentialIssuerMetadata) {
|
|
1451
|
+
return extractKnownCredentialConfigurationSupportedFormats(credentialIssuerMetadata.credential_configurations_supported);
|
|
1452
|
+
}
|
|
1453
|
+
/**
|
|
1454
|
+
* Resolve a credential offer into a credential offer object, handling both
|
|
1455
|
+
* 'credential_offer' and 'credential_offer_uri' params.
|
|
1456
|
+
*/
|
|
1457
|
+
async resolveCredentialOffer(credentialOffer) {
|
|
1458
|
+
return resolveCredentialOffer(credentialOffer, { fetch: this.options.callbacks.fetch });
|
|
1459
|
+
}
|
|
1460
|
+
async resolveIssuerMetadata(credentialIssuer) {
|
|
1461
|
+
return resolveIssuerMetadata(credentialIssuer, { fetch: this.options.callbacks.fetch });
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Retrieve an authorization code for a presentation during issuance session
|
|
1465
|
+
*
|
|
1466
|
+
* This can only be called if an authorization challenge was performed before and returned a
|
|
1467
|
+
* `presentation` parameter along with an `auth_session`. If the presentation response included
|
|
1468
|
+
* an `presentation_during_issuance_session` parameter it MUST be included in this request as well.
|
|
1469
|
+
*/
|
|
1470
|
+
async retrieveAuthorizationCodeUsingPresentation(options) {
|
|
1471
|
+
if (!options.credentialOffer.grants?.[authorizationCodeGrantIdentifier]) throw new Oauth2Error(`Provided credential offer does not include the 'authorization_code' grant.`);
|
|
1472
|
+
const authorizationCodeGrant = options.credentialOffer.grants[authorizationCodeGrantIdentifier];
|
|
1473
|
+
const authorizationServer = determineAuthorizationServerForCredentialOffer({
|
|
1474
|
+
issuerMetadata: options.issuerMetadata,
|
|
1475
|
+
grantAuthorizationServer: authorizationCodeGrant.authorization_server
|
|
1476
|
+
});
|
|
1477
|
+
const authorizationServerMetadata = getAuthorizationServerMetadataFromList(options.issuerMetadata.authorizationServers, authorizationServer);
|
|
1478
|
+
const { authorizationChallengeResponse, dpop } = await new Oauth2Client({ callbacks: this.options.callbacks }).sendAuthorizationChallengeRequest({
|
|
1479
|
+
authorizationServerMetadata,
|
|
1480
|
+
authSession: options.authSession,
|
|
1481
|
+
presentationDuringIssuanceSession: options.presentationDuringIssuanceSession,
|
|
1482
|
+
dpop: options.dpop
|
|
1483
|
+
});
|
|
1484
|
+
return {
|
|
1485
|
+
authorizationChallengeResponse,
|
|
1486
|
+
dpop
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Initiates authorization for credential issuance. It handles the following cases:
|
|
1491
|
+
* - Authorization Challenge
|
|
1492
|
+
* - Pushed Authorization Request
|
|
1493
|
+
* - Regular Authorization url
|
|
1494
|
+
*
|
|
1495
|
+
* In case the authorization challenge request returns an error with `insufficient_authorization`
|
|
1496
|
+
* with a `presentation` field it means the authorization server expects presentation of credentials
|
|
1497
|
+
* before issuance of credentials. If this is the case, the value in `presentation` should be treated
|
|
1498
|
+
* as an openid4vp authorization request and submitted to the verifier. Once the presentation response
|
|
1499
|
+
* has been submitted, the RP will respond with a `presentation_during_issuance_session` parameter.
|
|
1500
|
+
* Together with the `auth_session` parameter returned in this call you can retrieve an `authorization_code`
|
|
1501
|
+
* using
|
|
1502
|
+
*/
|
|
1503
|
+
async initiateAuthorization(options) {
|
|
1504
|
+
if (!options.credentialOffer.grants?.[authorizationCodeGrantIdentifier]) throw new Oauth2Error(`Provided credential offer does not include the 'authorization_code' grant.`);
|
|
1505
|
+
const authorizationCodeGrant = options.credentialOffer.grants[authorizationCodeGrantIdentifier];
|
|
1506
|
+
const authorizationServer = determineAuthorizationServerForCredentialOffer({
|
|
1507
|
+
issuerMetadata: options.issuerMetadata,
|
|
1508
|
+
grantAuthorizationServer: authorizationCodeGrant.authorization_server
|
|
1509
|
+
});
|
|
1510
|
+
const authorizationServerMetadata = getAuthorizationServerMetadataFromList(options.issuerMetadata.authorizationServers, authorizationServer);
|
|
1511
|
+
const oauth2Client = new Oauth2Client({ callbacks: this.options.callbacks });
|
|
1512
|
+
try {
|
|
1513
|
+
return {
|
|
1514
|
+
...await oauth2Client.initiateAuthorization({
|
|
1515
|
+
clientId: options.clientId,
|
|
1516
|
+
pkceCodeVerifier: options.pkceCodeVerifier,
|
|
1517
|
+
redirectUri: options.redirectUri,
|
|
1518
|
+
scope: options.scope,
|
|
1519
|
+
additionalRequestPayload: {
|
|
1520
|
+
...options.additionalRequestPayload,
|
|
1521
|
+
issuer_state: options.credentialOffer?.grants?.authorization_code?.issuer_state
|
|
1522
|
+
},
|
|
1523
|
+
dpop: options.dpop,
|
|
1524
|
+
resource: options.issuerMetadata.credentialIssuer.credential_issuer,
|
|
1525
|
+
authorizationServerMetadata
|
|
1526
|
+
}),
|
|
1527
|
+
authorizationFlow: AuthorizationFlow.Oauth2Redirect,
|
|
1528
|
+
authorizationServer: authorizationServerMetadata.issuer
|
|
1529
|
+
};
|
|
1530
|
+
} catch (error) {
|
|
1531
|
+
if (error instanceof Oauth2ClientAuthorizationChallengeError && error.errorResponse.error === Oauth2ErrorCodes.InsufficientAuthorization && error.errorResponse.presentation) {
|
|
1532
|
+
if (!error.errorResponse.auth_session) throw new Openid4vciError(`Expected 'auth_session' to be defined with authorization challenge response error '${error.errorResponse.error}' and 'presentation' parameter`);
|
|
1533
|
+
return {
|
|
1534
|
+
authorizationFlow: AuthorizationFlow.PresentationDuringIssuance,
|
|
1535
|
+
openid4vpRequestUrl: error.errorResponse.presentation,
|
|
1536
|
+
authSession: error.errorResponse.auth_session,
|
|
1537
|
+
authorizationServer: authorizationServerMetadata.issuer
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
throw error;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Convenience method around {@link Oauth2Client.createAuthorizationRequestUrl}
|
|
1545
|
+
* but specifically focused on a credential offer
|
|
1546
|
+
*/
|
|
1547
|
+
async createAuthorizationRequestUrlFromOffer(options) {
|
|
1548
|
+
if (!options.credentialOffer.grants?.[authorizationCodeGrantIdentifier]) throw new Oauth2Error(`Provided credential offer does not include the 'authorization_code' grant.`);
|
|
1549
|
+
const authorizationCodeGrant = options.credentialOffer.grants[authorizationCodeGrantIdentifier];
|
|
1550
|
+
const authorizationServer = determineAuthorizationServerForCredentialOffer({
|
|
1551
|
+
issuerMetadata: options.issuerMetadata,
|
|
1552
|
+
grantAuthorizationServer: authorizationCodeGrant.authorization_server
|
|
1553
|
+
});
|
|
1554
|
+
const authorizationServerMetadata = getAuthorizationServerMetadataFromList(options.issuerMetadata.authorizationServers, authorizationServer);
|
|
1555
|
+
const { authorizationRequestUrl, pkce, dpop } = await this.oauth2Client.createAuthorizationRequestUrl({
|
|
1556
|
+
authorizationServerMetadata,
|
|
1557
|
+
clientId: options.clientId,
|
|
1558
|
+
additionalRequestPayload: {
|
|
1559
|
+
...options.additionalRequestPayload,
|
|
1560
|
+
issuer_state: options.credentialOffer?.grants?.authorization_code?.issuer_state
|
|
1561
|
+
},
|
|
1562
|
+
resource: options.issuerMetadata.credentialIssuer.credential_issuer,
|
|
1563
|
+
redirectUri: options.redirectUri,
|
|
1564
|
+
scope: options.scope,
|
|
1565
|
+
pkceCodeVerifier: options.pkceCodeVerifier,
|
|
1566
|
+
dpop: options.dpop
|
|
1567
|
+
});
|
|
1568
|
+
return {
|
|
1569
|
+
authorizationRequestUrl,
|
|
1570
|
+
pkce,
|
|
1571
|
+
dpop,
|
|
1572
|
+
authorizationServer: authorizationServerMetadata.issuer
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Convenience method around {@link Oauth2Client.retrievePreAuthorizedCodeAccessToken}
|
|
1577
|
+
* but specifically focused on a credential offer
|
|
1578
|
+
*/
|
|
1579
|
+
async retrievePreAuthorizedCodeAccessTokenFromOffer({ credentialOffer, issuerMetadata, additionalRequestPayload, txCode, dpop }) {
|
|
1580
|
+
if (!credentialOffer.grants?.[preAuthorizedCodeGrantIdentifier]) throw new Oauth2Error(`The credential offer does not contain the '${preAuthorizedCodeGrantIdentifier}' grant.`);
|
|
1581
|
+
if (credentialOffer.grants[preAuthorizedCodeGrantIdentifier].tx_code && !txCode) throw new Oauth2Error(`Retrieving access token requires a 'tx_code' in the request, but the 'txCode' parameter was not provided.`);
|
|
1582
|
+
const preAuthorizedCode = credentialOffer.grants[preAuthorizedCodeGrantIdentifier]["pre-authorized_code"];
|
|
1583
|
+
const authorizationServer = determineAuthorizationServerForCredentialOffer({
|
|
1584
|
+
grantAuthorizationServer: credentialOffer.grants[preAuthorizedCodeGrantIdentifier].authorization_server,
|
|
1585
|
+
issuerMetadata
|
|
1586
|
+
});
|
|
1587
|
+
const authorizationServerMetadata = getAuthorizationServerMetadataFromList(issuerMetadata.authorizationServers, authorizationServer);
|
|
1588
|
+
return {
|
|
1589
|
+
...await this.oauth2Client.retrievePreAuthorizedCodeAccessToken({
|
|
1590
|
+
authorizationServerMetadata,
|
|
1591
|
+
preAuthorizedCode,
|
|
1592
|
+
txCode,
|
|
1593
|
+
resource: issuerMetadata.credentialIssuer.credential_issuer,
|
|
1594
|
+
additionalRequestPayload,
|
|
1595
|
+
dpop
|
|
1596
|
+
}),
|
|
1597
|
+
authorizationServer
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
/**
|
|
1601
|
+
* Convenience method around {@link Oauth2Client.retrieveAuthorizationCodeAccessTokenFrom}
|
|
1602
|
+
* but specifically focused on a credential offer
|
|
1603
|
+
*/
|
|
1604
|
+
async retrieveAuthorizationCodeAccessTokenFromOffer({ issuerMetadata, additionalRequestPayload, credentialOffer, authorizationCode, pkceCodeVerifier, redirectUri, dpop }) {
|
|
1605
|
+
if (!credentialOffer.grants?.[authorizationCodeGrantIdentifier]) throw new Oauth2Error(`The credential offer does not contain the '${authorizationCodeGrantIdentifier}' grant.`);
|
|
1606
|
+
const authorizationServer = determineAuthorizationServerForCredentialOffer({
|
|
1607
|
+
grantAuthorizationServer: credentialOffer.grants[authorizationCodeGrantIdentifier].authorization_server,
|
|
1608
|
+
issuerMetadata
|
|
1609
|
+
});
|
|
1610
|
+
const authorizationServerMetadata = getAuthorizationServerMetadataFromList(issuerMetadata.authorizationServers, authorizationServer);
|
|
1611
|
+
return {
|
|
1612
|
+
...await this.oauth2Client.retrieveAuthorizationCodeAccessToken({
|
|
1613
|
+
authorizationServerMetadata,
|
|
1614
|
+
authorizationCode,
|
|
1615
|
+
pkceCodeVerifier,
|
|
1616
|
+
additionalRequestPayload,
|
|
1617
|
+
dpop,
|
|
1618
|
+
redirectUri,
|
|
1619
|
+
resource: issuerMetadata.credentialIssuer.credential_issuer
|
|
1620
|
+
}),
|
|
1621
|
+
authorizationServer
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
/**
|
|
1625
|
+
* Request a nonce to be used in credential request proofs from the `nonce_endpoint`
|
|
1626
|
+
*
|
|
1627
|
+
* @throws Openid4vciError - if no `nonce_endpoint` is configured in the issuer metadata
|
|
1628
|
+
* @throws InvalidFetchResponseError - if the nonce endpoint did not return a successful response
|
|
1629
|
+
* @throws ValidationError - if validating the nonce response failed
|
|
1630
|
+
*/
|
|
1631
|
+
async requestNonce(options) {
|
|
1632
|
+
return requestNonce({
|
|
1633
|
+
...options,
|
|
1634
|
+
fetch: this.options.callbacks.fetch
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Creates the jwt proof payload and header to be included in a credential request.
|
|
1639
|
+
*/
|
|
1640
|
+
async createCredentialRequestJwtProof(options) {
|
|
1641
|
+
const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[options.credentialConfigurationId];
|
|
1642
|
+
if (!credentialConfiguration) throw new Openid4vciError(`Credential configuration with '${options.credentialConfigurationId}' not found in 'credential_configurations_supported' from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
1643
|
+
if (credentialConfiguration.proof_types_supported) {
|
|
1644
|
+
if (!credentialConfiguration.proof_types_supported.jwt) throw new Openid4vciError(`Credential configuration with id '${options.credentialConfigurationId}' does not support the 'jwt' proof type.`);
|
|
1645
|
+
if (!credentialConfiguration.proof_types_supported.jwt.proof_signing_alg_values_supported.includes(options.signer.alg)) throw new Openid4vciError(`Credential configuration with id '${options.credentialConfigurationId}' does not support the '${options.signer.alg}' alg for 'jwt' proof type.`);
|
|
1646
|
+
if (credentialConfiguration.proof_types_supported.jwt.key_attestations_required && !options.keyAttestationJwt) throw new Openid4vciError(`Credential configuration with id '${options.credentialConfigurationId}' requires key attestations for 'jwt' proof type but no 'keyAttestationJwt' was provided`);
|
|
1647
|
+
}
|
|
1648
|
+
return { jwt: await createCredentialRequestJwtProof({
|
|
1649
|
+
credentialIssuer: options.issuerMetadata.credentialIssuer.credential_issuer,
|
|
1650
|
+
signer: options.signer,
|
|
1651
|
+
clientId: options.clientId,
|
|
1652
|
+
issuedAt: options.issuedAt,
|
|
1653
|
+
nonce: options.nonce,
|
|
1654
|
+
keyAttestationJwt: options.keyAttestationJwt,
|
|
1655
|
+
callbacks: this.options.callbacks
|
|
1656
|
+
}) };
|
|
1657
|
+
}
|
|
1658
|
+
/**
|
|
1659
|
+
* @throws Openid4vciRetrieveCredentialsError - if an unsuccessful response or the response couldn't be parsed as credential response
|
|
1660
|
+
* @throws ValidationError - if validation of the credential request failed
|
|
1661
|
+
* @throws Openid4vciError - if the `credentialConfigurationId` couldn't be found, or if the the format specific request couldn't be constructed
|
|
1662
|
+
*/
|
|
1663
|
+
async retrieveCredentials({ issuerMetadata, proof, proofs, credentialConfigurationId, additionalRequestPayload, accessToken, dpop }) {
|
|
1664
|
+
let credentialResponse;
|
|
1665
|
+
if (issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft15 || issuerMetadata.originalDraftVersion === Openid4vciDraftVersion.Draft16) credentialResponse = await retrieveCredentialsWithCredentialConfigurationId({
|
|
1666
|
+
accessToken,
|
|
1667
|
+
credentialConfigurationId,
|
|
1668
|
+
issuerMetadata,
|
|
1669
|
+
additionalRequestPayload,
|
|
1670
|
+
proof,
|
|
1671
|
+
proofs,
|
|
1672
|
+
callbacks: this.options.callbacks,
|
|
1673
|
+
dpop
|
|
1674
|
+
});
|
|
1675
|
+
else credentialResponse = await retrieveCredentialsWithFormat({
|
|
1676
|
+
accessToken,
|
|
1677
|
+
formatPayload: getCredentialRequestFormatPayloadForCredentialConfigurationId({
|
|
1678
|
+
credentialConfigurationId,
|
|
1679
|
+
issuerMetadata
|
|
1680
|
+
}),
|
|
1681
|
+
issuerMetadata,
|
|
1682
|
+
additionalRequestPayload,
|
|
1683
|
+
proof,
|
|
1684
|
+
proofs,
|
|
1685
|
+
callbacks: this.options.callbacks,
|
|
1686
|
+
dpop
|
|
1687
|
+
});
|
|
1688
|
+
if (!credentialResponse.ok) throw new Openid4vciRetrieveCredentialsError(`Error retrieving credentials from '${issuerMetadata.credentialIssuer.credential_issuer}'`, credentialResponse, await credentialResponse.response.clone().text());
|
|
1689
|
+
return credentialResponse;
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* @throws Openid4vciRetrieveCredentialsError - if an unsuccessful response or the response couldn't be parsed as credential response
|
|
1693
|
+
* @throws ValidationError - if validation of the credential request failed
|
|
1694
|
+
*/
|
|
1695
|
+
async retrieveDeferredCredentials(options) {
|
|
1696
|
+
const credentialResponse = await retrieveDeferredCredentials({
|
|
1697
|
+
...options,
|
|
1698
|
+
callbacks: this.options.callbacks
|
|
1699
|
+
});
|
|
1700
|
+
if (!credentialResponse.ok) throw new Openid4vciRetrieveCredentialsError(`Error retrieving deferred credentials from '${options.issuerMetadata.credentialIssuer.credential_issuer}'`, credentialResponse, await credentialResponse.response.clone().text());
|
|
1701
|
+
return credentialResponse;
|
|
1702
|
+
}
|
|
1703
|
+
/**
|
|
1704
|
+
* @throws Openid4vciSendNotificationError - if an unsuccessful response
|
|
1705
|
+
* @throws ValidationError - if validation of the notification request failed
|
|
1706
|
+
*/
|
|
1707
|
+
async sendNotification({ issuerMetadata, notification, additionalRequestPayload, accessToken, dpop }) {
|
|
1708
|
+
const notificationResponse = await sendNotification({
|
|
1709
|
+
accessToken,
|
|
1710
|
+
issuerMetadata,
|
|
1711
|
+
additionalRequestPayload,
|
|
1712
|
+
callbacks: this.options.callbacks,
|
|
1713
|
+
dpop,
|
|
1714
|
+
notification
|
|
1715
|
+
});
|
|
1716
|
+
if (!notificationResponse.ok) throw new Openid4vciSendNotificationError(`Error sending notification to '${issuerMetadata.credentialIssuer.credential_issuer}'`, notificationResponse);
|
|
1717
|
+
return notificationResponse;
|
|
1718
|
+
}
|
|
2301
1719
|
};
|
|
2302
1720
|
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
Oauth2AuthorizationServer,
|
|
2306
|
-
Oauth2ErrorCodes as Oauth2ErrorCodes3,
|
|
2307
|
-
Oauth2JwtVerificationError,
|
|
2308
|
-
Oauth2ServerErrorResponseError
|
|
2309
|
-
} from "@openid4vc/oauth2";
|
|
2310
|
-
import { ValidationError as ValidationError4, parseWithErrorHandling as parseWithErrorHandling11 } from "@openid4vc/utils";
|
|
2311
|
-
|
|
2312
|
-
// src/credential-request/credential-response.ts
|
|
2313
|
-
import { parseWithErrorHandling as parseWithErrorHandling8 } from "@openid4vc/utils";
|
|
1721
|
+
//#endregion
|
|
1722
|
+
//#region src/credential-request/credential-response.ts
|
|
2314
1723
|
function createCredentialResponse(options) {
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
...options.additionalPayload
|
|
2327
|
-
});
|
|
1724
|
+
return parseWithErrorHandling(zCredentialResponse, {
|
|
1725
|
+
c_nonce: options.cNonce,
|
|
1726
|
+
c_nonce_expires_in: options.cNonceExpiresInSeconds,
|
|
1727
|
+
credential: options.credential,
|
|
1728
|
+
credentials: options.credentials,
|
|
1729
|
+
notification_id: options.notificationId,
|
|
1730
|
+
transaction_id: options.transactionId,
|
|
1731
|
+
interval: options.interval,
|
|
1732
|
+
format: options.credentialRequest.format?.format,
|
|
1733
|
+
...options.additionalPayload
|
|
1734
|
+
});
|
|
2328
1735
|
}
|
|
2329
1736
|
function createDeferredCredentialResponse(options) {
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
1737
|
+
return parseWithErrorHandling(zDeferredCredentialResponse, {
|
|
1738
|
+
credentials: options.credentials,
|
|
1739
|
+
notification_id: options.notificationId,
|
|
1740
|
+
interval: options.interval,
|
|
1741
|
+
...options.additionalPayload
|
|
1742
|
+
});
|
|
2336
1743
|
}
|
|
2337
1744
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
import z22 from "zod";
|
|
1745
|
+
//#endregion
|
|
1746
|
+
//#region src/credential-request/parse-credential-request.ts
|
|
2341
1747
|
function parseCredentialRequest(options) {
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
}
|
|
2373
|
-
if (credentialRequest.credential_identifier) {
|
|
2374
|
-
return {
|
|
2375
|
-
credentialIdentifier: credentialRequest.credential_identifier,
|
|
2376
|
-
credentialRequest,
|
|
2377
|
-
proofs
|
|
2378
|
-
};
|
|
2379
|
-
}
|
|
2380
|
-
if (credentialRequest.format && allCredentialRequestFormatIdentifiers.includes(
|
|
2381
|
-
credentialRequest.format
|
|
2382
|
-
)) {
|
|
2383
|
-
return {
|
|
2384
|
-
// Removes all claims that are not specific to this format
|
|
2385
|
-
format: parseWithErrorHandling9(
|
|
2386
|
-
z22.union(allCredentialRequestFormats),
|
|
2387
|
-
credentialRequest,
|
|
2388
|
-
"Unable to validate format specific properties from credential request"
|
|
2389
|
-
),
|
|
2390
|
-
credentialRequest,
|
|
2391
|
-
proofs
|
|
2392
|
-
};
|
|
2393
|
-
}
|
|
2394
|
-
return {
|
|
2395
|
-
credentialRequest,
|
|
2396
|
-
proofs
|
|
2397
|
-
};
|
|
1748
|
+
const credentialRequest = parseWithErrorHandling(zCredentialRequest, options.credentialRequest, "Error validating credential request");
|
|
1749
|
+
let proofs;
|
|
1750
|
+
const knownProofs = zCredentialRequestProofs.strict().safeParse(credentialRequest.proofs);
|
|
1751
|
+
if (knownProofs.success) proofs = knownProofs.data;
|
|
1752
|
+
const knownProof = z.union(allCredentialRequestProofs).safeParse(credentialRequest.proof);
|
|
1753
|
+
if (knownProof.success && knownProof.data.proof_type === jwtProofTypeIdentifier) proofs = { [jwtProofTypeIdentifier]: [knownProof.data.jwt] };
|
|
1754
|
+
else if (knownProof.success && knownProof.data.proof_type === attestationProofTypeIdentifier) proofs = { [attestationProofTypeIdentifier]: [knownProof.data.attestation] };
|
|
1755
|
+
if (credentialRequest.credential_configuration_id) {
|
|
1756
|
+
getCredentialConfigurationSupportedById(options.issuerMetadata.credentialIssuer.credential_configurations_supported, credentialRequest.credential_configuration_id);
|
|
1757
|
+
return {
|
|
1758
|
+
credentialConfiguration: extractKnownCredentialConfigurationSupportedFormats(options.issuerMetadata.credentialIssuer.credential_configurations_supported)[credentialRequest.credential_configuration_id],
|
|
1759
|
+
credentialConfigurationId: credentialRequest.credential_configuration_id,
|
|
1760
|
+
credentialRequest,
|
|
1761
|
+
proofs
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
if (credentialRequest.credential_identifier) return {
|
|
1765
|
+
credentialIdentifier: credentialRequest.credential_identifier,
|
|
1766
|
+
credentialRequest,
|
|
1767
|
+
proofs
|
|
1768
|
+
};
|
|
1769
|
+
if (credentialRequest.format && allCredentialRequestFormatIdentifiers.includes(credentialRequest.format)) return {
|
|
1770
|
+
format: parseWithErrorHandling(z.union(allCredentialRequestFormats), credentialRequest, "Unable to validate format specific properties from credential request"),
|
|
1771
|
+
credentialRequest,
|
|
1772
|
+
proofs
|
|
1773
|
+
};
|
|
1774
|
+
return {
|
|
1775
|
+
credentialRequest,
|
|
1776
|
+
proofs
|
|
1777
|
+
};
|
|
2398
1778
|
}
|
|
2399
1779
|
|
|
2400
|
-
|
|
2401
|
-
|
|
1780
|
+
//#endregion
|
|
1781
|
+
//#region src/credential-request/parse-deferred-credential-request.ts
|
|
2402
1782
|
function parseDeferredCredentialRequest(options) {
|
|
2403
|
-
|
|
2404
|
-
zDeferredCredentialRequest,
|
|
2405
|
-
options.deferredCredentialRequest,
|
|
2406
|
-
"Error validating credential request"
|
|
2407
|
-
);
|
|
2408
|
-
return {
|
|
2409
|
-
deferredCredentialRequest
|
|
2410
|
-
};
|
|
1783
|
+
return { deferredCredentialRequest: parseWithErrorHandling(zDeferredCredentialRequest, options.deferredCredentialRequest, "Error validating credential request") };
|
|
2411
1784
|
}
|
|
2412
1785
|
|
|
2413
|
-
|
|
1786
|
+
//#endregion
|
|
1787
|
+
//#region src/formats/proof-type/attestation/attestation-proof-type.ts
|
|
2414
1788
|
async function verifyCredentialRequestAttestationProof(options) {
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
return verificationResult;
|
|
1789
|
+
return await verifyKeyAttestationJwt({
|
|
1790
|
+
...options,
|
|
1791
|
+
use: "proof_type.attestation"
|
|
1792
|
+
});
|
|
2420
1793
|
}
|
|
2421
1794
|
|
|
2422
|
-
|
|
1795
|
+
//#endregion
|
|
1796
|
+
//#region src/Openid4vciIssuer.ts
|
|
2423
1797
|
var Openid4vciIssuer = class {
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
internalMessage: "Error parsing deferred credential request",
|
|
2553
|
-
cause: error
|
|
2554
|
-
}
|
|
2555
|
-
);
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
/**
|
|
2559
|
-
* @throws ValidationError - when validation of the credential response fails
|
|
2560
|
-
*/
|
|
2561
|
-
createCredentialResponse(options) {
|
|
2562
|
-
return createCredentialResponse(options);
|
|
2563
|
-
}
|
|
2564
|
-
/**
|
|
2565
|
-
* @throws ValidationError - when validation of the credential response fails
|
|
2566
|
-
*/
|
|
2567
|
-
createDeferredCredentialResponse(options) {
|
|
2568
|
-
return createDeferredCredentialResponse(options);
|
|
2569
|
-
}
|
|
2570
|
-
/**
|
|
2571
|
-
* @throws ValidationError - when validation of the nonce response fails
|
|
2572
|
-
*/
|
|
2573
|
-
createNonceResponse(options) {
|
|
2574
|
-
return createNonceResponse(options);
|
|
2575
|
-
}
|
|
2576
|
-
async verifyWalletAttestation(options) {
|
|
2577
|
-
return new Oauth2AuthorizationServer({
|
|
2578
|
-
callbacks: this.options.callbacks
|
|
2579
|
-
}).verifyClientAttestation(options);
|
|
2580
|
-
}
|
|
1798
|
+
constructor(options) {
|
|
1799
|
+
this.options = options;
|
|
1800
|
+
}
|
|
1801
|
+
getCredentialIssuerMetadataDraft11(credentialIssuerMetadata) {
|
|
1802
|
+
return parseWithErrorHandling(zCredentialIssuerMetadataWithDraft11, credentialIssuerMetadata);
|
|
1803
|
+
}
|
|
1804
|
+
getKnownCredentialConfigurationsSupported(credentialIssuerMetadata) {
|
|
1805
|
+
return extractKnownCredentialConfigurationSupportedFormats(credentialIssuerMetadata.credential_configurations_supported);
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Create issuer metadata and validates the structure is correct
|
|
1809
|
+
*/
|
|
1810
|
+
createCredentialIssuerMetadata(credentialIssuerMetadata) {
|
|
1811
|
+
return parseWithErrorHandling(zCredentialIssuerMetadata, credentialIssuerMetadata, "Error validating credential issuer metadata");
|
|
1812
|
+
}
|
|
1813
|
+
async createCredentialOffer(options) {
|
|
1814
|
+
return createCredentialOffer({
|
|
1815
|
+
callbacks: this.options.callbacks,
|
|
1816
|
+
credentialConfigurationIds: options.credentialConfigurationIds,
|
|
1817
|
+
grants: options.grants,
|
|
1818
|
+
issuerMetadata: options.issuerMetadata,
|
|
1819
|
+
additionalPayload: options.additionalPayload,
|
|
1820
|
+
credentialOfferScheme: options.credentialOfferScheme,
|
|
1821
|
+
credentialOfferUri: options.credentialOfferUri
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
/**
|
|
1825
|
+
* @throws Oauth2ServerErrorResponseError - if verification of the jwt failed. You can extract
|
|
1826
|
+
* the credential error response from this.
|
|
1827
|
+
*/
|
|
1828
|
+
async verifyCredentialRequestJwtProof(options) {
|
|
1829
|
+
try {
|
|
1830
|
+
return await verifyCredentialRequestJwtProof({
|
|
1831
|
+
callbacks: this.options.callbacks,
|
|
1832
|
+
credentialIssuer: options.issuerMetadata.credentialIssuer.credential_issuer,
|
|
1833
|
+
expectedNonce: options.expectedNonce,
|
|
1834
|
+
nonceExpiresAt: options.nonceExpiresAt,
|
|
1835
|
+
jwt: options.jwt,
|
|
1836
|
+
clientId: options.clientId,
|
|
1837
|
+
now: options.now
|
|
1838
|
+
});
|
|
1839
|
+
} catch (error) {
|
|
1840
|
+
throw new Oauth2ServerErrorResponseError({
|
|
1841
|
+
error: Oauth2ErrorCodes.InvalidProof,
|
|
1842
|
+
error_description: error instanceof Oauth2JwtVerificationError || error instanceof Openid4vciError ? error.message : "Invalid proof"
|
|
1843
|
+
}, {
|
|
1844
|
+
internalMessage: "Error verifying credential request proof jwt",
|
|
1845
|
+
cause: error
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
/**
|
|
1850
|
+
* @throws Oauth2ServerErrorResponseError - if verification of the key attestation failed. You can extract
|
|
1851
|
+
* the credential error response from this.
|
|
1852
|
+
*/
|
|
1853
|
+
async verifyCredentialRequestAttestationProof(options) {
|
|
1854
|
+
try {
|
|
1855
|
+
return await verifyCredentialRequestAttestationProof({
|
|
1856
|
+
callbacks: this.options.callbacks,
|
|
1857
|
+
expectedNonce: options.expectedNonce,
|
|
1858
|
+
keyAttestationJwt: options.keyAttestationJwt,
|
|
1859
|
+
nonceExpiresAt: options.nonceExpiresAt,
|
|
1860
|
+
now: options.now
|
|
1861
|
+
});
|
|
1862
|
+
} catch (error) {
|
|
1863
|
+
throw new Oauth2ServerErrorResponseError({
|
|
1864
|
+
error: Oauth2ErrorCodes.InvalidProof,
|
|
1865
|
+
error_description: error instanceof Oauth2JwtVerificationError || error instanceof Openid4vciError ? error.message : "Invalid proof"
|
|
1866
|
+
}, {
|
|
1867
|
+
internalMessage: "Error verifying credential request proof attestation",
|
|
1868
|
+
cause: error
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* @throws Oauth2ServerErrorResponseError - when validation of the credential request fails
|
|
1874
|
+
* You can extract the credential error response from this.
|
|
1875
|
+
*/
|
|
1876
|
+
parseCredentialRequest(options) {
|
|
1877
|
+
try {
|
|
1878
|
+
return parseCredentialRequest(options);
|
|
1879
|
+
} catch (error) {
|
|
1880
|
+
throw new Oauth2ServerErrorResponseError({
|
|
1881
|
+
error: Oauth2ErrorCodes.InvalidCredentialRequest,
|
|
1882
|
+
error_description: error instanceof ValidationError ? error.message : "Invalid request"
|
|
1883
|
+
}, {
|
|
1884
|
+
internalMessage: "Error verifying credential request proof jwt",
|
|
1885
|
+
cause: error
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* @throws Oauth2ServerErrorResponseError - when validation of the deferred credential request fails
|
|
1891
|
+
*/
|
|
1892
|
+
parseDeferredCredentialRequest(options) {
|
|
1893
|
+
try {
|
|
1894
|
+
return parseDeferredCredentialRequest(options);
|
|
1895
|
+
} catch (error) {
|
|
1896
|
+
throw new Oauth2ServerErrorResponseError({
|
|
1897
|
+
error: Oauth2ErrorCodes.InvalidCredentialRequest,
|
|
1898
|
+
error_description: error instanceof ValidationError ? error.message : "Invalid request"
|
|
1899
|
+
}, {
|
|
1900
|
+
internalMessage: "Error parsing deferred credential request",
|
|
1901
|
+
cause: error
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
/**
|
|
1906
|
+
* @throws ValidationError - when validation of the credential response fails
|
|
1907
|
+
*/
|
|
1908
|
+
createCredentialResponse(options) {
|
|
1909
|
+
return createCredentialResponse(options);
|
|
1910
|
+
}
|
|
1911
|
+
/**
|
|
1912
|
+
* @throws ValidationError - when validation of the credential response fails
|
|
1913
|
+
*/
|
|
1914
|
+
createDeferredCredentialResponse(options) {
|
|
1915
|
+
return createDeferredCredentialResponse(options);
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* @throws ValidationError - when validation of the nonce response fails
|
|
1919
|
+
*/
|
|
1920
|
+
createNonceResponse(options) {
|
|
1921
|
+
return createNonceResponse(options);
|
|
1922
|
+
}
|
|
1923
|
+
async verifyWalletAttestation(options) {
|
|
1924
|
+
return new Oauth2AuthorizationServer({ callbacks: this.options.callbacks }).verifyClientAttestation(options);
|
|
1925
|
+
}
|
|
2581
1926
|
};
|
|
2582
1927
|
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
createClientAttestationJwt
|
|
2586
|
-
} from "@openid4vc/oauth2";
|
|
1928
|
+
//#endregion
|
|
1929
|
+
//#region src/Openid4vciWalletProvider.ts
|
|
2587
1930
|
var Openid4vciWalletProvider = class {
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
};
|
|
2613
|
-
export {
|
|
2614
|
-
AuthorizationFlow,
|
|
2615
|
-
Openid4vciClient,
|
|
2616
|
-
Openid4vciDraftVersion,
|
|
2617
|
-
Openid4vciError,
|
|
2618
|
-
Openid4vciIssuer,
|
|
2619
|
-
Openid4vciRetrieveCredentialsError,
|
|
2620
|
-
Openid4vciSendNotificationError,
|
|
2621
|
-
Openid4vciWalletProvider,
|
|
2622
|
-
createKeyAttestationJwt,
|
|
2623
|
-
credentialsSupportedToCredentialConfigurationsSupported,
|
|
2624
|
-
determineAuthorizationServerForCredentialOffer,
|
|
2625
|
-
extractScopesForCredentialConfigurationIds,
|
|
2626
|
-
getCredentialConfigurationsMatchingRequestFormat,
|
|
2627
|
-
getGlobalConfig,
|
|
2628
|
-
parseKeyAttestationJwt,
|
|
2629
|
-
setGlobalConfig,
|
|
2630
|
-
verifyKeyAttestationJwt
|
|
1931
|
+
constructor(options) {
|
|
1932
|
+
this.options = options;
|
|
1933
|
+
}
|
|
1934
|
+
async createWalletAttestationJwt(options) {
|
|
1935
|
+
const additionalPayload = options.additionalPayload ? {
|
|
1936
|
+
wallet_name: options.walletName,
|
|
1937
|
+
wallet_link: options.walletLink,
|
|
1938
|
+
...options.additionalPayload
|
|
1939
|
+
} : {
|
|
1940
|
+
wallet_name: options.walletName,
|
|
1941
|
+
wallet_link: options.walletLink
|
|
1942
|
+
};
|
|
1943
|
+
return await createClientAttestationJwt({
|
|
1944
|
+
...options,
|
|
1945
|
+
callbacks: this.options.callbacks,
|
|
1946
|
+
additionalPayload
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
async createKeyAttestationJwt(options) {
|
|
1950
|
+
return await createKeyAttestationJwt({
|
|
1951
|
+
callbacks: this.options.callbacks,
|
|
1952
|
+
...options
|
|
1953
|
+
});
|
|
1954
|
+
}
|
|
2631
1955
|
};
|
|
1956
|
+
|
|
1957
|
+
//#endregion
|
|
1958
|
+
export { AuthorizationFlow, Openid4vciClient, Openid4vciDraftVersion, Openid4vciError, Openid4vciIssuer, Openid4vciRetrieveCredentialsError, Openid4vciSendNotificationError, Openid4vciWalletProvider, createKeyAttestationJwt, credentialsSupportedToCredentialConfigurationsSupported, determineAuthorizationServerForCredentialOffer, extractScopesForCredentialConfigurationIds, getCredentialConfigurationsMatchingRequestFormat, getGlobalConfig, parseKeyAttestationJwt, setGlobalConfig, verifyKeyAttestationJwt };
|
|
2632
1959
|
//# sourceMappingURL=index.mjs.map
|