@sphereon/oid4vci-client 0.12.1-unstable.9 → 0.13.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.
Files changed (48) hide show
  1. package/dist/AccessTokenClient.d.ts.map +1 -1
  2. package/dist/AccessTokenClient.js +11 -5
  3. package/dist/AccessTokenClient.js.map +1 -1
  4. package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
  5. package/dist/AccessTokenClientV1_0_11.js +12 -5
  6. package/dist/AccessTokenClientV1_0_11.js.map +1 -1
  7. package/dist/AuthorizationCodeClient.js +2 -2
  8. package/dist/CredentialRequestClientBuilder.d.ts.map +1 -1
  9. package/dist/CredentialRequestClientBuilder.js.map +1 -1
  10. package/dist/OpenID4VCIClient.d.ts +3 -1
  11. package/dist/OpenID4VCIClient.d.ts.map +1 -1
  12. package/dist/OpenID4VCIClient.js +30 -14
  13. package/dist/OpenID4VCIClient.js.map +1 -1
  14. package/dist/OpenID4VCIClientV1_0_11.d.ts +4 -2
  15. package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
  16. package/dist/OpenID4VCIClientV1_0_11.js +32 -16
  17. package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
  18. package/dist/OpenID4VCIClientV1_0_13.d.ts +3 -1
  19. package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -1
  20. package/dist/OpenID4VCIClientV1_0_13.js +29 -15
  21. package/dist/OpenID4VCIClientV1_0_13.js.map +1 -1
  22. package/dist/ProofOfPossessionBuilder.js +6 -6
  23. package/dist/ProofOfPossessionBuilder.js.map +1 -1
  24. package/dist/functions/AccessTokenUtil.d.ts +5 -0
  25. package/dist/functions/AccessTokenUtil.d.ts.map +1 -0
  26. package/dist/functions/AccessTokenUtil.js +63 -0
  27. package/dist/functions/AccessTokenUtil.js.map +1 -0
  28. package/dist/functions/index.d.ts +2 -0
  29. package/dist/functions/index.d.ts.map +1 -1
  30. package/dist/functions/index.js +2 -0
  31. package/dist/functions/index.js.map +1 -1
  32. package/lib/AccessTokenClient.ts +9 -4
  33. package/lib/AccessTokenClientV1_0_11.ts +11 -3
  34. package/lib/AuthorizationCodeClient.ts +2 -2
  35. package/lib/CredentialRequestClientBuilder.ts +14 -14
  36. package/lib/OpenID4VCIClient.ts +31 -3
  37. package/lib/OpenID4VCIClientV1_0_11.ts +35 -6
  38. package/lib/OpenID4VCIClientV1_0_13.ts +33 -6
  39. package/lib/ProofOfPossessionBuilder.ts +6 -6
  40. package/lib/__tests__/CredentialRequestClient.spec.ts +1 -1
  41. package/lib/__tests__/CredentialRequestClientBuilder.spec.ts +1 -1
  42. package/lib/__tests__/CredentialRequestClientV1_0_11.spec.ts +2 -2
  43. package/lib/__tests__/IT.spec.ts +23 -29
  44. package/lib/__tests__/ProofOfPossessionBuilder.spec.ts +23 -23
  45. package/lib/__tests__/SdJwt.spec.ts +26 -26
  46. package/lib/functions/AccessTokenUtil.ts +52 -0
  47. package/lib/functions/index.ts +2 -0
  48. package/package.json +4 -4
@@ -22,6 +22,7 @@ import {
22
22
  import { ObjectUtils } from '@sphereon/ssi-types';
23
23
 
24
24
  import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13';
25
+ import { createJwtBearerClientAssertion } from './functions';
25
26
  import { LOG } from './types';
26
27
 
27
28
  export class AccessTokenClient {
@@ -48,6 +49,9 @@ export class AccessTokenClient {
48
49
  code,
49
50
  redirectUri,
50
51
  pin,
52
+ credentialIssuer: issuer,
53
+ metadata,
54
+ additionalParams: opts.additionalParams,
51
55
  pinMetadata,
52
56
  }),
53
57
  pinMetadata,
@@ -90,11 +94,12 @@ export class AccessTokenClient {
90
94
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
91
95
  // @ts-ignore
92
96
  const credentialOfferRequest = opts.credentialOffer ? await toUniformCredentialOfferRequest(opts.credentialOffer) : undefined;
93
- const request: Partial<AccessTokenRequest> = {};
94
-
95
- if (asOpts?.clientId) {
96
- request.client_id = asOpts.clientId;
97
+ const request: Partial<AccessTokenRequest> = { ...opts.additionalParams };
98
+ if (asOpts?.clientOpts?.clientId) {
99
+ request.client_id = asOpts.clientOpts.clientId;
97
100
  }
101
+ const credentialIssuer = opts.credentialIssuer ?? credentialOfferRequest?.credential_offer?.credential_issuer ?? opts.metadata?.issuer;
102
+ await createJwtBearerClientAssertion(request, { ...opts, credentialIssuer });
98
103
 
99
104
  if (credentialOfferRequest?.supportedFlows.includes(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)) {
100
105
  this.assertAlphanumericPin(opts.pinMetadata, pin);
@@ -14,6 +14,7 @@ import {
14
14
  GrantTypes,
15
15
  IssuerOpts,
16
16
  JsonURIMode,
17
+ OpenId4VCIVersion,
17
18
  OpenIDResponse,
18
19
  PRE_AUTH_CODE_LITERAL,
19
20
  TokenErrorResponse,
@@ -24,6 +25,7 @@ import { ObjectUtils } from '@sphereon/ssi-types';
24
25
  import Debug from 'debug';
25
26
 
26
27
  import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13';
28
+ import { createJwtBearerClientAssertion } from './functions';
27
29
 
28
30
  const debug = Debug('sphereon:oid4vci:token');
29
31
 
@@ -51,6 +53,10 @@ export class AccessTokenClientV1_0_11 {
51
53
  code,
52
54
  redirectUri,
53
55
  pin,
56
+ credentialIssuer: issuer,
57
+ metadata,
58
+ additionalParams: opts.additionalParams,
59
+ pinMetadata: opts.pinMetadata,
54
60
  }),
55
61
  isPinRequired,
56
62
  metadata,
@@ -92,11 +98,13 @@ export class AccessTokenClientV1_0_11 {
92
98
  const credentialOfferRequest = opts.credentialOffer
93
99
  ? await toUniformCredentialOfferRequest(opts.credentialOffer as CredentialOfferV1_0_11 | CredentialOfferV1_0_13)
94
100
  : undefined;
95
- const request: Partial<AccessTokenRequest> = {};
101
+ const request: Partial<AccessTokenRequest> = { ...opts.additionalParams };
102
+ const credentialIssuer = opts.credentialIssuer ?? credentialOfferRequest?.credential_offer?.credential_issuer ?? opts.metadata?.issuer;
96
103
 
97
- if (asOpts?.clientId) {
98
- request.client_id = asOpts.clientId;
104
+ if (asOpts?.clientOpts?.clientId) {
105
+ request.client_id = asOpts.clientOpts.clientId;
99
106
  }
107
+ await createJwtBearerClientAssertion(request, { ...opts, version: OpenId4VCIVersion.VER_1_0_11, credentialIssuer });
100
108
 
101
109
  if (credentialOfferRequest?.supportedFlows.includes(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)) {
102
110
  this.assertNumericPin(this.isPinRequiredValue(credentialOfferRequest.credential_offer), pin);
@@ -52,14 +52,14 @@ export async function createSignedAuthRequestWhenNeeded(requestObject: Record<st
52
52
  const iss = requestObject.iss ?? opts.iss ?? requestObject.client_id;
53
53
 
54
54
  const jwt: Jwt = {
55
- header: { alg: 'ES256', kid: opts.kid, typ: 'jwt' },
55
+ header: { alg: 'ES256', kid: opts.kid, typ: 'JWT' },
56
56
  payload: { ...requestObject, iss, authorization_details, ...(client_metadata && { client_metadata }) },
57
57
  };
58
58
  const pop = await ProofOfPossessionBuilder.fromJwt({
59
59
  jwt,
60
60
  callbacks: opts.signCallbacks,
61
61
  version: OpenId4VCIVersion.VER_1_0_11,
62
- mode: 'jwt',
62
+ mode: 'JWT',
63
63
  }).build();
64
64
  requestObject['request'] = pop.jwt;
65
65
  }
@@ -8,9 +8,9 @@ import {
8
8
  ExperimentalSubjectIssuance,
9
9
  OID4VCICredentialFormat,
10
10
  OpenId4VCIVersion,
11
- UniformCredentialOfferRequest
12
- } from '@sphereon/oid4vci-common'
13
- import { CredentialFormat } from '@sphereon/ssi-types'
11
+ UniformCredentialOfferRequest,
12
+ } from '@sphereon/oid4vci-common';
13
+ import { CredentialFormat } from '@sphereon/ssi-types';
14
14
 
15
15
  import { CredentialOfferClient } from './CredentialOfferClient';
16
16
  import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
@@ -30,12 +30,12 @@ export class CredentialRequestClientBuilder {
30
30
  }
31
31
 
32
32
  public static fromCredentialIssuer({
33
- credentialIssuer,
34
- metadata,
35
- version,
36
- credentialIdentifier,
37
- credentialTypes,
38
- }: {
33
+ credentialIssuer,
34
+ metadata,
35
+ version,
36
+ credentialIdentifier,
37
+ credentialTypes,
38
+ }: {
39
39
  credentialIssuer: string;
40
40
  metadata?: EndpointMetadata;
41
41
  version?: OpenId4VCIVersion;
@@ -99,9 +99,9 @@ export class CredentialRequestClientBuilder {
99
99
  }
100
100
 
101
101
  public static fromCredentialOffer({
102
- credentialOffer,
103
- metadata,
104
- }: {
102
+ credentialOffer,
103
+ metadata,
104
+ }: {
105
105
  credentialOffer: CredentialOfferRequestWithBaseUrl;
106
106
  metadata?: EndpointMetadata;
107
107
  }): CredentialRequestClientBuilder {
@@ -129,9 +129,9 @@ export class CredentialRequestClientBuilder {
129
129
 
130
130
  public withCredentialEndpointFromMetadata(metadata: CredentialIssuerMetadata | CredentialIssuerMetadataV1_0_13): this {
131
131
  if (isV1_0_13(this._builder)) {
132
- this._builder.withCredentialEndpointFromMetadata(metadata as CredentialIssuerMetadataV1_0_13)
132
+ this._builder.withCredentialEndpointFromMetadata(metadata as CredentialIssuerMetadataV1_0_13);
133
133
  } else {
134
- this._builder.withCredentialEndpointFromMetadata(metadata as CredentialIssuerMetadata)
134
+ this._builder.withCredentialEndpointFromMetadata(metadata as CredentialIssuerMetadata);
135
135
  }
136
136
  return this;
137
137
  }
@@ -3,6 +3,7 @@ import {
3
3
  Alg,
4
4
  AuthorizationRequestOpts,
5
5
  AuthorizationResponse,
6
+ AuthorizationServerOpts,
6
7
  AuthzFlowType,
7
8
  CodeChallengeMethod,
8
9
  CredentialConfigurationSupported,
@@ -41,8 +42,8 @@ import { createAuthorizationRequestUrl } from './AuthorizationCodeClient';
41
42
  import { createAuthorizationRequestUrlV1_0_11 } from './AuthorizationCodeClientV1_0_11';
42
43
  import { CredentialOfferClient } from './CredentialOfferClient';
43
44
  import { CredentialRequestOpts } from './CredentialRequestClient';
44
- import { CredentialRequestClientBuilderV1_0_13 } from './CredentialRequestClientBuilderV1_0_13';
45
45
  import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
46
+ import { CredentialRequestClientBuilderV1_0_13 } from './CredentialRequestClientBuilderV1_0_13';
46
47
  import { MetadataClient } from './MetadataClient';
47
48
  import { OpenID4VCIClientStateV1_0_11 } from './OpenID4VCIClientV1_0_11';
48
49
  import { OpenID4VCIClientStateV1_0_13 } from './OpenID4VCIClientV1_0_13';
@@ -103,6 +104,7 @@ export class OpenID4VCIClient {
103
104
  pkce: { disabled: false, codeChallengeMethod: CodeChallengeMethod.S256, ...pkce },
104
105
  authorizationRequestOpts,
105
106
  authorizationCodeResponse,
107
+ accessToken,
106
108
  jwk,
107
109
  endpointMetadata: endpointMetadata?.credentialIssuerMetadata?.authorization_server
108
110
  ? (endpointMetadata as EndpointMetadataResultV1_0_11)
@@ -273,8 +275,10 @@ export class OpenID4VCIClient {
273
275
  authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
274
276
  code?: string; // Directly pass in a code from an auth response
275
277
  redirectUri?: string;
278
+ additionalRequestParams?: Record<string, any>;
279
+ asOpts?: AuthorizationServerOpts;
276
280
  }): Promise<AccessTokenResponse> {
277
- const { pin, clientId } = opts ?? {};
281
+ const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
278
282
  let { redirectUri } = opts ?? {};
279
283
  if (opts?.authorizationResponse) {
280
284
  this._state.authorizationCodeResponse = { ...toAuthorizationResponsePayload(opts.authorizationResponse) };
@@ -288,6 +292,26 @@ export class OpenID4VCIClient {
288
292
  }
289
293
  this.assertIssuerData();
290
294
 
295
+ const asOpts: AuthorizationServerOpts = { ...opts?.asOpts };
296
+ const kid = asOpts.clientOpts?.kid ?? this._state.kid ?? this._state.authorizationRequestOpts?.requestObjectOpts?.kid;
297
+ const clientAssertionType =
298
+ asOpts.clientOpts?.clientAssertionType ??
299
+ (kid && clientId && typeof asOpts.clientOpts?.signCallbacks?.signCallback === 'function'
300
+ ? 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
301
+ : undefined);
302
+ if (this.isEBSI() || (clientId && kid)) {
303
+ if (!clientId) {
304
+ throw Error(`Client id expected for EBSI`);
305
+ }
306
+ asOpts.clientOpts = {
307
+ ...asOpts.clientOpts,
308
+ clientId,
309
+ ...(kid && { kid }),
310
+ ...(clientAssertionType && { clientAssertionType }),
311
+ signCallbacks: asOpts.clientOpts?.signCallbacks ?? this._state.authorizationRequestOpts?.requestObjectOpts?.signCallbacks,
312
+ };
313
+ }
314
+
291
315
  if (clientId) {
292
316
  this._state.clientId = clientId;
293
317
  }
@@ -311,7 +335,8 @@ export class OpenID4VCIClient {
311
335
  ...(!this._state.pkce.disabled && { codeVerifier: this._state.pkce.codeVerifier }),
312
336
  code,
313
337
  redirectUri,
314
- asOpts: { clientId: this.clientId },
338
+ asOpts,
339
+ ...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
315
340
  });
316
341
 
317
342
  if (response.errorBody) {
@@ -646,6 +671,9 @@ export class OpenID4VCIClient {
646
671
  }
647
672
  // this.assertIssuerData();
648
673
  return (
674
+ this.clientId?.includes('ebsi') ||
675
+ this._state.kid?.includes('did:ebsi:') ||
676
+ this.getIssuer().includes('ebsi') ||
649
677
  this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ||
650
678
  this.endpointMetadata.credentialIssuerMetadata?.authorization_server?.includes('ebsi.eu')
651
679
  );
@@ -3,6 +3,7 @@ import {
3
3
  Alg,
4
4
  AuthorizationRequestOpts,
5
5
  AuthorizationResponse,
6
+ AuthorizationServerOpts,
6
7
  AuthzFlowType,
7
8
  CodeChallengeMethod,
8
9
  CredentialConfigurationSupported,
@@ -259,8 +260,10 @@ export class OpenID4VCIClientV1_0_11 {
259
260
  authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
260
261
  code?: string; // Directly pass in a code from an auth response
261
262
  redirectUri?: string;
263
+ additionalRequestParams?: Record<string, any>;
264
+ asOpts?: AuthorizationServerOpts;
262
265
  }): Promise<AccessTokenResponse> {
263
- const { pin, clientId } = opts ?? {};
266
+ const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
264
267
  let { redirectUri } = opts ?? {};
265
268
  if (opts?.authorizationResponse) {
266
269
  this._state.authorizationCodeResponse = { ...toAuthorizationResponsePayload(opts.authorizationResponse) };
@@ -288,6 +291,25 @@ export class OpenID4VCIClientV1_0_11 {
288
291
  if (this._state.authorizationRequestOpts?.redirectUri && !redirectUri) {
289
292
  redirectUri = this._state.authorizationRequestOpts.redirectUri;
290
293
  }
294
+ const asOpts: AuthorizationServerOpts = { ...opts?.asOpts };
295
+ const kid = asOpts.clientOpts?.kid ?? this._state.kid ?? this._state.authorizationRequestOpts?.requestObjectOpts?.kid;
296
+ const clientAssertionType =
297
+ asOpts.clientOpts?.clientAssertionType ??
298
+ (kid && clientId && typeof asOpts.clientOpts?.signCallbacks?.signCallback === 'function'
299
+ ? 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
300
+ : undefined);
301
+ if (this.isEBSI() || (clientId && kid)) {
302
+ if (!clientId) {
303
+ throw Error(`Client id expected for EBSI`);
304
+ }
305
+ asOpts.clientOpts = {
306
+ ...asOpts.clientOpts,
307
+ clientId,
308
+ ...(kid && { kid }),
309
+ ...(clientAssertionType && { clientAssertionType }),
310
+ signCallbacks: asOpts.clientOpts?.signCallbacks ?? this._state.authorizationRequestOpts?.requestObjectOpts?.signCallbacks,
311
+ };
312
+ }
291
313
 
292
314
  const response = await accessTokenClient.acquireAccessToken({
293
315
  credentialOffer: this.credentialOffer,
@@ -297,7 +319,8 @@ export class OpenID4VCIClientV1_0_11 {
297
319
  ...(!this._state.pkce.disabled && { codeVerifier: this._state.pkce.codeVerifier }),
298
320
  code,
299
321
  redirectUri,
300
- asOpts: { clientId: this.clientId },
322
+ asOpts,
323
+ ...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
301
324
  });
302
325
 
303
326
  if (response.errorBody) {
@@ -584,8 +607,8 @@ export class OpenID4VCIClientV1_0_11 {
584
607
  */
585
608
  public isEBSI() {
586
609
  if (
587
- (this.credentialOffer?.credential_offer as CredentialOfferPayloadV1_0_11)['credentials'] &&
588
- (this.credentialOffer?.credential_offer as CredentialOfferPayloadV1_0_11).credentials.find(
610
+ this.credentialOffer &&
611
+ (this.credentialOffer?.credential_offer as CredentialOfferPayloadV1_0_11)?.credentials?.find(
589
612
  (cred) =>
590
613
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
591
614
  // @ts-ignore
@@ -594,8 +617,14 @@ export class OpenID4VCIClientV1_0_11 {
594
617
  ) {
595
618
  return true;
596
619
  }
597
- this.assertIssuerData();
598
- return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') === true;
620
+ // this.assertIssuerData();
621
+ return (
622
+ this.clientId?.includes('ebsi') ||
623
+ this._state.kid?.includes('did:ebsi:') ||
624
+ this.getIssuer().includes('ebsi') ||
625
+ this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ||
626
+ this.endpointMetadata.credentialIssuerMetadata?.authorization_server?.includes('ebsi.eu')
627
+ );
599
628
  }
600
629
 
601
630
  private assertIssuerData(): void {
@@ -3,6 +3,7 @@ import {
3
3
  Alg,
4
4
  AuthorizationRequestOpts,
5
5
  AuthorizationResponse,
6
+ AuthorizationServerOpts,
6
7
  AuthzFlowType,
7
8
  CodeChallengeMethod,
8
9
  CredentialConfigurationSupportedV1_0_13,
@@ -36,8 +37,7 @@ import { CredentialRequestOpts } from './CredentialRequestClient';
36
37
  import { CredentialRequestClientBuilder } from './CredentialRequestClientBuilder';
37
38
  import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13';
38
39
  import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
39
- import { generateMissingPKCEOpts } from './functions';
40
- import { sendNotification } from './functions';
40
+ import { generateMissingPKCEOpts, sendNotification } from './functions';
41
41
 
42
42
  const debug = Debug('sphereon:oid4vci');
43
43
 
@@ -265,8 +265,10 @@ export class OpenID4VCIClientV1_0_13 {
265
265
  authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
266
266
  code?: string; // Directly pass in a code from an auth response
267
267
  redirectUri?: string;
268
+ additionalRequestParams?: Record<string, any>;
269
+ asOpts?: AuthorizationServerOpts;
268
270
  }): Promise<AccessTokenResponse> {
269
- const { pin, clientId } = opts ?? {};
271
+ const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
270
272
  let { redirectUri } = opts ?? {};
271
273
  if (opts?.authorizationResponse) {
272
274
  this._state.authorizationCodeResponse = { ...toAuthorizationResponsePayload(opts.authorizationResponse) };
@@ -279,6 +281,25 @@ export class OpenID4VCIClientV1_0_13 {
279
281
  this._state.pkce.codeVerifier = opts.codeVerifier;
280
282
  }
281
283
  this.assertIssuerData();
284
+ const asOpts: AuthorizationServerOpts = { ...opts?.asOpts };
285
+ const kid = asOpts.clientOpts?.kid ?? this._state.kid ?? this._state.authorizationRequestOpts?.requestObjectOpts?.kid;
286
+ const clientAssertionType =
287
+ asOpts.clientOpts?.clientAssertionType ??
288
+ (kid && clientId && typeof asOpts.clientOpts?.signCallbacks?.signCallback === 'function'
289
+ ? 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
290
+ : undefined);
291
+ if (this.isEBSI() || (clientId && kid)) {
292
+ if (!clientId) {
293
+ throw Error(`Client id expected for EBSI`);
294
+ }
295
+ asOpts.clientOpts = {
296
+ ...asOpts.clientOpts,
297
+ clientId,
298
+ ...(kid && { kid }),
299
+ ...(clientAssertionType && { clientAssertionType }),
300
+ signCallbacks: asOpts.clientOpts?.signCallbacks ?? this._state.authorizationRequestOpts?.requestObjectOpts?.signCallbacks,
301
+ };
302
+ }
282
303
 
283
304
  if (clientId) {
284
305
  this._state.clientId = clientId;
@@ -302,7 +323,8 @@ export class OpenID4VCIClientV1_0_13 {
302
323
  ...(!this._state.pkce.disabled && { codeVerifier: this._state.pkce.codeVerifier }),
303
324
  code,
304
325
  redirectUri,
305
- asOpts: { clientId: this.clientId },
326
+ asOpts,
327
+ ...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
306
328
  });
307
329
 
308
330
  if (response.errorBody) {
@@ -636,8 +658,13 @@ export class OpenID4VCIClientV1_0_13 {
636
658
  }
637
659
  }
638
660
 
639
- this.assertIssuerData();
640
- return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ?? false;
661
+ return (
662
+ this.clientId?.includes('ebsi') ||
663
+ this._state.kid?.includes('did:ebsi:') ||
664
+ this.getIssuer().includes('ebsi') ||
665
+ this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ||
666
+ this.endpointMetadata.credentialIssuerMetadata?.authorization_server?.includes('ebsi.eu')
667
+ );
641
668
  }
642
669
 
643
670
  private assertIssuerData(): void {
@@ -53,7 +53,7 @@ export class ProofOfPossessionBuilder<DIDDoc> {
53
53
  if (jwt) {
54
54
  this.withJwt(jwt);
55
55
  } else {
56
- this.withTyp(version < OpenId4VCIVersion.VER_1_0_11 || mode === 'jwt' ? 'jwt' : 'openid4vci-proof+jwt');
56
+ this.withTyp(version < OpenId4VCIVersion.VER_1_0_11 || mode === 'JWT' ? 'JWT' : 'openid4vci-proof+jwt');
57
57
  }
58
58
  if (accessTokenResponse) {
59
59
  this.withAccessTokenResponse(accessTokenResponse);
@@ -64,7 +64,7 @@ export class ProofOfPossessionBuilder<DIDDoc> {
64
64
  jwt,
65
65
  callbacks,
66
66
  version,
67
- mode = 'jwt',
67
+ mode = 'JWT',
68
68
  }: {
69
69
  jwt?: Jwt;
70
70
  callbacks: ProofOfPossessionCallbacks<DIDDoc>;
@@ -144,11 +144,11 @@ export class ProofOfPossessionBuilder<DIDDoc> {
144
144
  withTyp(typ: Typ): this {
145
145
  if (this.mode === 'pop' && this.version >= OpenId4VCIVersion.VER_1_0_11) {
146
146
  if (!!typ && typ !== 'openid4vci-proof+jwt') {
147
- throw Error('typ must be openid4vci-proof+jwt for version 1.0.11 and up');
147
+ throw Error(`typ must be openid4vci-proof+jwt for version 1.0.11 and up. Provided: ${typ}`);
148
148
  }
149
149
  } else {
150
- if (!!typ && typ !== 'jwt') {
151
- throw Error('typ must be jwt for version 1.0.10 and below');
150
+ if (!!typ && typ !== 'JWT') {
151
+ throw Error(`typ must be jwt for version 1.0.10 and below. Provided: ${typ}`);
152
152
  }
153
153
  }
154
154
  this.typ = typ;
@@ -216,7 +216,7 @@ export class ProofOfPossessionBuilder<DIDDoc> {
216
216
  this.mode,
217
217
  this.callbacks,
218
218
  {
219
- typ: this.typ ?? (this.version < OpenId4VCIVersion.VER_1_0_11 || this.mode === 'jwt' ? 'jwt' : 'openid4vci-proof+jwt'),
219
+ typ: this.typ ?? (this.version < OpenId4VCIVersion.VER_1_0_11 || this.mode === 'JWT' ? 'JWT' : 'openid4vci-proof+jwt'),
220
220
  kid: this.kid,
221
221
  jwk: this.jwk,
222
222
  jti: this.jti,
@@ -29,7 +29,7 @@ import { getMockData } from './data/VciDataFixtures';
29
29
  const partialJWT = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmN';
30
30
 
31
31
  const jwt1_0_08: Jwt = {
32
- header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
32
+ header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
33
33
  payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
34
34
  };
35
35
 
@@ -20,7 +20,7 @@ const partialJWT = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmN';
20
20
  const partialJWT_withoutDid = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJlYmZlYjFmNzEyZWJjNmYxYzI3N';
21
21
 
22
22
  /*const jwtv1_0_08: Jwt = {
23
- header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
23
+ header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
24
24
  payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
25
25
  };*/
26
26
 
@@ -31,12 +31,12 @@ const partialJWT = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmN';
31
31
  const partialJWT_withoutDid = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJlYmZlYjFmNzEyZWJjNmYxYzI3N';
32
32
 
33
33
  const jwt: Jwt = {
34
- header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
34
+ header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
35
35
  payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
36
36
  };
37
37
 
38
38
  const jwt_withoutDid: Jwt = {
39
- header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
39
+ header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
40
40
  payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
41
41
  };
42
42
 
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  AccessTokenResponse,
3
- Alg, CredentialOfferPayloadV1_0_13,
3
+ Alg,
4
+ CredentialOfferPayloadV1_0_13,
4
5
  CredentialOfferRequestWithBaseUrl,
5
6
  Jwt,
6
7
  OpenId4VCIVersion,
7
- ProofOfPossession, resolveCredentialOfferURI,
8
- WellKnownEndpoints
9
- } from '@sphereon/oid4vci-common'
8
+ ProofOfPossession,
9
+ resolveCredentialOfferURI,
10
+ WellKnownEndpoints,
11
+ } from '@sphereon/oid4vci-common';
10
12
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
11
13
  // @ts-ignore
12
14
  import nock from 'nock';
@@ -271,10 +273,6 @@ describe('OID4VCI-Client should', () => {
271
273
  .withTokenFromResponse(accessTokenResponse.successBody!)
272
274
  .build();
273
275
 
274
- //TS2322: Type '(args: ProofOfPossessionCallbackArgs) => Promise<string>'
275
- // is not assignable to type 'ProofOfPossessionCallback'.
276
- // Types of parameters 'args' and 'args' are incompatible.
277
- // Property 'kid' is missing in type '{ header: unknown; payload: unknown; }' but required in type 'ProofOfPossessionCallbackArgs'.
278
276
  const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
279
277
  jwt: jwtDid,
280
278
  callbacks: {
@@ -315,8 +313,8 @@ describe('OID4VCI-Client should', () => {
315
313
  });
316
314
 
317
315
  nock(ISSUER_URL)
318
- .post(/token.*/)
319
- .reply(200, JSON.stringify(mockedAccessTokenResponse));
316
+ .post(/token.*/)
317
+ .reply(200, JSON.stringify(mockedAccessTokenResponse));
320
318
 
321
319
  /* The actual access token calls */
322
320
  const accessTokenClient: AccessTokenClient = new AccessTokenClient();
@@ -324,21 +322,17 @@ describe('OID4VCI-Client should', () => {
324
322
  expect(accessTokenResponse.successBody).toEqual(mockedAccessTokenResponse);
325
323
  // Get the credential
326
324
  nock(ISSUER_URL)
327
- .post(/credential/)
328
- .reply(200, {
329
- format: 'jwt-vc',
330
- credential: mockedVC,
331
- });
325
+ .post(/credential/)
326
+ .reply(200, {
327
+ format: 'jwt-vc',
328
+ credential: mockedVC,
329
+ });
332
330
  const credReqClient = CredentialRequestClientBuilder.fromCredentialOffer({ credentialOffer: credentialOffer })
333
- .withFormat('jwt_vc')
331
+ .withFormat('jwt_vc')
334
332
 
335
- .withTokenFromResponse(accessTokenResponse.successBody!)
336
- .build();
333
+ .withTokenFromResponse(accessTokenResponse.successBody!)
334
+ .build();
337
335
 
338
- //TS2322: Type '(args: ProofOfPossessionCallbackArgs) => Promise<string>'
339
- // is not assignable to type 'ProofOfPossessionCallback'.
340
- // Types of parameters 'args' and 'args' are incompatible.
341
- // Property 'kid' is missing in type '{ header: unknown; payload: unknown; }' but required in type 'ProofOfPossessionCallbackArgs'.
342
336
  const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
343
337
  jwt: jwtDid,
344
338
  callbacks: {
@@ -346,13 +340,13 @@ describe('OID4VCI-Client should', () => {
346
340
  },
347
341
  version: OpenId4VCIVersion.VER_1_0_11,
348
342
  })
349
- .withEndpointMetadata({
350
- issuer: 'https://issuer.research.identiproof.io',
351
- credential_endpoint: 'https://issuer.research.identiproof.io/credential',
352
- token_endpoint: 'https://issuer.research.identiproof.io/token',
353
- })
354
- .withKid('did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1')
355
- .build();
343
+ .withEndpointMetadata({
344
+ issuer: 'https://issuer.research.identiproof.io',
345
+ credential_endpoint: 'https://issuer.research.identiproof.io/credential',
346
+ token_endpoint: 'https://issuer.research.identiproof.io/token',
347
+ })
348
+ .withKid('did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1')
349
+ .build();
356
350
  const credResponse = await credReqClient.acquireCredentialsUsingProof({
357
351
  proofInput: proof,
358
352
  credentialTypes: credentialOffer.original_credential_offer.credential_configuration_ids[0],
@@ -8,12 +8,12 @@ import { ProofOfPossessionBuilder } from '..';
8
8
  import { IDENTIPROOF_ISSUER_URL } from './MetadataMocks';
9
9
 
10
10
  const jwt: Jwt = {
11
- header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
11
+ header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
12
12
  payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now() / 1000 },
13
13
  };
14
14
 
15
15
  const jwt_withoutDid: Jwt = {
16
- header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
16
+ header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
17
17
  payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now() / 1000 },
18
18
  };
19
19
 
@@ -62,10 +62,10 @@ describe('ProofOfPossession Builder ', () => {
62
62
  it('should fail without supplied proof or callbacks and with kid without did', async function () {
63
63
  await expect(
64
64
  ProofOfPossessionBuilder.fromProof(undefined as never, OpenId4VCIVersion.VER_1_0_13)
65
- .withIssuer(IDENTIPROOF_ISSUER_URL)
66
- .withClientId('sphereon:wallet')
67
- .withKid(kid_withoutDid)
68
- .build(),
65
+ .withIssuer(IDENTIPROOF_ISSUER_URL)
66
+ .withClientId('sphereon:wallet')
67
+ .withKid(kid_withoutDid)
68
+ .build(),
69
69
  ).rejects.toThrow(Error(PROOF_CANT_BE_CONSTRUCTED));
70
70
  });
71
71
 
@@ -87,11 +87,11 @@ describe('ProofOfPossession Builder ', () => {
87
87
  callbacks: { signCallback: proofOfPossessionCallbackFunction },
88
88
  version: OpenId4VCIVersion.VER_1_0_08,
89
89
  })
90
- .withJwt(undefined as never)
91
- .withIssuer(IDENTIPROOF_ISSUER_URL)
92
- .withClientId('sphereon:wallet')
93
- .withKid(kid_withoutDid)
94
- .build(),
90
+ .withJwt(undefined as never)
91
+ .withIssuer(IDENTIPROOF_ISSUER_URL)
92
+ .withClientId('sphereon:wallet')
93
+ .withKid(kid_withoutDid)
94
+ .build(),
95
95
  ).toThrow(Error(NO_JWT_PROVIDED));
96
96
  });
97
97
 
@@ -118,10 +118,10 @@ describe('ProofOfPossession Builder ', () => {
118
118
  },
119
119
  version: OpenId4VCIVersion.VER_1_0_08,
120
120
  })
121
- .withIssuer(IDENTIPROOF_ISSUER_URL)
122
- .withKid(kid_withoutDid)
123
- .withClientId('sphereon:wallet')
124
- .build();
121
+ .withIssuer(IDENTIPROOF_ISSUER_URL)
122
+ .withKid(kid_withoutDid)
123
+ .withClientId('sphereon:wallet')
124
+ .build();
125
125
  expect(proof).toBeDefined();
126
126
  });
127
127
 
@@ -152,10 +152,10 @@ describe('ProofOfPossession Builder ', () => {
152
152
  callbacks: { signCallback: proofOfPossessionCallbackFunction },
153
153
  version: OpenId4VCIVersion.VER_1_0_08,
154
154
  })
155
- .withIssuer(IDENTIPROOF_ISSUER_URL)
156
- .withClientId('sphereon:wallet')
157
- .withKid(kid_withoutDid)
158
- .build(),
155
+ .withIssuer(IDENTIPROOF_ISSUER_URL)
156
+ .withClientId('sphereon:wallet')
157
+ .withKid(kid_withoutDid)
158
+ .build(),
159
159
  ).rejects.toThrow(Error(JWS_NOT_VALID));
160
160
  });
161
161
 
@@ -186,10 +186,10 @@ describe('ProofOfPossession Builder ', () => {
186
186
  callbacks: { signCallback: proofOfPossessionCallbackFunction },
187
187
  version: OpenId4VCIVersion.VER_1_0_08,
188
188
  })
189
- .withIssuer(IDENTIPROOF_ISSUER_URL)
190
- .withClientId('sphereon:wallet')
191
- .withKid(kid_withoutDid)
192
- .build(),
189
+ .withIssuer(IDENTIPROOF_ISSUER_URL)
190
+ .withClientId('sphereon:wallet')
191
+ .withKid(kid_withoutDid)
192
+ .build(),
193
193
  ).rejects.toThrow(Error(JWS_NOT_VALID));
194
194
  });
195
195
  });