@sphereon/oid4vci-client 0.10.4-unstable.98 → 0.12.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/README.md +7 -7
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +5 -6
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
- package/dist/AccessTokenClientV1_0_11.js +3 -5
- package/dist/AccessTokenClientV1_0_11.js.map +1 -1
- package/dist/AuthorizationCodeClient.d.ts +4 -1
- package/dist/AuthorizationCodeClient.d.ts.map +1 -1
- package/dist/AuthorizationCodeClient.js +47 -8
- package/dist/AuthorizationCodeClient.js.map +1 -1
- package/dist/AuthorizationCodeClientV1_0_11.d.ts.map +1 -1
- package/dist/AuthorizationCodeClientV1_0_11.js +5 -3
- package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -1
- package/dist/CredentialOfferClient.d.ts.map +1 -1
- package/dist/CredentialOfferClient.js +26 -12
- package/dist/CredentialOfferClient.js.map +1 -1
- package/dist/CredentialOfferClientV1_0_11.js +6 -7
- package/dist/CredentialOfferClientV1_0_11.js.map +1 -1
- package/dist/CredentialOfferClientV1_0_13.d.ts +10 -0
- package/dist/CredentialOfferClientV1_0_13.d.ts.map +1 -0
- package/dist/CredentialOfferClientV1_0_13.js +94 -0
- package/dist/CredentialOfferClientV1_0_13.js.map +1 -0
- package/dist/CredentialRequestClient.js +1 -1
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_11.d.ts +3 -1
- package/dist/CredentialRequestClientBuilderV1_0_11.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_11.js +4 -0
- package/dist/CredentialRequestClientBuilderV1_0_11.js.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.d.ts +9 -3
- package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.js +2 -1
- package/dist/CredentialRequestClientV1_0_11.js.map +1 -1
- package/dist/MetadataClient.d.ts +5 -5
- package/dist/MetadataClient.d.ts.map +1 -1
- package/dist/MetadataClient.js +30 -13
- package/dist/MetadataClient.js.map +1 -1
- package/dist/MetadataClientV1_0_13.d.ts +31 -0
- package/dist/MetadataClientV1_0_13.d.ts.map +1 -0
- package/dist/MetadataClientV1_0_13.js +181 -0
- package/dist/MetadataClientV1_0_13.js.map +1 -0
- package/dist/OpenID4VCIClient.d.ts +13 -24
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +126 -103
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.d.ts +3 -2
- package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.js +5 -18
- package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.d.ts +112 -0
- package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -0
- package/dist/OpenID4VCIClientV1_0_13.js +478 -0
- package/dist/OpenID4VCIClientV1_0_13.js.map +1 -0
- package/dist/ProofOfPossessionBuilder.d.ts +14 -3
- package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
- package/dist/ProofOfPossessionBuilder.js +20 -20
- package/dist/ProofOfPossessionBuilder.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/lib/AccessTokenClient.ts +5 -11
- package/lib/AccessTokenClientV1_0_11.ts +3 -9
- package/lib/AuthorizationCodeClient.ts +47 -8
- package/lib/AuthorizationCodeClientV1_0_11.ts +8 -6
- package/lib/CredentialOfferClient.ts +31 -9
- package/lib/CredentialOfferClientV1_0_11.ts +6 -6
- package/lib/CredentialOfferClientV1_0_13.ts +103 -0
- package/lib/CredentialRequestClient.ts +1 -1
- package/lib/CredentialRequestClientBuilderV1_0_11.ts +7 -0
- package/lib/CredentialRequestClientV1_0_11.ts +9 -4
- package/lib/MetadataClient.ts +49 -14
- package/lib/MetadataClientV1_0_13.ts +188 -0
- package/lib/OpenID4VCIClient.ts +131 -115
- package/lib/OpenID4VCIClientV1_0_11.ts +9 -19
- package/lib/OpenID4VCIClientV1_0_13.ts +677 -0
- package/lib/ProofOfPossessionBuilder.ts +40 -9
- package/lib/__tests__/CredentialRequestClientV1_0_11.spec.ts +2 -2
- package/lib/__tests__/MetadataClient.spec.ts +3 -4
- package/lib/__tests__/MetadataMocks.ts +1 -0
- package/lib/__tests__/OpenID4VCIClient.spec.ts +42 -9
- package/lib/__tests__/OpenID4VCIClientV1_0_11.spec.ts +24 -0
- package/lib/__tests__/OpenID4VCIClientV1_0_13.spec.ts +204 -0
- package/lib/__tests__/SdJwt.spec.ts +2 -2
- package/lib/__tests__/SphereonE2E.spec.test.ts +4 -3
- package/lib/index.ts +8 -0
- package/package.json +4 -4
package/lib/OpenID4VCIClient.ts
CHANGED
|
@@ -5,17 +5,23 @@ import {
|
|
|
5
5
|
AuthorizationResponse,
|
|
6
6
|
AuthzFlowType,
|
|
7
7
|
CodeChallengeMethod,
|
|
8
|
+
CredentialConfigurationSupported,
|
|
8
9
|
CredentialConfigurationSupportedV1_0_13,
|
|
9
|
-
|
|
10
|
+
CredentialOfferPayloadV1_0_08,
|
|
11
|
+
CredentialOfferPayloadV1_0_11,
|
|
10
12
|
CredentialOfferRequestWithBaseUrl,
|
|
11
13
|
CredentialResponse,
|
|
14
|
+
CredentialsSupportedLegacy,
|
|
12
15
|
DefaultURISchemes,
|
|
16
|
+
determineVersionsFromIssuerMetadata,
|
|
17
|
+
EndpointMetadataResultV1_0_11,
|
|
13
18
|
EndpointMetadataResultV1_0_13,
|
|
14
19
|
ExperimentalSubjectIssuance,
|
|
15
20
|
getClientIdFromCredentialOfferPayload,
|
|
16
21
|
getIssuerFromCredentialOfferPayload,
|
|
17
22
|
getSupportedCredentials,
|
|
18
23
|
getTypesFromCredentialSupported,
|
|
24
|
+
getTypesFromObject,
|
|
19
25
|
JWK,
|
|
20
26
|
KID_JWK_X5C_ERROR,
|
|
21
27
|
NotificationRequest,
|
|
@@ -30,32 +36,24 @@ import { CredentialFormat } from '@sphereon/ssi-types';
|
|
|
30
36
|
import Debug from 'debug';
|
|
31
37
|
|
|
32
38
|
import { AccessTokenClient } from './AccessTokenClient';
|
|
39
|
+
import { AccessTokenClientV1_0_11 } from './AccessTokenClientV1_0_11';
|
|
33
40
|
import { createAuthorizationRequestUrl } from './AuthorizationCodeClient';
|
|
41
|
+
import { createAuthorizationRequestUrlV1_0_11 } from './AuthorizationCodeClientV1_0_11';
|
|
34
42
|
import { CredentialOfferClient } from './CredentialOfferClient';
|
|
35
43
|
import { CredentialRequestOpts } from './CredentialRequestClient';
|
|
36
44
|
import { CredentialRequestClientBuilder } from './CredentialRequestClientBuilder';
|
|
45
|
+
import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
|
|
37
46
|
import { MetadataClient } from './MetadataClient';
|
|
47
|
+
import { OpenID4VCIClientStateV1_0_11 } from './OpenID4VCIClientV1_0_11';
|
|
48
|
+
import { OpenID4VCIClientStateV1_0_13 } from './OpenID4VCIClientV1_0_13';
|
|
38
49
|
import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
|
|
39
|
-
import { generateMissingPKCEOpts } from './functions
|
|
40
|
-
import { sendNotification } from './functions/notifications';
|
|
50
|
+
import { generateMissingPKCEOpts, sendNotification } from './functions';
|
|
41
51
|
|
|
42
52
|
const debug = Debug('sphereon:oid4vci');
|
|
43
53
|
|
|
44
|
-
export
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
clientId?: string;
|
|
48
|
-
kid?: string;
|
|
49
|
-
jwk?: JWK;
|
|
50
|
-
alg?: Alg | string;
|
|
51
|
-
endpointMetadata?: EndpointMetadataResultV1_0_13;
|
|
52
|
-
accessTokenResponse?: AccessTokenResponse;
|
|
53
|
-
authorizationRequestOpts?: AuthorizationRequestOpts;
|
|
54
|
-
authorizationCodeResponse?: AuthorizationResponse;
|
|
55
|
-
pkce: PKCEOpts;
|
|
56
|
-
accessToken?: string;
|
|
57
|
-
authorizationURL?: string;
|
|
58
|
-
}
|
|
54
|
+
export type OpenID4VCIClientState = OpenID4VCIClientStateV1_0_11 | OpenID4VCIClientStateV1_0_13;
|
|
55
|
+
|
|
56
|
+
export type EndpointMetadataResult = EndpointMetadataResultV1_0_11 | EndpointMetadataResultV1_0_13;
|
|
59
57
|
|
|
60
58
|
export class OpenID4VCIClient {
|
|
61
59
|
private readonly _state: OpenID4VCIClientState;
|
|
@@ -85,7 +83,7 @@ export class OpenID4VCIClient {
|
|
|
85
83
|
authorizationRequest?: AuthorizationRequestOpts; // Can be provided here, or when manually calling createAuthorizationUrl
|
|
86
84
|
jwk?: JWK;
|
|
87
85
|
accessToken?: string;
|
|
88
|
-
endpointMetadata?:
|
|
86
|
+
endpointMetadata?: EndpointMetadataResult;
|
|
89
87
|
accessTokenResponse?: AccessTokenResponse;
|
|
90
88
|
authorizationRequestOpts?: AuthorizationRequestOpts;
|
|
91
89
|
authorizationCodeResponse?: AuthorizationResponse;
|
|
@@ -105,12 +103,13 @@ export class OpenID4VCIClient {
|
|
|
105
103
|
pkce: { disabled: false, codeChallengeMethod: CodeChallengeMethod.S256, ...pkce },
|
|
106
104
|
authorizationRequestOpts,
|
|
107
105
|
authorizationCodeResponse,
|
|
108
|
-
accessToken,
|
|
109
106
|
jwk,
|
|
110
|
-
endpointMetadata
|
|
107
|
+
endpointMetadata: endpointMetadata?.credentialIssuerMetadata?.authorization_server
|
|
108
|
+
? (endpointMetadata as EndpointMetadataResultV1_0_11)
|
|
109
|
+
: (endpointMetadata as EndpointMetadataResultV1_0_13 | undefined),
|
|
111
110
|
accessTokenResponse,
|
|
112
111
|
authorizationURL,
|
|
113
|
-
};
|
|
112
|
+
} as OpenID4VCIClientState;
|
|
114
113
|
// Running syncAuthorizationRequestOpts later as it is using the state
|
|
115
114
|
if (!this._state.authorizationRequestOpts) {
|
|
116
115
|
this._state.authorizationRequestOpts = this.syncAuthorizationRequestOpts(authorizationRequest);
|
|
@@ -227,19 +226,28 @@ export class OpenID4VCIClient {
|
|
|
227
226
|
) {
|
|
228
227
|
this._state.endpointMetadata.authorization_endpoint = this._state.endpointMetadata.credentialIssuerMetadata.authorization_endpoint as string;
|
|
229
228
|
}
|
|
230
|
-
this.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
229
|
+
if (this.version() <= OpenId4VCIVersion.VER_1_0_11) {
|
|
230
|
+
this._state.authorizationURL = await createAuthorizationRequestUrlV1_0_11({
|
|
231
|
+
pkce: this._state.pkce,
|
|
232
|
+
endpointMetadata: this.endpointMetadata as EndpointMetadataResultV1_0_11,
|
|
233
|
+
authorizationRequest: this._state.authorizationRequestOpts,
|
|
234
|
+
credentialOffer: this.credentialOffer,
|
|
235
|
+
credentialsSupported: Object.values(this.getCredentialsSupported(true)) as CredentialsSupportedLegacy[],
|
|
236
|
+
});
|
|
237
|
+
} else {
|
|
238
|
+
this._state.authorizationURL = await createAuthorizationRequestUrl({
|
|
239
|
+
pkce: this._state.pkce,
|
|
240
|
+
endpointMetadata: this.endpointMetadata as EndpointMetadataResultV1_0_13,
|
|
241
|
+
authorizationRequest: this._state.authorizationRequestOpts,
|
|
242
|
+
credentialOffer: this.credentialOffer,
|
|
243
|
+
credentialConfigurationSupported: this.getCredentialsSupported(false) as Record<string, CredentialConfigurationSupportedV1_0_13>,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
238
246
|
}
|
|
239
247
|
return this._state.authorizationURL;
|
|
240
248
|
}
|
|
241
249
|
|
|
242
|
-
public async retrieveServerMetadata(): Promise<
|
|
250
|
+
public async retrieveServerMetadata(): Promise<EndpointMetadataResult> {
|
|
243
251
|
this.assertIssuerData();
|
|
244
252
|
if (!this._state.endpointMetadata) {
|
|
245
253
|
if (this.credentialOffer) {
|
|
@@ -284,7 +292,7 @@ export class OpenID4VCIClient {
|
|
|
284
292
|
this._state.clientId = clientId;
|
|
285
293
|
}
|
|
286
294
|
if (!this._state.accessTokenResponse) {
|
|
287
|
-
const accessTokenClient = new AccessTokenClient();
|
|
295
|
+
const accessTokenClient = this.version() <= OpenId4VCIVersion.VER_1_0_12 ? new AccessTokenClientV1_0_11() : new AccessTokenClient();
|
|
288
296
|
|
|
289
297
|
if (redirectUri && redirectUri !== this._state.authorizationRequestOpts?.redirectUri) {
|
|
290
298
|
console.log(
|
|
@@ -294,6 +302,7 @@ export class OpenID4VCIClient {
|
|
|
294
302
|
if (this._state.authorizationRequestOpts?.redirectUri && !redirectUri) {
|
|
295
303
|
redirectUri = this._state.authorizationRequestOpts.redirectUri;
|
|
296
304
|
}
|
|
305
|
+
|
|
297
306
|
const response = await accessTokenClient.acquireAccessToken({
|
|
298
307
|
credentialOffer: this.credentialOffer,
|
|
299
308
|
metadata: this.endpointMetadata,
|
|
@@ -328,7 +337,6 @@ export class OpenID4VCIClient {
|
|
|
328
337
|
}
|
|
329
338
|
|
|
330
339
|
public async acquireCredentials({
|
|
331
|
-
credentialIdentifier,
|
|
332
340
|
credentialTypes,
|
|
333
341
|
context,
|
|
334
342
|
proofCallbacks,
|
|
@@ -340,8 +348,7 @@ export class OpenID4VCIClient {
|
|
|
340
348
|
deferredCredentialAwait,
|
|
341
349
|
deferredCredentialIntervalInMS,
|
|
342
350
|
}: {
|
|
343
|
-
|
|
344
|
-
credentialTypes?: string | string[];
|
|
351
|
+
credentialTypes: string | string[];
|
|
345
352
|
context?: string[];
|
|
346
353
|
proofCallbacks: ProofOfPossessionCallbacks<any>;
|
|
347
354
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
@@ -361,38 +368,41 @@ export class OpenID4VCIClient {
|
|
|
361
368
|
if (jwk) this._state.jwk = jwk;
|
|
362
369
|
if (kid) this._state.kid = kid;
|
|
363
370
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
371
|
+
let requestBuilder: CredentialRequestClientBuilder | CredentialRequestClientBuilderV1_0_11;
|
|
372
|
+
if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
|
|
373
|
+
requestBuilder = this.credentialOffer
|
|
374
|
+
? CredentialRequestClientBuilderV1_0_11.fromCredentialOffer({
|
|
375
|
+
credentialOffer: this.credentialOffer,
|
|
376
|
+
metadata: this.endpointMetadata,
|
|
377
|
+
})
|
|
378
|
+
: CredentialRequestClientBuilderV1_0_11.fromCredentialIssuer({
|
|
379
|
+
credentialIssuer: this.getIssuer(),
|
|
380
|
+
credentialTypes,
|
|
381
|
+
metadata: this.endpointMetadata,
|
|
382
|
+
version: this.version(),
|
|
383
|
+
});
|
|
384
|
+
} else {
|
|
385
|
+
requestBuilder = this.credentialOffer
|
|
386
|
+
? CredentialRequestClientBuilder.fromCredentialOffer({
|
|
387
|
+
credentialOffer: this.credentialOffer,
|
|
388
|
+
metadata: this.endpointMetadata,
|
|
389
|
+
})
|
|
390
|
+
: CredentialRequestClientBuilder.fromCredentialIssuer({
|
|
391
|
+
credentialIssuer: this.getIssuer(),
|
|
392
|
+
credentialTypes,
|
|
393
|
+
metadata: this.endpointMetadata,
|
|
394
|
+
version: this.version(),
|
|
395
|
+
});
|
|
396
|
+
}
|
|
375
397
|
|
|
376
398
|
requestBuilder.withTokenFromResponse(this.accessTokenResponse);
|
|
377
399
|
requestBuilder.withDeferredCredentialAwait(deferredCredentialAwait ?? false, deferredCredentialIntervalInMS);
|
|
378
400
|
let subjectIssuance: ExperimentalSubjectIssuance | undefined;
|
|
379
401
|
if (this.endpointMetadata?.credentialIssuerMetadata) {
|
|
380
402
|
const metadata = this.endpointMetadata.credentialIssuerMetadata;
|
|
381
|
-
const types =
|
|
403
|
+
const types = Array.isArray(credentialTypes) ? credentialTypes : [credentialTypes];
|
|
382
404
|
|
|
383
|
-
if (
|
|
384
|
-
if (typeof metadata.credential_configurations_supported !== 'object') {
|
|
385
|
-
throw Error(
|
|
386
|
-
`Credentials_supported should be an object, current ${typeof metadata.credential_configurations_supported} when credential_identifier is used`,
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
const credentialsSupported = metadata.credential_configurations_supported;
|
|
390
|
-
if (!metadata.credential_configurations_supported || !credentialsSupported[credentialIdentifier]) {
|
|
391
|
-
throw new Error(`Credential type ${credentialIdentifier} is not supported by issuer ${this.getIssuer()}`);
|
|
392
|
-
}
|
|
393
|
-
} else if (!types) {
|
|
394
|
-
throw Error(`If no credential_identifier is used, we expect types`);
|
|
395
|
-
} else if (metadata.credentials_supported && Array.isArray(metadata.credentials_supported)) {
|
|
405
|
+
if (metadata.credentials_supported && Array.isArray(metadata.credentials_supported)) {
|
|
396
406
|
let typeSupported = false;
|
|
397
407
|
|
|
398
408
|
metadata.credentials_supported.forEach((supportedCredential) => {
|
|
@@ -412,9 +422,9 @@ export class OpenID4VCIClient {
|
|
|
412
422
|
console.log(`Not all credential types ${JSON.stringify(credentialTypes)} are present in metadata for ${this.getIssuer()}`);
|
|
413
423
|
// throw Error(`Not all credential types ${JSON.stringify(credentialTypes)} are supported by issuer ${this.getIssuer()}`);
|
|
414
424
|
}
|
|
415
|
-
} else if (metadata.
|
|
416
|
-
const credentialsSupported = metadata.
|
|
417
|
-
if (types.some((type) => !metadata.
|
|
425
|
+
} else if (metadata.credentials_supported && !Array.isArray(metadata.credentials_supported)) {
|
|
426
|
+
const credentialsSupported = metadata.credentials_supported;
|
|
427
|
+
if (types.some((type) => !metadata.credentials_supported || !credentialsSupported[type])) {
|
|
418
428
|
throw Error(`Not all credential types ${JSON.stringify(credentialTypes)} are supported by issuer ${this.getIssuer()}`);
|
|
419
429
|
}
|
|
420
430
|
}
|
|
@@ -448,7 +458,10 @@ export class OpenID4VCIClient {
|
|
|
448
458
|
}
|
|
449
459
|
const response = await credentialRequestClient.acquireCredentialsUsingProof({
|
|
450
460
|
proofInput: proofBuilder,
|
|
451
|
-
|
|
461
|
+
credentialTypes,
|
|
462
|
+
context,
|
|
463
|
+
format,
|
|
464
|
+
subjectIssuance,
|
|
452
465
|
});
|
|
453
466
|
if (response.errorBody) {
|
|
454
467
|
debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
|
|
@@ -473,13 +486,14 @@ export class OpenID4VCIClient {
|
|
|
473
486
|
}
|
|
474
487
|
|
|
475
488
|
getCredentialsSupported(
|
|
489
|
+
restrictToInitiationTypes?: boolean,
|
|
476
490
|
format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[],
|
|
477
|
-
): Record<string, CredentialConfigurationSupportedV1_0_13> {
|
|
491
|
+
): Record<string, CredentialConfigurationSupportedV1_0_13> | Array<CredentialConfigurationSupported> {
|
|
478
492
|
return getSupportedCredentials({
|
|
479
493
|
issuerMetadata: this.endpointMetadata.credentialIssuerMetadata,
|
|
480
494
|
version: this.version(),
|
|
481
495
|
format: format,
|
|
482
|
-
types: undefined,
|
|
496
|
+
types: restrictToInitiationTypes ? this.getCredentialOfferTypes() : undefined,
|
|
483
497
|
});
|
|
484
498
|
}
|
|
485
499
|
|
|
@@ -491,34 +505,28 @@ export class OpenID4VCIClient {
|
|
|
491
505
|
return sendNotification(credentialRequestOpts, request, accessToken ?? this._state.accessToken ?? this._state.accessTokenResponse?.access_token);
|
|
492
506
|
}
|
|
493
507
|
|
|
494
|
-
|
|
508
|
+
getCredentialOfferTypes(): string[][] | undefined {
|
|
495
509
|
if (!this.credentialOffer) {
|
|
496
510
|
return [];
|
|
497
|
-
} else if (this.
|
|
511
|
+
} else if (this.version() < OpenId4VCIVersion.VER_1_0_11) {
|
|
498
512
|
const orig = this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08;
|
|
499
513
|
const types: string[] = typeof orig.credential_type === 'string' ? [orig.credential_type] : orig.credential_type;
|
|
500
514
|
const result: string[][] = [];
|
|
501
515
|
result[0] = types;
|
|
502
516
|
return result;
|
|
503
|
-
} else {
|
|
504
|
-
return this.credentialOffer.credential_offer.credentials.map((c) =>
|
|
505
|
-
if (typeof c === 'string') {
|
|
506
|
-
return [c];
|
|
507
|
-
} else if ('types' in c) {
|
|
508
|
-
return c.types;
|
|
509
|
-
} else if ('vct' in c) {
|
|
510
|
-
return [c.vct];
|
|
511
|
-
} else {
|
|
512
|
-
return c.credential_definition.types;
|
|
513
|
-
}
|
|
514
|
-
});
|
|
517
|
+
} else if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
|
|
518
|
+
return (this.credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials.map((c) => getTypesFromObject(c) ?? []);
|
|
515
519
|
}
|
|
516
|
-
|
|
520
|
+
// we don't have this for v13. v13 only has credential_configuration_ids which is not translatable to type
|
|
521
|
+
return undefined;
|
|
522
|
+
}
|
|
517
523
|
|
|
518
524
|
issuerSupportedFlowTypes(): AuthzFlowType[] {
|
|
519
525
|
return (
|
|
520
526
|
this.credentialOffer?.supportedFlows ??
|
|
521
|
-
(this._state.endpointMetadata?.credentialIssuerMetadata?.authorization_endpoint
|
|
527
|
+
(this._state.endpointMetadata?.credentialIssuerMetadata?.authorization_endpoint ?? this._state.endpointMetadata?.authorization_server
|
|
528
|
+
? [AuthzFlowType.AUTHORIZATION_CODE_FLOW]
|
|
529
|
+
: [])
|
|
522
530
|
);
|
|
523
531
|
}
|
|
524
532
|
|
|
@@ -526,23 +534,33 @@ export class OpenID4VCIClient {
|
|
|
526
534
|
return this.issuerSupportedFlowTypes().includes(flowType);
|
|
527
535
|
}
|
|
528
536
|
|
|
529
|
-
public hasAuthorizationURL(): boolean {
|
|
530
|
-
return !!this.authorizationURL;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
537
|
get authorizationURL(): string | undefined {
|
|
534
538
|
return this._state.authorizationURL;
|
|
535
539
|
}
|
|
536
540
|
|
|
541
|
+
public hasAuthorizationURL(): boolean {
|
|
542
|
+
return !!this.authorizationURL;
|
|
543
|
+
}
|
|
544
|
+
|
|
537
545
|
get credentialOffer(): CredentialOfferRequestWithBaseUrl | undefined {
|
|
538
546
|
return this._state.credentialOffer;
|
|
539
547
|
}
|
|
540
548
|
|
|
541
549
|
public version(): OpenId4VCIVersion {
|
|
542
|
-
|
|
550
|
+
if (this.credentialOffer?.version && this.credentialOffer.version !== OpenId4VCIVersion.VER_UNKNOWN) {
|
|
551
|
+
return this.credentialOffer.version;
|
|
552
|
+
}
|
|
553
|
+
const metadata = this._state.endpointMetadata;
|
|
554
|
+
if (metadata?.credentialIssuerMetadata) {
|
|
555
|
+
const versions = determineVersionsFromIssuerMetadata(metadata.credentialIssuerMetadata);
|
|
556
|
+
if (versions.length > 0 && !versions.includes(OpenId4VCIVersion.VER_UNKNOWN)) {
|
|
557
|
+
return versions[0];
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return OpenId4VCIVersion.VER_1_0_13;
|
|
543
561
|
}
|
|
544
562
|
|
|
545
|
-
public get endpointMetadata():
|
|
563
|
+
public get endpointMetadata(): EndpointMetadataResult {
|
|
546
564
|
this.assertServerMetadata();
|
|
547
565
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
548
566
|
return this._state.endpointMetadata!;
|
|
@@ -589,8 +607,11 @@ export class OpenID4VCIClient {
|
|
|
589
607
|
|
|
590
608
|
public getAccessTokenEndpoint(): string {
|
|
591
609
|
this.assertIssuerData();
|
|
592
|
-
|
|
593
|
-
|
|
610
|
+
if (this.endpointMetadata) {
|
|
611
|
+
return this.endpointMetadata.token_endpoint;
|
|
612
|
+
}
|
|
613
|
+
return this.version() <= OpenId4VCIVersion.VER_1_0_12
|
|
614
|
+
? AccessTokenClientV1_0_11.determineTokenURL({ issuerOpts: { issuer: this.getIssuer() } })
|
|
594
615
|
: AccessTokenClient.determineTokenURL({ issuerOpts: { issuer: this.getIssuer() } });
|
|
595
616
|
}
|
|
596
617
|
|
|
@@ -611,33 +632,23 @@ export class OpenID4VCIClient {
|
|
|
611
632
|
/**
|
|
612
633
|
* Too bad we need a method like this, but EBSI is not exposing metadata
|
|
613
634
|
*/
|
|
614
|
-
public isEBSI()
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
if (credentialConfigurations) {
|
|
621
|
-
const isEBSITrustFramework = credentialOffer.credential_configuration_ids
|
|
622
|
-
.map((id) => credentialConfigurations[id])
|
|
623
|
-
.filter(
|
|
624
|
-
(config): config is CredentialConfigurationSupportedV1_0_13 =>
|
|
625
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
626
|
-
// @ts-ignore
|
|
627
|
-
config !== undefined && 'trust_framework' in config && 'name' in config.trust_framework,
|
|
628
|
-
)
|
|
635
|
+
public isEBSI() {
|
|
636
|
+
if (
|
|
637
|
+
this.credentialOffer &&
|
|
638
|
+
(this.credentialOffer?.credential_offer as CredentialOfferPayloadV1_0_11)?.credentials?.find(
|
|
639
|
+
(cred) =>
|
|
629
640
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
630
641
|
// @ts-ignore
|
|
631
|
-
.
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}
|
|
636
|
-
}
|
|
642
|
+
typeof cred !== 'string' && 'trust_framework' in cred && 'name' in cred.trust_framework && cred.trust_framework.name.includes('ebsi'),
|
|
643
|
+
)
|
|
644
|
+
) {
|
|
645
|
+
return true;
|
|
637
646
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
647
|
+
// this.assertIssuerData();
|
|
648
|
+
return (
|
|
649
|
+
this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ||
|
|
650
|
+
this.endpointMetadata.credentialIssuerMetadata?.authorization_server?.includes('ebsi.eu')
|
|
651
|
+
);
|
|
641
652
|
}
|
|
642
653
|
|
|
643
654
|
private assertIssuerData(): void {
|
|
@@ -661,7 +672,12 @@ export class OpenID4VCIClient {
|
|
|
661
672
|
}
|
|
662
673
|
|
|
663
674
|
private syncAuthorizationRequestOpts(opts?: AuthorizationRequestOpts): AuthorizationRequestOpts {
|
|
664
|
-
|
|
675
|
+
const requestObjectOpts = { ...this._state?.authorizationRequestOpts?.requestObjectOpts, ...opts?.requestObjectOpts };
|
|
676
|
+
let authorizationRequestOpts = {
|
|
677
|
+
...this._state?.authorizationRequestOpts,
|
|
678
|
+
...opts,
|
|
679
|
+
...(requestObjectOpts && { requestObjectOpts }),
|
|
680
|
+
} as AuthorizationRequestOpts;
|
|
665
681
|
if (!authorizationRequestOpts) {
|
|
666
682
|
// We only set a redirectUri if no options are provided.
|
|
667
683
|
// Note that this only works for mobile apps, that can handle a code query param on the default openid-credential-offer deeplink.
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getIssuerFromCredentialOfferPayload,
|
|
18
18
|
getSupportedCredentials,
|
|
19
19
|
getTypesFromCredentialSupported,
|
|
20
|
+
getTypesFromObject,
|
|
20
21
|
JWK,
|
|
21
22
|
KID_JWK_X5C_ERROR,
|
|
22
23
|
OID4VCICredentialFormat,
|
|
@@ -50,6 +51,7 @@ export interface OpenID4VCIClientStateV1_0_11 {
|
|
|
50
51
|
authorizationRequestOpts?: AuthorizationRequestOpts;
|
|
51
52
|
authorizationCodeResponse?: AuthorizationResponse;
|
|
52
53
|
pkce: PKCEOpts;
|
|
54
|
+
accessToken?: string;
|
|
53
55
|
authorizationURL?: string;
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -212,7 +214,7 @@ export class OpenID4VCIClientV1_0_11 {
|
|
|
212
214
|
throw Error(`No Authorization Request options present or provided in this call`);
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
// todo: Probably can go with current logic in
|
|
217
|
+
// todo: Probably can go with current logic in MetadataClientV1_0_13 who will always set the authorization_endpoint when found
|
|
216
218
|
// handling this because of the support for v1_0-08
|
|
217
219
|
if (
|
|
218
220
|
this._state.endpointMetadata?.credentialIssuerMetadata &&
|
|
@@ -459,15 +461,13 @@ export class OpenID4VCIClientV1_0_11 {
|
|
|
459
461
|
}) as Record<string, CredentialConfigurationSupported>;
|
|
460
462
|
}
|
|
461
463
|
|
|
462
|
-
getCredentialsSupported(
|
|
463
|
-
format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[],
|
|
464
|
-
): Record<string, CredentialConfigurationSupported> {
|
|
464
|
+
getCredentialsSupported(format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[]): CredentialConfigurationSupported[] {
|
|
465
465
|
return getSupportedCredentials({
|
|
466
466
|
issuerMetadata: this.endpointMetadata.credentialIssuerMetadata,
|
|
467
467
|
version: this.version(),
|
|
468
468
|
format: format,
|
|
469
469
|
types: undefined,
|
|
470
|
-
}) as
|
|
470
|
+
}) as CredentialConfigurationSupported[];
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
getCredentialOfferTypes(): string[][] {
|
|
@@ -480,20 +480,10 @@ export class OpenID4VCIClientV1_0_11 {
|
|
|
480
480
|
result[0] = types;
|
|
481
481
|
return result;
|
|
482
482
|
} else if (this.credentialOffer.version < OpenId4VCIVersion.VER_1_0_13) {
|
|
483
|
-
return (this.credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials.map((c) =>
|
|
484
|
-
if (typeof c === 'string') {
|
|
485
|
-
return [c];
|
|
486
|
-
} else if ('types' in c) {
|
|
487
|
-
return c.types;
|
|
488
|
-
} else if ('vct' in c) {
|
|
489
|
-
return [c.vct];
|
|
490
|
-
} else {
|
|
491
|
-
return c.credential_definition.types;
|
|
492
|
-
}
|
|
493
|
-
});
|
|
483
|
+
return (this.credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials.map((c) => getTypesFromObject(c) ?? []);
|
|
494
484
|
}
|
|
495
|
-
// we don't
|
|
496
|
-
|
|
485
|
+
// we don't support > V11
|
|
486
|
+
throw Error(`This class only supports version 11 and lower! Version: ${this.version()}`);
|
|
497
487
|
}
|
|
498
488
|
|
|
499
489
|
issuerSupportedFlowTypes(): AuthzFlowType[] {
|
|
@@ -605,7 +595,7 @@ export class OpenID4VCIClientV1_0_11 {
|
|
|
605
595
|
return true;
|
|
606
596
|
}
|
|
607
597
|
this.assertIssuerData();
|
|
608
|
-
return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu');
|
|
598
|
+
return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') === true;
|
|
609
599
|
}
|
|
610
600
|
|
|
611
601
|
private assertIssuerData(): void {
|