@openid4vc/openid4vci 0.3.0-alpha-20251120111954 → 0.3.0-alpha-20251121092537
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.cjs +189 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -361
- package/dist/index.d.mts +93 -361
- package/dist/index.mjs +190 -182
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -168,32 +168,53 @@ async function createCredentialOffer(options) {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
//#endregion
|
|
171
|
-
//#region src/
|
|
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
|
-
|
|
171
|
+
//#region src/credential-request/credential-request-configurations.ts
|
|
172
|
+
function getCredentialConfigurationsMatchingRequestFormat({ requestFormat, issuerMetadata }) {
|
|
173
|
+
const knownCredentialConfigurations = issuerMetadata.knownCredentialConfigurations;
|
|
174
|
+
return Object.fromEntries(Object.entries(knownCredentialConfigurations).filter(([, credentialConfiguration]) => {
|
|
175
|
+
if (credentialConfiguration.format !== requestFormat.format) return false;
|
|
176
|
+
const r = requestFormat;
|
|
177
|
+
const c = credentialConfiguration;
|
|
178
|
+
if ((c.format === "ldp_vc" || c.format === "jwt_vc_json-ld") && r.format === c.format) return (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type) && (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition["@context"], c.credential_definition["@context"]);
|
|
179
|
+
if (c.format === "jwt_vc_json" && r.format === c.format) return (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type);
|
|
180
|
+
if (c.format === "vc+sd-jwt" && r.format === c.format) {
|
|
181
|
+
if (r.vct && c.vct) return r.vct === c.vct;
|
|
182
|
+
if (c.credential_definition && r.credential_definition) return (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type);
|
|
183
|
+
}
|
|
184
|
+
if (c.format === "mso_mdoc" && r.format === c.format) return r.doctype === c.doctype;
|
|
185
|
+
return false;
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/error/Openid4vciError.ts
|
|
191
|
+
var Openid4vciError = class extends Error {
|
|
192
|
+
constructor(message, options) {
|
|
193
|
+
const errorMessage = message ?? "Unknown error occurred.";
|
|
194
|
+
const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
|
|
195
|
+
super(`${errorMessage}${causeMessage}`);
|
|
196
|
+
this.cause = options?.cause;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/error/Openid4vciRetrieveCredentialsError.ts
|
|
202
|
+
var Openid4vciRetrieveCredentialsError = class extends Openid4vciError {
|
|
203
|
+
constructor(message, response, responseText) {
|
|
204
|
+
const errorData = response.credentialResponseResult?.data ?? response.credentialErrorResponseResult?.data ?? (response.credentialResponseResult?.error ? (0, __openid4vc_utils.formatZodError)(response.credentialResponseResult.error) : void 0) ?? responseText;
|
|
205
|
+
super(`${message}\n${JSON.stringify(errorData, null, 2)}`);
|
|
206
|
+
this.response = response;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/error/Openid4vciSendNotificationError.ts
|
|
212
|
+
var Openid4vciSendNotificationError = class extends Openid4vciError {
|
|
213
|
+
constructor(message, response) {
|
|
214
|
+
super(message);
|
|
215
|
+
this.response = response;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
197
218
|
|
|
198
219
|
//#endregion
|
|
199
220
|
//#region src/key-attestation/z-key-attestation.ts
|
|
@@ -222,18 +243,103 @@ const zKeyAttestationJwtPayloadForUse = (use) => zod.default.object({
|
|
|
222
243
|
exp: use === "proof_type.jwt" ? __openid4vc_utils.zInteger : zod.default.optional(__openid4vc_utils.zInteger)
|
|
223
244
|
}).loose();
|
|
224
245
|
|
|
246
|
+
//#endregion
|
|
247
|
+
//#region src/key-attestation/key-attestation.ts
|
|
248
|
+
async function createKeyAttestationJwt(options) {
|
|
249
|
+
const header = (0, __openid4vc_utils.parseWithErrorHandling)(zKeyAttestationJwtHeader, {
|
|
250
|
+
...(0, __openid4vc_oauth2.jwtHeaderFromJwtSigner)(options.signer),
|
|
251
|
+
typ: "keyattestation+jwt"
|
|
252
|
+
});
|
|
253
|
+
const payload = (0, __openid4vc_utils.parseWithErrorHandling)(zKeyAttestationJwtPayloadForUse(options.use), {
|
|
254
|
+
iat: (0, __openid4vc_utils.dateToSeconds)(options.issuedAt),
|
|
255
|
+
exp: options.expiresAt ? (0, __openid4vc_utils.dateToSeconds)(options.expiresAt) : void 0,
|
|
256
|
+
nonce: options.nonce,
|
|
257
|
+
attested_keys: options.attestedKeys,
|
|
258
|
+
user_authentication: options.userAuthentication,
|
|
259
|
+
key_storage: options.keyStorage,
|
|
260
|
+
certification: options.certification,
|
|
261
|
+
...options.additionalPayload
|
|
262
|
+
});
|
|
263
|
+
const { jwt } = await options.callbacks.signJwt(options.signer, {
|
|
264
|
+
header,
|
|
265
|
+
payload
|
|
266
|
+
});
|
|
267
|
+
return jwt;
|
|
268
|
+
}
|
|
269
|
+
function parseKeyAttestationJwt({ keyAttestationJwt, use }) {
|
|
270
|
+
return (0, __openid4vc_oauth2.decodeJwt)({
|
|
271
|
+
jwt: keyAttestationJwt,
|
|
272
|
+
headerSchema: zKeyAttestationJwtHeader,
|
|
273
|
+
payloadSchema: zKeyAttestationJwtPayloadForUse(use)
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
async function verifyKeyAttestationJwt(options) {
|
|
277
|
+
const { header, payload } = parseKeyAttestationJwt({
|
|
278
|
+
keyAttestationJwt: options.keyAttestationJwt,
|
|
279
|
+
use: options.use
|
|
280
|
+
});
|
|
281
|
+
const now = options.now?.getTime() ?? Date.now();
|
|
282
|
+
if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) throw new Openid4vciError("Nonce used for key attestation jwt expired");
|
|
283
|
+
const { signer } = await (0, __openid4vc_oauth2.verifyJwt)({
|
|
284
|
+
compact: options.keyAttestationJwt,
|
|
285
|
+
header,
|
|
286
|
+
payload,
|
|
287
|
+
signer: (0, __openid4vc_oauth2.jwtSignerFromJwt)({
|
|
288
|
+
header,
|
|
289
|
+
payload
|
|
290
|
+
}),
|
|
291
|
+
verifyJwtCallback: options.callbacks.verifyJwt,
|
|
292
|
+
errorMessage: "Error verifiying key attestation jwt",
|
|
293
|
+
expectedNonce: options.expectedNonce,
|
|
294
|
+
now: options.now
|
|
295
|
+
});
|
|
296
|
+
return {
|
|
297
|
+
header,
|
|
298
|
+
payload,
|
|
299
|
+
signer
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region src/metadata/credential-issuer/z-claims-description.ts
|
|
305
|
+
const zCredentialConfigurationSupportedClaimsDescriptionDraft14 = zod.default.object({
|
|
306
|
+
mandatory: zod.default.boolean().optional(),
|
|
307
|
+
value_type: zod.default.string().optional(),
|
|
308
|
+
display: zod.default.array(zod.default.object({
|
|
309
|
+
name: zod.default.string().optional(),
|
|
310
|
+
locale: zod.default.string().optional()
|
|
311
|
+
}).loose()).optional()
|
|
312
|
+
}).loose();
|
|
313
|
+
const zCredentialConfigurationSupportedClaimsDraft14 = zod.default.record(zod.default.string(), zod.default.union([zCredentialConfigurationSupportedClaimsDescriptionDraft14, zod.default.lazy(() => zCredentialConfigurationSupportedClaimsDraft14)]));
|
|
314
|
+
const zClaimDescriptionPathValue = zod.default.union([
|
|
315
|
+
zod.default.string(),
|
|
316
|
+
zod.default.number().int().nonnegative(),
|
|
317
|
+
zod.default.null()
|
|
318
|
+
]);
|
|
319
|
+
const zClaimsDescriptionPath = zod.default.tuple([zClaimDescriptionPathValue], zClaimDescriptionPathValue);
|
|
320
|
+
const zMsoMdocClaimsDescriptionPath = zod.default.tuple([zod.default.string(), zod.default.string()], zod.default.string(), { message: "mso_mdoc claims description path MUST be an array with at least two string elements, pointing to the namespace and element identifier within an mdoc credential" });
|
|
321
|
+
const zIssuerMetadataClaimsDescription = zod.default.object({
|
|
322
|
+
path: zClaimsDescriptionPath,
|
|
323
|
+
mandatory: zod.default.boolean().optional(),
|
|
324
|
+
display: zod.default.array(zod.default.object({
|
|
325
|
+
name: zod.default.string().optional(),
|
|
326
|
+
locale: zod.default.string().optional()
|
|
327
|
+
}).loose()).optional()
|
|
328
|
+
}).loose();
|
|
329
|
+
const zMsoMdocIssuerMetadataClaimsDescription = zIssuerMetadataClaimsDescription.extend({ path: zMsoMdocClaimsDescriptionPath });
|
|
330
|
+
|
|
225
331
|
//#endregion
|
|
226
332
|
//#region src/metadata/credential-issuer/z-credential-configuration-supported-common.ts
|
|
227
333
|
const zCredentialConfigurationSupportedDisplayEntry = zod.default.object({
|
|
228
334
|
name: zod.default.string(),
|
|
229
335
|
locale: zod.default.string().optional(),
|
|
230
336
|
logo: zod.default.object({
|
|
231
|
-
uri:
|
|
337
|
+
uri: __openid4vc_utils.zHttpsUrl.or(__openid4vc_utils.zDataUrl).optional(),
|
|
232
338
|
alt_text: zod.default.string().optional()
|
|
233
339
|
}).loose().optional(),
|
|
234
340
|
description: zod.default.string().optional(),
|
|
235
341
|
background_color: zod.default.string().optional(),
|
|
236
|
-
background_image: zod.default.object({ uri:
|
|
342
|
+
background_image: zod.default.object({ uri: __openid4vc_utils.zHttpsUrl.or(__openid4vc_utils.zDataUrl).optional() }).loose().optional(),
|
|
237
343
|
text_color: zod.default.string().optional()
|
|
238
344
|
}).loose();
|
|
239
345
|
const zCredentialConfigurationSupportedCommonCredentialMetadata = zod.default.object({ display: zod.default.array(zCredentialConfigurationSupportedDisplayEntry).optional() }).loose();
|
|
@@ -639,7 +745,7 @@ const zCredentialIssuerMetadataDisplayEntry = zod.default.object({
|
|
|
639
745
|
name: zod.default.string().optional(),
|
|
640
746
|
locale: zod.default.string().optional(),
|
|
641
747
|
logo: zod.default.object({
|
|
642
|
-
uri:
|
|
748
|
+
uri: __openid4vc_utils.zHttpsUrl.or(__openid4vc_utils.zDataUrl).optional(),
|
|
643
749
|
alt_text: zod.default.string().optional()
|
|
644
750
|
}).loose().optional()
|
|
645
751
|
}).loose();
|
|
@@ -657,15 +763,15 @@ const zCredentialIssuerMetadataDraft14Draft15V1 = zod.default.object({
|
|
|
657
763
|
}).loose().optional(),
|
|
658
764
|
batch_credential_issuance: zod.default.object({ batch_size: zod.default.number().positive() }).loose().optional(),
|
|
659
765
|
display: zod.default.array(zCredentialIssuerMetadataDisplayEntry).optional(),
|
|
660
|
-
credential_configurations_supported: zod.default.record(zod.default.string(),
|
|
766
|
+
credential_configurations_supported: zod.default.record(zod.default.string(), zCredentialConfigurationSupportedCommon)
|
|
661
767
|
}).loose();
|
|
662
768
|
const zCredentialConfigurationSupportedDraft11ToV1 = zod.default.object({
|
|
663
769
|
id: zod.default.string().optional(),
|
|
664
770
|
format: zod.default.string(),
|
|
665
771
|
cryptographic_suites_supported: zod.default.array(zod.default.string()).optional(),
|
|
666
772
|
display: zod.default.array(zod.default.object({
|
|
667
|
-
logo: zod.default.object({ url:
|
|
668
|
-
background_image: zod.default.object({ url:
|
|
773
|
+
logo: zod.default.object({ url: __openid4vc_utils.zHttpsUrl.or(__openid4vc_utils.zDataUrl).optional() }).loose().optional(),
|
|
774
|
+
background_image: zod.default.object({ url: __openid4vc_utils.zHttpsUrl.or(__openid4vc_utils.zDataUrl).optional() }).loose().optional()
|
|
669
775
|
}).loose()).optional(),
|
|
670
776
|
claims: zod.default.any().optional()
|
|
671
777
|
}).loose().transform(({ cryptographic_suites_supported, display, claims, id, format,...rest }) => ({
|
|
@@ -765,6 +871,37 @@ const zCredentialIssuerMetadataWithDraftVersion = zod.default.union([zCredential
|
|
|
765
871
|
originalDraftVersion: Openid4vciDraftVersion.Draft11
|
|
766
872
|
}))]);
|
|
767
873
|
|
|
874
|
+
//#endregion
|
|
875
|
+
//#region src/metadata/credential-issuer/credential-configurations.ts
|
|
876
|
+
function extractScopesForCredentialConfigurationIds(options) {
|
|
877
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
878
|
+
for (const credentialConfigurationId of options.credentialConfigurationIds) {
|
|
879
|
+
const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
880
|
+
if (!credentialConfiguration) throw new __openid4vc_oauth2.Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in metadata from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
881
|
+
const scope = credentialConfiguration.scope;
|
|
882
|
+
if (scope) scopes.add(scope);
|
|
883
|
+
else if (!scope && options.throwOnConfigurationWithoutScope) throw new __openid4vc_oauth2.Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`);
|
|
884
|
+
}
|
|
885
|
+
return scopes.size > 0 ? Array.from(scopes) : void 0;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Transforms draft 11 credentials supported syntax to credential configurations supported
|
|
889
|
+
*
|
|
890
|
+
* @throws if a credentials supported entry without id is passed
|
|
891
|
+
* @throws if a credentials supported entry with invalid structure or format specific properties is passed
|
|
892
|
+
*/
|
|
893
|
+
function credentialsSupportedToCredentialConfigurationsSupported(credentialsSupported) {
|
|
894
|
+
const credentialConfigurationsSupported = {};
|
|
895
|
+
for (let index = 0; index < credentialsSupported.length; index++) {
|
|
896
|
+
const credentialSupported = credentialsSupported[index];
|
|
897
|
+
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`);
|
|
898
|
+
const parseResult = zCredentialConfigurationSupportedDraft11ToV1.safeParse(credentialSupported);
|
|
899
|
+
if (!parseResult.success) throw new __openid4vc_utils.ValidationError(`Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`, parseResult.error);
|
|
900
|
+
credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
|
|
901
|
+
}
|
|
902
|
+
return credentialConfigurationsSupported;
|
|
903
|
+
}
|
|
904
|
+
|
|
768
905
|
//#endregion
|
|
769
906
|
//#region src/metadata/credential-issuer/z-signed-credential-issuer-metadata.ts
|
|
770
907
|
const zSignedCredentialIssuerMetadataHeader = zod.default.object({
|
|
@@ -838,161 +975,34 @@ async function fetchCredentialIssuerMetadata(credentialIssuer, options) {
|
|
|
838
975
|
}
|
|
839
976
|
/**
|
|
840
977
|
* Extract credential configuration supported entries where the `format` is known to this
|
|
841
|
-
* library. Should be ran only after verifying
|
|
842
|
-
* we can be certain that if the `format`
|
|
978
|
+
* library and the configuration validates correctly. Should be ran only after verifying
|
|
979
|
+
* the credential issuer metadata structure, so we can be certain that if the `format`
|
|
980
|
+
* matches the other format specific requirements are also met.
|
|
843
981
|
*
|
|
844
982
|
* Validation is done when resolving issuer metadata, or when calling `createIssuerMetadata`.
|
|
845
983
|
*/
|
|
846
984
|
function extractKnownCredentialConfigurationSupportedFormats(credentialConfigurationsSupported) {
|
|
847
|
-
return Object.fromEntries(Object.entries(credentialConfigurationsSupported).filter((entry) =>
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
if (!configuration) throw new __openid4vc_oauth2.Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in credential configurations supported.`);
|
|
852
|
-
return configuration;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
//#endregion
|
|
856
|
-
//#region src/credential-request/credential-request-configurations.ts
|
|
857
|
-
function getCredentialConfigurationsMatchingRequestFormat({ requestFormat, credentialConfigurations }) {
|
|
858
|
-
const knownCredentialConfigurations = extractKnownCredentialConfigurationSupportedFormats(credentialConfigurations);
|
|
859
|
-
return Object.fromEntries(Object.entries(knownCredentialConfigurations).filter(([, credentialConfiguration]) => {
|
|
860
|
-
if (credentialConfiguration.format !== requestFormat.format) return false;
|
|
861
|
-
const r = requestFormat;
|
|
862
|
-
const c = credentialConfiguration;
|
|
863
|
-
if ((c.format === "ldp_vc" || c.format === "jwt_vc_json-ld") && r.format === c.format) return (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type) && (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition["@context"], c.credential_definition["@context"]);
|
|
864
|
-
if (c.format === "jwt_vc_json" && r.format === c.format) return (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type);
|
|
865
|
-
if (c.format === "vc+sd-jwt" && r.format === c.format) {
|
|
866
|
-
if (r.vct && c.vct) return r.vct === c.vct;
|
|
867
|
-
if (c.credential_definition && r.credential_definition) return (0, __openid4vc_utils.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type);
|
|
868
|
-
}
|
|
869
|
-
if (c.format === "mso_mdoc" && r.format === c.format) return r.doctype === c.doctype;
|
|
870
|
-
return false;
|
|
985
|
+
return Object.fromEntries(Object.entries(credentialConfigurationsSupported).filter((entry) => {
|
|
986
|
+
const credentialConfiguration = zCredentialConfigurationSupportedWithFormats.safeParse(entry[1]);
|
|
987
|
+
if (!credentialConfiguration.success) return false;
|
|
988
|
+
return allCredentialIssuerMetadataFormatIdentifiers.includes(credentialConfiguration.data.format);
|
|
871
989
|
}));
|
|
872
990
|
}
|
|
873
|
-
|
|
874
|
-
//#endregion
|
|
875
|
-
//#region src/error/Openid4vciError.ts
|
|
876
|
-
var Openid4vciError = class extends Error {
|
|
877
|
-
constructor(message, options) {
|
|
878
|
-
const errorMessage = message ?? "Unknown error occurred.";
|
|
879
|
-
const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
|
|
880
|
-
super(`${errorMessage}${causeMessage}`);
|
|
881
|
-
this.cause = options?.cause;
|
|
882
|
-
}
|
|
883
|
-
};
|
|
884
|
-
|
|
885
|
-
//#endregion
|
|
886
|
-
//#region src/error/Openid4vciRetrieveCredentialsError.ts
|
|
887
|
-
var Openid4vciRetrieveCredentialsError = class extends Openid4vciError {
|
|
888
|
-
constructor(message, response, responseText) {
|
|
889
|
-
const errorData = response.credentialResponseResult?.data ?? response.credentialErrorResponseResult?.data ?? (response.credentialResponseResult?.error ? (0, __openid4vc_utils.formatZodError)(response.credentialResponseResult.error) : void 0) ?? responseText;
|
|
890
|
-
super(`${message}\n${JSON.stringify(errorData, null, 2)}`);
|
|
891
|
-
this.response = response;
|
|
892
|
-
}
|
|
893
|
-
};
|
|
894
|
-
|
|
895
|
-
//#endregion
|
|
896
|
-
//#region src/error/Openid4vciSendNotificationError.ts
|
|
897
|
-
var Openid4vciSendNotificationError = class extends Openid4vciError {
|
|
898
|
-
constructor(message, response) {
|
|
899
|
-
super(message);
|
|
900
|
-
this.response = response;
|
|
901
|
-
}
|
|
902
|
-
};
|
|
903
|
-
|
|
904
|
-
//#endregion
|
|
905
|
-
//#region src/key-attestation/key-attestation.ts
|
|
906
|
-
async function createKeyAttestationJwt(options) {
|
|
907
|
-
const header = (0, __openid4vc_utils.parseWithErrorHandling)(zKeyAttestationJwtHeader, {
|
|
908
|
-
...(0, __openid4vc_oauth2.jwtHeaderFromJwtSigner)(options.signer),
|
|
909
|
-
typ: "keyattestation+jwt"
|
|
910
|
-
});
|
|
911
|
-
const payload = (0, __openid4vc_utils.parseWithErrorHandling)(zKeyAttestationJwtPayloadForUse(options.use), {
|
|
912
|
-
iat: (0, __openid4vc_utils.dateToSeconds)(options.issuedAt),
|
|
913
|
-
exp: options.expiresAt ? (0, __openid4vc_utils.dateToSeconds)(options.expiresAt) : void 0,
|
|
914
|
-
nonce: options.nonce,
|
|
915
|
-
attested_keys: options.attestedKeys,
|
|
916
|
-
user_authentication: options.userAuthentication,
|
|
917
|
-
key_storage: options.keyStorage,
|
|
918
|
-
certification: options.certification,
|
|
919
|
-
...options.additionalPayload
|
|
920
|
-
});
|
|
921
|
-
const { jwt } = await options.callbacks.signJwt(options.signer, {
|
|
922
|
-
header,
|
|
923
|
-
payload
|
|
924
|
-
});
|
|
925
|
-
return jwt;
|
|
926
|
-
}
|
|
927
|
-
function parseKeyAttestationJwt({ keyAttestationJwt, use }) {
|
|
928
|
-
return (0, __openid4vc_oauth2.decodeJwt)({
|
|
929
|
-
jwt: keyAttestationJwt,
|
|
930
|
-
headerSchema: zKeyAttestationJwtHeader,
|
|
931
|
-
payloadSchema: zKeyAttestationJwtPayloadForUse(use)
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
|
-
async function verifyKeyAttestationJwt(options) {
|
|
935
|
-
const { header, payload } = parseKeyAttestationJwt({
|
|
936
|
-
keyAttestationJwt: options.keyAttestationJwt,
|
|
937
|
-
use: options.use
|
|
938
|
-
});
|
|
939
|
-
const now = options.now?.getTime() ?? Date.now();
|
|
940
|
-
if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) throw new Openid4vciError("Nonce used for key attestation jwt expired");
|
|
941
|
-
const { signer } = await (0, __openid4vc_oauth2.verifyJwt)({
|
|
942
|
-
compact: options.keyAttestationJwt,
|
|
943
|
-
header,
|
|
944
|
-
payload,
|
|
945
|
-
signer: (0, __openid4vc_oauth2.jwtSignerFromJwt)({
|
|
946
|
-
header,
|
|
947
|
-
payload
|
|
948
|
-
}),
|
|
949
|
-
verifyJwtCallback: options.callbacks.verifyJwt,
|
|
950
|
-
errorMessage: "Error verifiying key attestation jwt",
|
|
951
|
-
expectedNonce: options.expectedNonce,
|
|
952
|
-
now: options.now
|
|
953
|
-
});
|
|
954
|
-
return {
|
|
955
|
-
header,
|
|
956
|
-
payload,
|
|
957
|
-
signer
|
|
958
|
-
};
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
//#endregion
|
|
962
|
-
//#region src/metadata/credential-issuer/credential-configurations.ts
|
|
963
|
-
function extractScopesForCredentialConfigurationIds(options) {
|
|
964
|
-
const scopes = /* @__PURE__ */ new Set();
|
|
965
|
-
for (const credentialConfigurationId of options.credentialConfigurationIds) {
|
|
966
|
-
const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
967
|
-
if (!credentialConfiguration) throw new __openid4vc_oauth2.Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in metadata from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
968
|
-
const scope = credentialConfiguration.scope;
|
|
969
|
-
if (scope) scopes.add(scope);
|
|
970
|
-
else if (!scope && options.throwOnConfigurationWithoutScope) throw new __openid4vc_oauth2.Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`);
|
|
971
|
-
}
|
|
972
|
-
return scopes.size > 0 ? Array.from(scopes) : void 0;
|
|
973
|
-
}
|
|
974
991
|
/**
|
|
975
|
-
*
|
|
976
|
-
*
|
|
977
|
-
* @throws if a credentials supported entry without id is passed
|
|
978
|
-
* @throws if a credentials supported entry with invalid structure or format specific properties is passed
|
|
992
|
+
* Get a known credential configuration supported by its id, it will throw an error if the configuration
|
|
993
|
+
* is not found or if its found but the credential configuration is invalid.
|
|
979
994
|
*/
|
|
980
|
-
function
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
const parseResult = zCredentialConfigurationSupportedDraft11ToV1.safeParse(credentialSupported);
|
|
986
|
-
if (!parseResult.success) throw new __openid4vc_utils.ValidationError(`Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`, parseResult.error);
|
|
987
|
-
credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
|
|
988
|
-
}
|
|
989
|
-
return credentialConfigurationsSupported;
|
|
995
|
+
function getKnownCredentialConfigurationSupportedById(issuerMetadata, credentialConfigurationId) {
|
|
996
|
+
const configuration = issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
997
|
+
if (!configuration) throw new __openid4vc_oauth2.Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in credential configurations supported.`);
|
|
998
|
+
if (!issuerMetadata.knownCredentialConfigurations[credentialConfigurationId]) (0, __openid4vc_utils.parseWithErrorHandling)(zCredentialConfigurationSupportedWithFormats, configuration, `Credential configuration with id '${credentialConfigurationId}' is not valid`);
|
|
999
|
+
return issuerMetadata.knownCredentialConfigurations[credentialConfigurationId];
|
|
990
1000
|
}
|
|
991
1001
|
|
|
992
1002
|
//#endregion
|
|
993
1003
|
//#region src/credential-request/format-payload.ts
|
|
994
1004
|
function getCredentialRequestFormatPayloadForCredentialConfigurationId(options) {
|
|
995
|
-
const credentialConfiguration =
|
|
1005
|
+
const credentialConfiguration = getKnownCredentialConfigurationSupportedById(options.issuerMetadata, options.credentialConfigurationId);
|
|
996
1006
|
if ((0, __openid4vc_utils.zIs)(zLegacySdJwtVcCredentialIssuerMetadataV1, credentialConfiguration) || (0, __openid4vc_utils.zIs)(zLegacySdJwtVcCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
997
1007
|
format: credentialConfiguration.format,
|
|
998
1008
|
vct: credentialConfiguration.vct
|
|
@@ -1270,7 +1280,7 @@ const zDeferredCredentialResponse = zBaseCredentialResponse.superRefine((value,
|
|
|
1270
1280
|
//#region src/credential-request/retrieve-credentials.ts
|
|
1271
1281
|
async function retrieveCredentialsWithCredentialConfigurationId(options) {
|
|
1272
1282
|
if (options.issuerMetadata.originalDraftVersion !== Openid4vciDraftVersion.Draft15 && options.issuerMetadata.originalDraftVersion !== Openid4vciDraftVersion.V1) 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.");
|
|
1273
|
-
|
|
1283
|
+
getKnownCredentialConfigurationSupportedById(options.issuerMetadata, options.credentialConfigurationId);
|
|
1274
1284
|
const credentialRequest = {
|
|
1275
1285
|
...options.additionalRequestPayload,
|
|
1276
1286
|
credential_configuration_id: options.credentialConfigurationId,
|
|
@@ -1481,7 +1491,8 @@ async function resolveIssuerMetadata(credentialIssuer, options) {
|
|
|
1481
1491
|
originalDraftVersion,
|
|
1482
1492
|
credentialIssuer: credentialIssuerMetadata,
|
|
1483
1493
|
signedCredentialIssuer: signed,
|
|
1484
|
-
authorizationServers: authoriationServersMetadata
|
|
1494
|
+
authorizationServers: authoriationServersMetadata,
|
|
1495
|
+
knownCredentialConfigurations: extractKnownCredentialConfigurationSupportedFormats(credentialIssuerMetadata.credential_configurations_supported)
|
|
1485
1496
|
};
|
|
1486
1497
|
}
|
|
1487
1498
|
|
|
@@ -1575,9 +1586,6 @@ var Openid4vciClient = class {
|
|
|
1575
1586
|
this.options = options;
|
|
1576
1587
|
this.oauth2Client = new __openid4vc_oauth2.Oauth2Client({ callbacks: this.options.callbacks });
|
|
1577
1588
|
}
|
|
1578
|
-
getKnownCredentialConfigurationsSupported(credentialIssuerMetadata) {
|
|
1579
|
-
return extractKnownCredentialConfigurationSupportedFormats(credentialIssuerMetadata.credential_configurations_supported);
|
|
1580
|
-
}
|
|
1581
1589
|
/**
|
|
1582
1590
|
* Resolve a credential offer into a credential offer object, handling both
|
|
1583
1591
|
* 'credential_offer' and 'credential_offer_uri' params.
|
|
@@ -1882,9 +1890,9 @@ function parseCredentialRequest(options) {
|
|
|
1882
1890
|
if (knownProof.success && knownProof.data.proof_type === jwtProofTypeIdentifier) proofs = { [jwtProofTypeIdentifier]: [knownProof.data.jwt] };
|
|
1883
1891
|
else if (knownProof.success && knownProof.data.proof_type === attestationProofTypeIdentifier) proofs = { [attestationProofTypeIdentifier]: [knownProof.data.attestation] };
|
|
1884
1892
|
if (credentialRequest.credential_configuration_id) {
|
|
1885
|
-
|
|
1893
|
+
getKnownCredentialConfigurationSupportedById(options.issuerMetadata, credentialRequest.credential_configuration_id);
|
|
1886
1894
|
return {
|
|
1887
|
-
credentialConfiguration:
|
|
1895
|
+
credentialConfiguration: options.issuerMetadata.knownCredentialConfigurations[credentialRequest.credential_configuration_id],
|
|
1888
1896
|
credentialConfigurationId: credentialRequest.credential_configuration_id,
|
|
1889
1897
|
credentialRequest,
|
|
1890
1898
|
proofs
|