@openid4vc/openid4vci 0.3.0-alpha-20251120111517 → 0.3.0-alpha-20251120112059
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 +184 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -281
- package/dist/index.d.mts +13 -281
- package/dist/index.mjs +184 -176
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -144,32 +144,53 @@ async function createCredentialOffer(options) {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
//#endregion
|
|
147
|
-
//#region src/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
})
|
|
172
|
-
|
|
147
|
+
//#region src/credential-request/credential-request-configurations.ts
|
|
148
|
+
function getCredentialConfigurationsMatchingRequestFormat({ requestFormat, issuerMetadata }) {
|
|
149
|
+
const knownCredentialConfigurations = issuerMetadata.knownCredentialConfigurations;
|
|
150
|
+
return Object.fromEntries(Object.entries(knownCredentialConfigurations).filter(([, credentialConfiguration]) => {
|
|
151
|
+
if (credentialConfiguration.format !== requestFormat.format) return false;
|
|
152
|
+
const r = requestFormat;
|
|
153
|
+
const c = credentialConfiguration;
|
|
154
|
+
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"]);
|
|
155
|
+
if (c.format === "jwt_vc_json" && r.format === c.format) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
156
|
+
if (c.format === "vc+sd-jwt" && r.format === c.format) {
|
|
157
|
+
if (r.vct && c.vct) return r.vct === c.vct;
|
|
158
|
+
if (c.credential_definition && r.credential_definition) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
159
|
+
}
|
|
160
|
+
if (c.format === "mso_mdoc" && r.format === c.format) return r.doctype === c.doctype;
|
|
161
|
+
return false;
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/error/Openid4vciError.ts
|
|
167
|
+
var Openid4vciError = class extends Error {
|
|
168
|
+
constructor(message, options) {
|
|
169
|
+
const errorMessage = message ?? "Unknown error occurred.";
|
|
170
|
+
const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
|
|
171
|
+
super(`${errorMessage}${causeMessage}`);
|
|
172
|
+
this.cause = options?.cause;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/error/Openid4vciRetrieveCredentialsError.ts
|
|
178
|
+
var Openid4vciRetrieveCredentialsError = class extends Openid4vciError {
|
|
179
|
+
constructor(message, response, responseText) {
|
|
180
|
+
const errorData = response.credentialResponseResult?.data ?? response.credentialErrorResponseResult?.data ?? (response.credentialResponseResult?.error ? formatZodError(response.credentialResponseResult.error) : void 0) ?? responseText;
|
|
181
|
+
super(`${message}\n${JSON.stringify(errorData, null, 2)}`);
|
|
182
|
+
this.response = response;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/error/Openid4vciSendNotificationError.ts
|
|
188
|
+
var Openid4vciSendNotificationError = class extends Openid4vciError {
|
|
189
|
+
constructor(message, response) {
|
|
190
|
+
super(message);
|
|
191
|
+
this.response = response;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
173
194
|
|
|
174
195
|
//#endregion
|
|
175
196
|
//#region src/key-attestation/z-key-attestation.ts
|
|
@@ -198,6 +219,91 @@ const zKeyAttestationJwtPayloadForUse = (use) => z.object({
|
|
|
198
219
|
exp: use === "proof_type.jwt" ? zInteger : z.optional(zInteger)
|
|
199
220
|
}).loose();
|
|
200
221
|
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/key-attestation/key-attestation.ts
|
|
224
|
+
async function createKeyAttestationJwt(options) {
|
|
225
|
+
const header = parseWithErrorHandling(zKeyAttestationJwtHeader, {
|
|
226
|
+
...jwtHeaderFromJwtSigner(options.signer),
|
|
227
|
+
typ: "keyattestation+jwt"
|
|
228
|
+
});
|
|
229
|
+
const payload = parseWithErrorHandling(zKeyAttestationJwtPayloadForUse(options.use), {
|
|
230
|
+
iat: dateToSeconds(options.issuedAt),
|
|
231
|
+
exp: options.expiresAt ? dateToSeconds(options.expiresAt) : void 0,
|
|
232
|
+
nonce: options.nonce,
|
|
233
|
+
attested_keys: options.attestedKeys,
|
|
234
|
+
user_authentication: options.userAuthentication,
|
|
235
|
+
key_storage: options.keyStorage,
|
|
236
|
+
certification: options.certification,
|
|
237
|
+
...options.additionalPayload
|
|
238
|
+
});
|
|
239
|
+
const { jwt } = await options.callbacks.signJwt(options.signer, {
|
|
240
|
+
header,
|
|
241
|
+
payload
|
|
242
|
+
});
|
|
243
|
+
return jwt;
|
|
244
|
+
}
|
|
245
|
+
function parseKeyAttestationJwt({ keyAttestationJwt, use }) {
|
|
246
|
+
return decodeJwt({
|
|
247
|
+
jwt: keyAttestationJwt,
|
|
248
|
+
headerSchema: zKeyAttestationJwtHeader,
|
|
249
|
+
payloadSchema: zKeyAttestationJwtPayloadForUse(use)
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async function verifyKeyAttestationJwt(options) {
|
|
253
|
+
const { header, payload } = parseKeyAttestationJwt({
|
|
254
|
+
keyAttestationJwt: options.keyAttestationJwt,
|
|
255
|
+
use: options.use
|
|
256
|
+
});
|
|
257
|
+
const now = options.now?.getTime() ?? Date.now();
|
|
258
|
+
if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) throw new Openid4vciError("Nonce used for key attestation jwt expired");
|
|
259
|
+
const { signer } = await verifyJwt({
|
|
260
|
+
compact: options.keyAttestationJwt,
|
|
261
|
+
header,
|
|
262
|
+
payload,
|
|
263
|
+
signer: jwtSignerFromJwt({
|
|
264
|
+
header,
|
|
265
|
+
payload
|
|
266
|
+
}),
|
|
267
|
+
verifyJwtCallback: options.callbacks.verifyJwt,
|
|
268
|
+
errorMessage: "Error verifiying key attestation jwt",
|
|
269
|
+
expectedNonce: options.expectedNonce,
|
|
270
|
+
now: options.now
|
|
271
|
+
});
|
|
272
|
+
return {
|
|
273
|
+
header,
|
|
274
|
+
payload,
|
|
275
|
+
signer
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/metadata/credential-issuer/z-claims-description.ts
|
|
281
|
+
const zCredentialConfigurationSupportedClaimsDescriptionDraft14 = z.object({
|
|
282
|
+
mandatory: z.boolean().optional(),
|
|
283
|
+
value_type: z.string().optional(),
|
|
284
|
+
display: z.array(z.object({
|
|
285
|
+
name: z.string().optional(),
|
|
286
|
+
locale: z.string().optional()
|
|
287
|
+
}).loose()).optional()
|
|
288
|
+
}).loose();
|
|
289
|
+
const zCredentialConfigurationSupportedClaimsDraft14 = z.record(z.string(), z.union([zCredentialConfigurationSupportedClaimsDescriptionDraft14, z.lazy(() => zCredentialConfigurationSupportedClaimsDraft14)]));
|
|
290
|
+
const zClaimDescriptionPathValue = z.union([
|
|
291
|
+
z.string(),
|
|
292
|
+
z.number().int().nonnegative(),
|
|
293
|
+
z.null()
|
|
294
|
+
]);
|
|
295
|
+
const zClaimsDescriptionPath = z.tuple([zClaimDescriptionPathValue], zClaimDescriptionPathValue);
|
|
296
|
+
const zMsoMdocClaimsDescriptionPath = z.tuple([z.string(), z.string()], z.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" });
|
|
297
|
+
const zIssuerMetadataClaimsDescription = z.object({
|
|
298
|
+
path: zClaimsDescriptionPath,
|
|
299
|
+
mandatory: z.boolean().optional(),
|
|
300
|
+
display: z.array(z.object({
|
|
301
|
+
name: z.string().optional(),
|
|
302
|
+
locale: z.string().optional()
|
|
303
|
+
}).loose()).optional()
|
|
304
|
+
}).loose();
|
|
305
|
+
const zMsoMdocIssuerMetadataClaimsDescription = zIssuerMetadataClaimsDescription.extend({ path: zMsoMdocClaimsDescriptionPath });
|
|
306
|
+
|
|
201
307
|
//#endregion
|
|
202
308
|
//#region src/metadata/credential-issuer/z-credential-configuration-supported-common.ts
|
|
203
309
|
const zCredentialConfigurationSupportedDisplayEntry = z.object({
|
|
@@ -633,7 +739,7 @@ const zCredentialIssuerMetadataDraft14Draft15V1 = z.object({
|
|
|
633
739
|
}).loose().optional(),
|
|
634
740
|
batch_credential_issuance: z.object({ batch_size: z.number().positive() }).loose().optional(),
|
|
635
741
|
display: z.array(zCredentialIssuerMetadataDisplayEntry).optional(),
|
|
636
|
-
credential_configurations_supported: z.record(z.string(),
|
|
742
|
+
credential_configurations_supported: z.record(z.string(), zCredentialConfigurationSupportedCommon)
|
|
637
743
|
}).loose();
|
|
638
744
|
const zCredentialConfigurationSupportedDraft11ToV1 = z.object({
|
|
639
745
|
id: z.string().optional(),
|
|
@@ -741,6 +847,37 @@ const zCredentialIssuerMetadataWithDraftVersion = z.union([zCredentialIssuerMeta
|
|
|
741
847
|
originalDraftVersion: Openid4vciDraftVersion.Draft11
|
|
742
848
|
}))]);
|
|
743
849
|
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region src/metadata/credential-issuer/credential-configurations.ts
|
|
852
|
+
function extractScopesForCredentialConfigurationIds(options) {
|
|
853
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
854
|
+
for (const credentialConfigurationId of options.credentialConfigurationIds) {
|
|
855
|
+
const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
856
|
+
if (!credentialConfiguration) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in metadata from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
857
|
+
const scope = credentialConfiguration.scope;
|
|
858
|
+
if (scope) scopes.add(scope);
|
|
859
|
+
else if (!scope && options.throwOnConfigurationWithoutScope) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`);
|
|
860
|
+
}
|
|
861
|
+
return scopes.size > 0 ? Array.from(scopes) : void 0;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Transforms draft 11 credentials supported syntax to credential configurations supported
|
|
865
|
+
*
|
|
866
|
+
* @throws if a credentials supported entry without id is passed
|
|
867
|
+
* @throws if a credentials supported entry with invalid structure or format specific properties is passed
|
|
868
|
+
*/
|
|
869
|
+
function credentialsSupportedToCredentialConfigurationsSupported(credentialsSupported) {
|
|
870
|
+
const credentialConfigurationsSupported = {};
|
|
871
|
+
for (let index = 0; index < credentialsSupported.length; index++) {
|
|
872
|
+
const credentialSupported = credentialsSupported[index];
|
|
873
|
+
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`);
|
|
874
|
+
const parseResult = zCredentialConfigurationSupportedDraft11ToV1.safeParse(credentialSupported);
|
|
875
|
+
if (!parseResult.success) throw new ValidationError(`Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`, parseResult.error);
|
|
876
|
+
credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
|
|
877
|
+
}
|
|
878
|
+
return credentialConfigurationsSupported;
|
|
879
|
+
}
|
|
880
|
+
|
|
744
881
|
//#endregion
|
|
745
882
|
//#region src/metadata/credential-issuer/z-signed-credential-issuer-metadata.ts
|
|
746
883
|
const zSignedCredentialIssuerMetadataHeader = z.object({
|
|
@@ -814,161 +951,34 @@ async function fetchCredentialIssuerMetadata(credentialIssuer, options) {
|
|
|
814
951
|
}
|
|
815
952
|
/**
|
|
816
953
|
* Extract credential configuration supported entries where the `format` is known to this
|
|
817
|
-
* library. Should be ran only after verifying
|
|
818
|
-
* we can be certain that if the `format`
|
|
954
|
+
* library and the configuration validates correctly. Should be ran only after verifying
|
|
955
|
+
* the credential issuer metadata structure, so we can be certain that if the `format`
|
|
956
|
+
* matches the other format specific requirements are also met.
|
|
819
957
|
*
|
|
820
958
|
* Validation is done when resolving issuer metadata, or when calling `createIssuerMetadata`.
|
|
821
959
|
*/
|
|
822
960
|
function extractKnownCredentialConfigurationSupportedFormats(credentialConfigurationsSupported) {
|
|
823
|
-
return Object.fromEntries(Object.entries(credentialConfigurationsSupported).filter((entry) =>
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
if (!configuration) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in credential configurations supported.`);
|
|
828
|
-
return configuration;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
//#endregion
|
|
832
|
-
//#region src/credential-request/credential-request-configurations.ts
|
|
833
|
-
function getCredentialConfigurationsMatchingRequestFormat({ requestFormat, credentialConfigurations }) {
|
|
834
|
-
const knownCredentialConfigurations = extractKnownCredentialConfigurationSupportedFormats(credentialConfigurations);
|
|
835
|
-
return Object.fromEntries(Object.entries(knownCredentialConfigurations).filter(([, credentialConfiguration]) => {
|
|
836
|
-
if (credentialConfiguration.format !== requestFormat.format) return false;
|
|
837
|
-
const r = requestFormat;
|
|
838
|
-
const c = credentialConfiguration;
|
|
839
|
-
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"]);
|
|
840
|
-
if (c.format === "jwt_vc_json" && r.format === c.format) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
841
|
-
if (c.format === "vc+sd-jwt" && r.format === c.format) {
|
|
842
|
-
if (r.vct && c.vct) return r.vct === c.vct;
|
|
843
|
-
if (c.credential_definition && r.credential_definition) return arrayEqualsIgnoreOrder(r.credential_definition.type, c.credential_definition.type);
|
|
844
|
-
}
|
|
845
|
-
if (c.format === "mso_mdoc" && r.format === c.format) return r.doctype === c.doctype;
|
|
846
|
-
return false;
|
|
961
|
+
return Object.fromEntries(Object.entries(credentialConfigurationsSupported).filter((entry) => {
|
|
962
|
+
const credentialConfiguration = zCredentialConfigurationSupportedWithFormats.safeParse(entry[1]);
|
|
963
|
+
if (!credentialConfiguration.success) return false;
|
|
964
|
+
return allCredentialIssuerMetadataFormatIdentifiers.includes(credentialConfiguration.data.format);
|
|
847
965
|
}));
|
|
848
966
|
}
|
|
849
|
-
|
|
850
|
-
//#endregion
|
|
851
|
-
//#region src/error/Openid4vciError.ts
|
|
852
|
-
var Openid4vciError = class extends Error {
|
|
853
|
-
constructor(message, options) {
|
|
854
|
-
const errorMessage = message ?? "Unknown error occurred.";
|
|
855
|
-
const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
|
|
856
|
-
super(`${errorMessage}${causeMessage}`);
|
|
857
|
-
this.cause = options?.cause;
|
|
858
|
-
}
|
|
859
|
-
};
|
|
860
|
-
|
|
861
|
-
//#endregion
|
|
862
|
-
//#region src/error/Openid4vciRetrieveCredentialsError.ts
|
|
863
|
-
var Openid4vciRetrieveCredentialsError = class extends Openid4vciError {
|
|
864
|
-
constructor(message, response, responseText) {
|
|
865
|
-
const errorData = response.credentialResponseResult?.data ?? response.credentialErrorResponseResult?.data ?? (response.credentialResponseResult?.error ? formatZodError(response.credentialResponseResult.error) : void 0) ?? responseText;
|
|
866
|
-
super(`${message}\n${JSON.stringify(errorData, null, 2)}`);
|
|
867
|
-
this.response = response;
|
|
868
|
-
}
|
|
869
|
-
};
|
|
870
|
-
|
|
871
|
-
//#endregion
|
|
872
|
-
//#region src/error/Openid4vciSendNotificationError.ts
|
|
873
|
-
var Openid4vciSendNotificationError = class extends Openid4vciError {
|
|
874
|
-
constructor(message, response) {
|
|
875
|
-
super(message);
|
|
876
|
-
this.response = response;
|
|
877
|
-
}
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
//#endregion
|
|
881
|
-
//#region src/key-attestation/key-attestation.ts
|
|
882
|
-
async function createKeyAttestationJwt(options) {
|
|
883
|
-
const header = parseWithErrorHandling(zKeyAttestationJwtHeader, {
|
|
884
|
-
...jwtHeaderFromJwtSigner(options.signer),
|
|
885
|
-
typ: "keyattestation+jwt"
|
|
886
|
-
});
|
|
887
|
-
const payload = parseWithErrorHandling(zKeyAttestationJwtPayloadForUse(options.use), {
|
|
888
|
-
iat: dateToSeconds(options.issuedAt),
|
|
889
|
-
exp: options.expiresAt ? dateToSeconds(options.expiresAt) : void 0,
|
|
890
|
-
nonce: options.nonce,
|
|
891
|
-
attested_keys: options.attestedKeys,
|
|
892
|
-
user_authentication: options.userAuthentication,
|
|
893
|
-
key_storage: options.keyStorage,
|
|
894
|
-
certification: options.certification,
|
|
895
|
-
...options.additionalPayload
|
|
896
|
-
});
|
|
897
|
-
const { jwt } = await options.callbacks.signJwt(options.signer, {
|
|
898
|
-
header,
|
|
899
|
-
payload
|
|
900
|
-
});
|
|
901
|
-
return jwt;
|
|
902
|
-
}
|
|
903
|
-
function parseKeyAttestationJwt({ keyAttestationJwt, use }) {
|
|
904
|
-
return decodeJwt({
|
|
905
|
-
jwt: keyAttestationJwt,
|
|
906
|
-
headerSchema: zKeyAttestationJwtHeader,
|
|
907
|
-
payloadSchema: zKeyAttestationJwtPayloadForUse(use)
|
|
908
|
-
});
|
|
909
|
-
}
|
|
910
|
-
async function verifyKeyAttestationJwt(options) {
|
|
911
|
-
const { header, payload } = parseKeyAttestationJwt({
|
|
912
|
-
keyAttestationJwt: options.keyAttestationJwt,
|
|
913
|
-
use: options.use
|
|
914
|
-
});
|
|
915
|
-
const now = options.now?.getTime() ?? Date.now();
|
|
916
|
-
if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) throw new Openid4vciError("Nonce used for key attestation jwt expired");
|
|
917
|
-
const { signer } = await verifyJwt({
|
|
918
|
-
compact: options.keyAttestationJwt,
|
|
919
|
-
header,
|
|
920
|
-
payload,
|
|
921
|
-
signer: jwtSignerFromJwt({
|
|
922
|
-
header,
|
|
923
|
-
payload
|
|
924
|
-
}),
|
|
925
|
-
verifyJwtCallback: options.callbacks.verifyJwt,
|
|
926
|
-
errorMessage: "Error verifiying key attestation jwt",
|
|
927
|
-
expectedNonce: options.expectedNonce,
|
|
928
|
-
now: options.now
|
|
929
|
-
});
|
|
930
|
-
return {
|
|
931
|
-
header,
|
|
932
|
-
payload,
|
|
933
|
-
signer
|
|
934
|
-
};
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
//#endregion
|
|
938
|
-
//#region src/metadata/credential-issuer/credential-configurations.ts
|
|
939
|
-
function extractScopesForCredentialConfigurationIds(options) {
|
|
940
|
-
const scopes = /* @__PURE__ */ new Set();
|
|
941
|
-
for (const credentialConfigurationId of options.credentialConfigurationIds) {
|
|
942
|
-
const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
943
|
-
if (!credentialConfiguration) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in metadata from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`);
|
|
944
|
-
const scope = credentialConfiguration.scope;
|
|
945
|
-
if (scope) scopes.add(scope);
|
|
946
|
-
else if (!scope && options.throwOnConfigurationWithoutScope) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`);
|
|
947
|
-
}
|
|
948
|
-
return scopes.size > 0 ? Array.from(scopes) : void 0;
|
|
949
|
-
}
|
|
950
967
|
/**
|
|
951
|
-
*
|
|
952
|
-
*
|
|
953
|
-
* @throws if a credentials supported entry without id is passed
|
|
954
|
-
* @throws if a credentials supported entry with invalid structure or format specific properties is passed
|
|
968
|
+
* Get a known credential configuration supported by its id, it will throw an error if the configuration
|
|
969
|
+
* is not found or if its found but the credential configuration is invalid.
|
|
955
970
|
*/
|
|
956
|
-
function
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
const parseResult = zCredentialConfigurationSupportedDraft11ToV1.safeParse(credentialSupported);
|
|
962
|
-
if (!parseResult.success) throw new ValidationError(`Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`, parseResult.error);
|
|
963
|
-
credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
|
|
964
|
-
}
|
|
965
|
-
return credentialConfigurationsSupported;
|
|
971
|
+
function getKnownCredentialConfigurationSupportedById(issuerMetadata, credentialConfigurationId) {
|
|
972
|
+
const configuration = issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
|
|
973
|
+
if (!configuration) throw new Oauth2Error(`Credential configuration with id '${credentialConfigurationId}' not found in credential configurations supported.`);
|
|
974
|
+
if (!issuerMetadata.knownCredentialConfigurations[credentialConfigurationId]) parseWithErrorHandling(zCredentialConfigurationSupportedWithFormats, configuration, `Credential configuration with id '${credentialConfigurationId}' is not valid`);
|
|
975
|
+
return issuerMetadata.knownCredentialConfigurations[credentialConfigurationId];
|
|
966
976
|
}
|
|
967
977
|
|
|
968
978
|
//#endregion
|
|
969
979
|
//#region src/credential-request/format-payload.ts
|
|
970
980
|
function getCredentialRequestFormatPayloadForCredentialConfigurationId(options) {
|
|
971
|
-
const credentialConfiguration =
|
|
981
|
+
const credentialConfiguration = getKnownCredentialConfigurationSupportedById(options.issuerMetadata, options.credentialConfigurationId);
|
|
972
982
|
if (zIs(zLegacySdJwtVcCredentialIssuerMetadataV1, credentialConfiguration) || zIs(zLegacySdJwtVcCredentialIssuerMetadataDraft14, credentialConfiguration)) return {
|
|
973
983
|
format: credentialConfiguration.format,
|
|
974
984
|
vct: credentialConfiguration.vct
|
|
@@ -1246,7 +1256,7 @@ const zDeferredCredentialResponse = zBaseCredentialResponse.superRefine((value,
|
|
|
1246
1256
|
//#region src/credential-request/retrieve-credentials.ts
|
|
1247
1257
|
async function retrieveCredentialsWithCredentialConfigurationId(options) {
|
|
1248
1258
|
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.");
|
|
1249
|
-
|
|
1259
|
+
getKnownCredentialConfigurationSupportedById(options.issuerMetadata, options.credentialConfigurationId);
|
|
1250
1260
|
const credentialRequest = {
|
|
1251
1261
|
...options.additionalRequestPayload,
|
|
1252
1262
|
credential_configuration_id: options.credentialConfigurationId,
|
|
@@ -1457,7 +1467,8 @@ async function resolveIssuerMetadata(credentialIssuer, options) {
|
|
|
1457
1467
|
originalDraftVersion,
|
|
1458
1468
|
credentialIssuer: credentialIssuerMetadata,
|
|
1459
1469
|
signedCredentialIssuer: signed,
|
|
1460
|
-
authorizationServers: authoriationServersMetadata
|
|
1470
|
+
authorizationServers: authoriationServersMetadata,
|
|
1471
|
+
knownCredentialConfigurations: extractKnownCredentialConfigurationSupportedFormats(credentialIssuerMetadata.credential_configurations_supported)
|
|
1461
1472
|
};
|
|
1462
1473
|
}
|
|
1463
1474
|
|
|
@@ -1551,9 +1562,6 @@ var Openid4vciClient = class {
|
|
|
1551
1562
|
this.options = options;
|
|
1552
1563
|
this.oauth2Client = new Oauth2Client({ callbacks: this.options.callbacks });
|
|
1553
1564
|
}
|
|
1554
|
-
getKnownCredentialConfigurationsSupported(credentialIssuerMetadata) {
|
|
1555
|
-
return extractKnownCredentialConfigurationSupportedFormats(credentialIssuerMetadata.credential_configurations_supported);
|
|
1556
|
-
}
|
|
1557
1565
|
/**
|
|
1558
1566
|
* Resolve a credential offer into a credential offer object, handling both
|
|
1559
1567
|
* 'credential_offer' and 'credential_offer_uri' params.
|
|
@@ -1858,9 +1866,9 @@ function parseCredentialRequest(options) {
|
|
|
1858
1866
|
if (knownProof.success && knownProof.data.proof_type === jwtProofTypeIdentifier) proofs = { [jwtProofTypeIdentifier]: [knownProof.data.jwt] };
|
|
1859
1867
|
else if (knownProof.success && knownProof.data.proof_type === attestationProofTypeIdentifier) proofs = { [attestationProofTypeIdentifier]: [knownProof.data.attestation] };
|
|
1860
1868
|
if (credentialRequest.credential_configuration_id) {
|
|
1861
|
-
|
|
1869
|
+
getKnownCredentialConfigurationSupportedById(options.issuerMetadata, credentialRequest.credential_configuration_id);
|
|
1862
1870
|
return {
|
|
1863
|
-
credentialConfiguration:
|
|
1871
|
+
credentialConfiguration: options.issuerMetadata.knownCredentialConfigurations[credentialRequest.credential_configuration_id],
|
|
1864
1872
|
credentialConfigurationId: credentialRequest.credential_configuration_id,
|
|
1865
1873
|
credentialRequest,
|
|
1866
1874
|
proofs
|