@digitalbazaar/oid4-client 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/OID4Client.js +20 -6
- package/lib/index.js +1 -0
- package/lib/util.js +37 -0
- package/package.json +1 -1
package/lib/OID4Client.js
CHANGED
|
@@ -27,7 +27,9 @@ export class OID4Client {
|
|
|
27
27
|
if(!offer) {
|
|
28
28
|
throw new TypeError('"credentialDefinition" must be an object.');
|
|
29
29
|
}
|
|
30
|
-
requests = _createCredentialRequestsFromOffer({
|
|
30
|
+
requests = _createCredentialRequestsFromOffer({
|
|
31
|
+
issuerConfig, offer, format
|
|
32
|
+
});
|
|
31
33
|
if(requests.length > 1) {
|
|
32
34
|
throw new Error(
|
|
33
35
|
'More than one credential is offered; ' +
|
|
@@ -48,7 +50,9 @@ export class OID4Client {
|
|
|
48
50
|
} = {}) {
|
|
49
51
|
const {issuerConfig, offer} = this;
|
|
50
52
|
if(requests === undefined && offer) {
|
|
51
|
-
requests = _createCredentialRequestsFromOffer({
|
|
53
|
+
requests = _createCredentialRequestsFromOffer({
|
|
54
|
+
issuerConfig, offer, format
|
|
55
|
+
});
|
|
52
56
|
} else if(!(Array.isArray(requests) && requests.length > 0)) {
|
|
53
57
|
throw new TypeError('"requests" must be an array of length >= 1.');
|
|
54
58
|
}
|
|
@@ -393,19 +397,29 @@ function _isPresentationRequired(error) {
|
|
|
393
397
|
return error.status === 400 && errorType === 'presentation_required';
|
|
394
398
|
}
|
|
395
399
|
|
|
396
|
-
function _createCredentialRequestsFromOffer({
|
|
400
|
+
function _createCredentialRequestsFromOffer({
|
|
401
|
+
issuerConfig, offer, format
|
|
402
|
+
}) {
|
|
397
403
|
// get any supported credential configurations from issuer config
|
|
398
404
|
const supported = _createSupportedCredentialsMap({issuerConfig});
|
|
399
405
|
|
|
400
|
-
// build requests from credentials identified in `offer`
|
|
406
|
+
// build requests from credentials identified in `offer` and remove any
|
|
407
|
+
// that do not match the given format
|
|
401
408
|
const credentials = offer.credential_configuration_ids ?? offer.credentials;
|
|
402
|
-
|
|
409
|
+
const requests = credentials.map(c => {
|
|
403
410
|
if(typeof c === 'string') {
|
|
404
411
|
// use supported credential config
|
|
405
412
|
return _getSupportedCredentialById({id: c, supported});
|
|
406
413
|
}
|
|
407
414
|
return c;
|
|
408
|
-
});
|
|
415
|
+
}).filter(r => r.format === format);
|
|
416
|
+
|
|
417
|
+
if(requests.length === 0) {
|
|
418
|
+
throw new Error(
|
|
419
|
+
`No supported credential(s) with format "${format}" found.`);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return requests;
|
|
409
423
|
}
|
|
410
424
|
|
|
411
425
|
function _createSupportedCredentialsMap({issuerConfig}) {
|
package/lib/index.js
CHANGED
package/lib/util.js
CHANGED
|
@@ -162,6 +162,43 @@ export async function generateDIDProofJWT({
|
|
|
162
162
|
return signJWT({payload, protectedHeader, signer});
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
export async function getCredentialOffer({url, agent} = {}) {
|
|
166
|
+
const {protocol, searchParams} = new URL(url);
|
|
167
|
+
if(protocol !== 'openid-credential-offer:') {
|
|
168
|
+
throw new SyntaxError(
|
|
169
|
+
'"url" must express a URL with the ' +
|
|
170
|
+
'"openid-credential-offer" protocol.');
|
|
171
|
+
}
|
|
172
|
+
const offer = searchParams.get('credential_offer');
|
|
173
|
+
if(offer) {
|
|
174
|
+
return JSON.parse(offer);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// try to fetch offer from URL
|
|
178
|
+
const offerUrl = searchParams.get('credential_offer_uri');
|
|
179
|
+
if(!offerUrl) {
|
|
180
|
+
throw new SyntaxError(
|
|
181
|
+
'OID4VCI credential offer must have "credential_offer" or ' +
|
|
182
|
+
'"credential_offer_uri".');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if(!offerUrl.startsWith('https://')) {
|
|
186
|
+
const error = new Error(
|
|
187
|
+
`"credential_offer_uri" (${offerUrl}) must start with "https://".`);
|
|
188
|
+
error.name = 'NotSupportedError';
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const response = await fetchJSON({url: offerUrl, agent});
|
|
193
|
+
if(!response.data) {
|
|
194
|
+
const error = new Error(
|
|
195
|
+
`Credential offer fetched from "${offerUrl}" is not JSON.`);
|
|
196
|
+
error.name = 'DataError';
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
return response.data;
|
|
200
|
+
}
|
|
201
|
+
|
|
165
202
|
export function parseCredentialOfferUrl({url} = {}) {
|
|
166
203
|
assert(url, 'url', 'string');
|
|
167
204
|
|