@sphereon/oid4vci-client 0.15.2-unstable.8 → 0.16.1-next.13

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 (83) hide show
  1. package/dist/AccessTokenClient.d.ts +7 -5
  2. package/dist/AccessTokenClient.d.ts.map +1 -1
  3. package/dist/AccessTokenClient.js +25 -5
  4. package/dist/AccessTokenClient.js.map +1 -1
  5. package/dist/AccessTokenClientV1_0_11.d.ts +7 -5
  6. package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
  7. package/dist/AccessTokenClientV1_0_11.js +25 -5
  8. package/dist/AccessTokenClientV1_0_11.js.map +1 -1
  9. package/dist/AuthorizationCodeClient.d.ts.map +1 -1
  10. package/dist/AuthorizationCodeClient.js +3 -2
  11. package/dist/AuthorizationCodeClient.js.map +1 -1
  12. package/dist/AuthorizationCodeClientV1_0_11.js +1 -1
  13. package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -1
  14. package/dist/CredentialRequestClient.d.ts +6 -4
  15. package/dist/CredentialRequestClient.d.ts.map +1 -1
  16. package/dist/CredentialRequestClient.js +23 -5
  17. package/dist/CredentialRequestClient.js.map +1 -1
  18. package/dist/CredentialRequestClientV1_0_11.d.ts +5 -3
  19. package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -1
  20. package/dist/CredentialRequestClientV1_0_11.js +32 -4
  21. package/dist/CredentialRequestClientV1_0_11.js.map +1 -1
  22. package/dist/MetadataClient.d.ts +1 -0
  23. package/dist/MetadataClient.d.ts.map +1 -1
  24. package/dist/MetadataClient.js +5 -4
  25. package/dist/MetadataClient.js.map +1 -1
  26. package/dist/MetadataClientV1_0_13.d.ts +1 -0
  27. package/dist/MetadataClientV1_0_13.d.ts.map +1 -1
  28. package/dist/MetadataClientV1_0_13.js +5 -9
  29. package/dist/MetadataClientV1_0_13.js.map +1 -1
  30. package/dist/OpenID4VCIClient.d.ts +10 -10
  31. package/dist/OpenID4VCIClient.d.ts.map +1 -1
  32. package/dist/OpenID4VCIClient.js +11 -17
  33. package/dist/OpenID4VCIClient.js.map +1 -1
  34. package/dist/OpenID4VCIClientV1_0_11.d.ts +10 -9
  35. package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
  36. package/dist/OpenID4VCIClientV1_0_11.js +14 -7
  37. package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
  38. package/dist/OpenID4VCIClientV1_0_13.d.ts +10 -9
  39. package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -1
  40. package/dist/OpenID4VCIClientV1_0_13.js +11 -6
  41. package/dist/OpenID4VCIClientV1_0_13.js.map +1 -1
  42. package/dist/ProofOfPossessionBuilder.d.ts +2 -1
  43. package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
  44. package/dist/ProofOfPossessionBuilder.js.map +1 -1
  45. package/dist/functions/AccessTokenUtil.d.ts.map +1 -1
  46. package/dist/functions/AccessTokenUtil.js +2 -2
  47. package/dist/functions/AccessTokenUtil.js.map +1 -1
  48. package/dist/functions/dpopUtil.d.ts +10 -0
  49. package/dist/functions/dpopUtil.d.ts.map +1 -0
  50. package/dist/functions/dpopUtil.js +30 -0
  51. package/dist/functions/dpopUtil.js.map +1 -0
  52. package/dist/functions/notifications.d.ts.map +1 -1
  53. package/dist/functions/notifications.js +3 -3
  54. package/dist/functions/notifications.js.map +1 -1
  55. package/dist/index.d.ts +0 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +0 -1
  58. package/dist/index.js.map +1 -1
  59. package/lib/AccessTokenClient.ts +44 -7
  60. package/lib/AccessTokenClientV1_0_11.ts +44 -7
  61. package/lib/AuthorizationCodeClient.ts +4 -3
  62. package/lib/AuthorizationCodeClientV1_0_11.ts +3 -3
  63. package/lib/CredentialRequestClient.ts +49 -7
  64. package/lib/CredentialRequestClientV1_0_11.ts +48 -5
  65. package/lib/MetadataClient.ts +2 -1
  66. package/lib/MetadataClientV1_0_13.ts +2 -7
  67. package/lib/OpenID4VCIClient.ts +26 -28
  68. package/lib/OpenID4VCIClientV1_0_11.ts +25 -14
  69. package/lib/OpenID4VCIClientV1_0_13.ts +23 -13
  70. package/lib/ProofOfPossessionBuilder.ts +1 -1
  71. package/lib/__tests__/AccessTokenClient.spec.ts +4 -11
  72. package/lib/__tests__/SphereonE2E.spec.test.ts +3 -3
  73. package/lib/functions/AccessTokenUtil.ts +2 -2
  74. package/lib/functions/dpopUtil.ts +35 -0
  75. package/lib/functions/notifications.ts +2 -4
  76. package/lib/index.ts +0 -1
  77. package/package.json +5 -4
  78. package/dist/IssuerSessionClient.d.ts +0 -3
  79. package/dist/IssuerSessionClient.d.ts.map +0 -1
  80. package/dist/IssuerSessionClient.js +0 -28
  81. package/dist/IssuerSessionClient.js.map +0 -1
  82. package/lib/IssuerSessionClient.ts +0 -17
  83. package/lib/__tests__/IssuerSessionClient.spec.ts +0 -64
@@ -1,4 +1,6 @@
1
+ import { CreateDPoPClientOpts, JWK } from '@sphereon/oid4vc-common';
1
2
  import {
3
+ AccessTokenRequestOpts,
2
4
  AccessTokenResponse,
3
5
  Alg,
4
6
  AuthorizationRequestOpts,
@@ -15,6 +17,7 @@ import {
15
17
  CredentialsSupportedLegacy,
16
18
  DefaultURISchemes,
17
19
  determineVersionsFromIssuerMetadata,
20
+ DPoPResponseParams,
18
21
  EndpointMetadataResultV1_0_11,
19
22
  EndpointMetadataResultV1_0_13,
20
23
  ExperimentalSubjectIssuance,
@@ -22,8 +25,7 @@ import {
22
25
  getIssuerFromCredentialOfferPayload,
23
26
  getSupportedCredentials,
24
27
  getTypesFromCredentialSupported,
25
- getTypesFromObject, IssuerSessionResponse,
26
- JWK,
28
+ getTypesFromObject,
27
29
  KID_JWK_X5C_ERROR,
28
30
  NotificationRequest,
29
31
  NotificationResult,
@@ -31,7 +33,7 @@ import {
31
33
  OpenId4VCIVersion,
32
34
  PKCEOpts,
33
35
  ProofOfPossessionCallbacks,
34
- toAuthorizationResponsePayload
36
+ toAuthorizationResponsePayload,
35
37
  } from '@sphereon/oid4vci-common';
36
38
  import { CredentialFormat } from '@sphereon/ssi-types';
37
39
  import Debug from 'debug';
@@ -49,7 +51,6 @@ import { OpenID4VCIClientStateV1_0_11 } from './OpenID4VCIClientV1_0_11';
49
51
  import { OpenID4VCIClientStateV1_0_13 } from './OpenID4VCIClientV1_0_13';
50
52
  import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
51
53
  import { generateMissingPKCEOpts, sendNotification } from './functions';
52
- import { acquireIssuerSessionId } from './IssuerSessionClient';
53
54
 
54
55
  const debug = Debug('sphereon:oid4vci');
55
56
 
@@ -269,16 +270,13 @@ export class OpenID4VCIClient {
269
270
  this._state.pkce = generateMissingPKCEOpts({ ...this._state.pkce, ...pkce });
270
271
  }
271
272
 
272
- public async acquireAccessToken(opts?: {
273
- pin?: string;
274
- clientId?: string;
275
- codeVerifier?: string;
276
- authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
277
- code?: string; // Directly pass in a code from an auth response
278
- redirectUri?: string;
279
- additionalRequestParams?: Record<string, any>;
280
- asOpts?: AuthorizationServerOpts;
281
- }): Promise<AccessTokenResponse> {
273
+ public async acquireAccessToken(
274
+ opts?: Omit<AccessTokenRequestOpts, 'credentialOffer' | 'credentialIssuer' | 'metadata' | 'additionalParams'> & {
275
+ clientId?: string;
276
+ authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
277
+ additionalRequestParams?: Record<string, any>;
278
+ },
279
+ ): Promise<AccessTokenResponse & { params?: DPoPResponseParams }> {
282
280
  const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
283
281
  let { redirectUri } = opts ?? {};
284
282
  if (opts?.authorizationResponse) {
@@ -337,6 +335,7 @@ export class OpenID4VCIClient {
337
335
  code,
338
336
  redirectUri,
339
337
  asOpts,
338
+ ...(opts?.createDPoPOpts && { createDPoPOpts: opts.createDPoPOpts }),
340
339
  ...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
341
340
  });
342
341
 
@@ -356,20 +355,11 @@ export class OpenID4VCIClient {
356
355
  );
357
356
  }
358
357
  this._state.accessTokenResponse = response.successBody;
358
+ this._state.dpopResponseParams = response.params;
359
359
  this._state.accessToken = response.successBody.access_token;
360
360
  }
361
361
 
362
- return this.accessTokenResponse;
363
- }
364
-
365
- public async acquireIssuerSessionId() : Promise<IssuerSessionResponse | undefined> {
366
- if(!this._state.endpointMetadata) {
367
- return Promise.reject('endpointMetadata no loaded, retrieveServerMetadata()')
368
- }
369
- if(!('session_endpoint' in this._state.endpointMetadata) || !this._state.endpointMetadata.session_endpoint) {
370
- return undefined
371
- }
372
- return acquireIssuerSessionId({sessionEndpoint: this._state.endpointMetadata.session_endpoint})
362
+ return { ...this.accessTokenResponse, ...(this.dpopResponseParams && { params: this.dpopResponseParams }) };
373
363
  }
374
364
 
375
365
  public async acquireCredentials({
@@ -383,6 +373,7 @@ export class OpenID4VCIClient {
383
373
  jti,
384
374
  deferredCredentialAwait,
385
375
  deferredCredentialIntervalInMS,
376
+ createDPoPOpts,
386
377
  }: {
387
378
  credentialTypes: string | string[];
388
379
  context?: string[];
@@ -395,7 +386,8 @@ export class OpenID4VCIClient {
395
386
  deferredCredentialAwait?: boolean;
396
387
  deferredCredentialIntervalInMS?: number;
397
388
  experimentalHolderIssuanceSupported?: boolean;
398
- }): Promise<CredentialResponse & { access_token: string }> {
389
+ createDPoPOpts?: CreateDPoPClientOpts;
390
+ }): Promise<CredentialResponse & { params?: DPoPResponseParams; access_token: string }> {
399
391
  if ([jwk, kid].filter((v) => v !== undefined).length > 1) {
400
392
  throw new Error(KID_JWK_X5C_ERROR + `. jwk: ${jwk !== undefined}, kid: ${kid !== undefined}`);
401
393
  }
@@ -498,7 +490,9 @@ export class OpenID4VCIClient {
498
490
  context,
499
491
  format,
500
492
  subjectIssuance,
493
+ createDPoPOpts,
501
494
  });
495
+ this._state.dpopResponseParams = response.params;
502
496
  if (response.errorBody) {
503
497
  debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
504
498
  throw Error(
@@ -514,7 +508,7 @@ export class OpenID4VCIClient {
514
508
  } for issuer ${this.getIssuer()} failed as there was no success response body`,
515
509
  );
516
510
  }
517
- return { ...response.successBody, access_token: response.access_token };
511
+ return { ...response.successBody, ...(this.dpopResponseParams && { params: this.dpopResponseParams }), access_token: response.access_token };
518
512
  }
519
513
 
520
514
  public async exportState(): Promise<string> {
@@ -560,7 +554,7 @@ export class OpenID4VCIClient {
560
554
  issuerSupportedFlowTypes(): AuthzFlowType[] {
561
555
  return (
562
556
  this.credentialOffer?.supportedFlows ??
563
- (this._state.endpointMetadata?.credentialIssuerMetadata?.authorization_endpoint ?? this._state.endpointMetadata?.authorization_server
557
+ ((this._state.endpointMetadata?.credentialIssuerMetadata?.authorization_endpoint ?? this._state.endpointMetadata?.authorization_server)
564
558
  ? [AuthzFlowType.AUTHORIZATION_CODE_FLOW]
565
559
  : [])
566
560
  );
@@ -636,6 +630,10 @@ export class OpenID4VCIClient {
636
630
  return this._state.accessTokenResponse!;
637
631
  }
638
632
 
633
+ get dpopResponseParams(): DPoPResponseParams | undefined {
634
+ return this._state.dpopResponseParams;
635
+ }
636
+
639
637
  public getIssuer(): string {
640
638
  this.assertIssuerData();
641
639
  return this._state.credentialIssuer;
@@ -1,4 +1,6 @@
1
+ import { CreateDPoPClientOpts, JWK } from '@sphereon/oid4vc-common';
1
2
  import {
3
+ AccessTokenRequestOpts,
2
4
  AccessTokenResponse,
3
5
  Alg,
4
6
  AuthorizationRequestOpts,
@@ -13,13 +15,13 @@ import {
13
15
  CredentialResponse,
14
16
  CredentialsSupportedLegacy,
15
17
  DefaultURISchemes,
18
+ DPoPResponseParams,
16
19
  EndpointMetadataResultV1_0_11,
17
20
  getClientIdFromCredentialOfferPayload,
18
21
  getIssuerFromCredentialOfferPayload,
19
22
  getSupportedCredentials,
20
23
  getTypesFromCredentialSupported,
21
24
  getTypesFromObject,
22
- JWK,
23
25
  KID_JWK_X5C_ERROR,
24
26
  OID4VCICredentialFormat,
25
27
  OpenId4VCIVersion,
@@ -36,7 +38,7 @@ import { CredentialOfferClientV1_0_11 } from './CredentialOfferClientV1_0_11';
36
38
  import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
37
39
  import { MetadataClientV1_0_11 } from './MetadataClientV1_0_11';
38
40
  import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
39
- import { generateMissingPKCEOpts } from './functions/AuthorizationUtil';
41
+ import { generateMissingPKCEOpts } from './functions';
40
42
 
41
43
  const debug = Debug('sphereon:oid4vci');
42
44
 
@@ -49,6 +51,7 @@ export interface OpenID4VCIClientStateV1_0_11 {
49
51
  alg?: Alg | string;
50
52
  endpointMetadata?: EndpointMetadataResultV1_0_11;
51
53
  accessTokenResponse?: AccessTokenResponse;
54
+ dpopResponseParams?: DPoPResponseParams;
52
55
  authorizationRequestOpts?: AuthorizationRequestOpts;
53
56
  authorizationCodeResponse?: AuthorizationResponse;
54
57
  pkce: PKCEOpts;
@@ -253,16 +256,13 @@ export class OpenID4VCIClientV1_0_11 {
253
256
  this._state.pkce = generateMissingPKCEOpts({ ...this._state.pkce, ...pkce });
254
257
  }
255
258
 
256
- public async acquireAccessToken(opts?: {
257
- pin?: string;
258
- clientId?: string;
259
- codeVerifier?: string;
260
- authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
261
- code?: string; // Directly pass in a code from an auth response
262
- redirectUri?: string;
263
- additionalRequestParams?: Record<string, any>;
264
- asOpts?: AuthorizationServerOpts;
265
- }): Promise<AccessTokenResponse> {
259
+ public async acquireAccessToken(
260
+ opts?: Omit<AccessTokenRequestOpts, 'credentialOffer' | 'credentialIssuer' | 'metadata' | 'additionalParams'> & {
261
+ clientId?: string;
262
+ authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
263
+ additionalRequestParams?: Record<string, any>;
264
+ },
265
+ ): Promise<AccessTokenResponse & { params?: DPoPResponseParams }> {
266
266
  const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
267
267
  let { redirectUri } = opts ?? {};
268
268
  if (opts?.authorizationResponse) {
@@ -320,6 +320,7 @@ export class OpenID4VCIClientV1_0_11 {
320
320
  code,
321
321
  redirectUri,
322
322
  asOpts,
323
+ ...(opts?.createDPoPOpts && { createDPoPOpts: opts.createDPoPOpts }),
323
324
  ...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
324
325
  });
325
326
 
@@ -339,9 +340,11 @@ export class OpenID4VCIClientV1_0_11 {
339
340
  );
340
341
  }
341
342
  this._state.accessTokenResponse = response.successBody;
343
+ this._state.dpopResponseParams = response.params;
344
+ this._state.accessToken = response.successBody.access_token;
342
345
  }
343
346
 
344
- return this.accessTokenResponse;
347
+ return { ...this.accessTokenResponse, ...(this.dpopResponseParams && { params: this.dpopResponseParams }) };
345
348
  }
346
349
 
347
350
  public async acquireCredentials({
@@ -355,6 +358,7 @@ export class OpenID4VCIClientV1_0_11 {
355
358
  jti,
356
359
  deferredCredentialAwait,
357
360
  deferredCredentialIntervalInMS,
361
+ createDPoPOpts,
358
362
  }: {
359
363
  credentialTypes: string | string[];
360
364
  context?: string[];
@@ -366,6 +370,7 @@ export class OpenID4VCIClientV1_0_11 {
366
370
  jti?: string;
367
371
  deferredCredentialAwait?: boolean;
368
372
  deferredCredentialIntervalInMS?: number;
373
+ createDPoPOpts?: CreateDPoPClientOpts;
369
374
  }): Promise<CredentialResponse> {
370
375
  if ([jwk, kid].filter((v) => v !== undefined).length > 1) {
371
376
  throw new Error(KID_JWK_X5C_ERROR + `. jwk: ${jwk !== undefined}, kid: ${kid !== undefined}`);
@@ -445,7 +450,9 @@ export class OpenID4VCIClientV1_0_11 {
445
450
  credentialTypes,
446
451
  context,
447
452
  format,
453
+ createDPoPOpts,
448
454
  });
455
+ this._state.dpopResponseParams = response.params;
449
456
  if (response.errorBody) {
450
457
  debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
451
458
  throw Error(
@@ -461,7 +468,7 @@ export class OpenID4VCIClientV1_0_11 {
461
468
  } for issuer ${this.getIssuer()} failed as there was no success response body`,
462
469
  );
463
470
  }
464
- return response.successBody;
471
+ return { ...response.successBody, ...(this.dpopResponseParams && { params: this.dpopResponseParams }) };
465
472
  }
466
473
 
467
474
  public async exportState(): Promise<string> {
@@ -576,6 +583,10 @@ export class OpenID4VCIClientV1_0_11 {
576
583
  return this._state.accessTokenResponse!;
577
584
  }
578
585
 
586
+ get dpopResponseParams(): DPoPResponseParams | undefined {
587
+ return this._state.dpopResponseParams;
588
+ }
589
+
579
590
  public getIssuer(): string {
580
591
  this.assertIssuerData();
581
592
  return this._state.credentialIssuer;
@@ -1,4 +1,6 @@
1
+ import { CreateDPoPClientOpts, JWK } from '@sphereon/oid4vc-common';
1
2
  import {
3
+ AccessTokenRequestOpts,
2
4
  AccessTokenResponse,
3
5
  Alg,
4
6
  AuthorizationRequestOpts,
@@ -11,13 +13,13 @@ import {
11
13
  CredentialOfferRequestWithBaseUrl,
12
14
  CredentialResponse,
13
15
  DefaultURISchemes,
16
+ DPoPResponseParams,
14
17
  EndpointMetadataResultV1_0_13,
15
18
  ExperimentalSubjectIssuance,
16
19
  getClientIdFromCredentialOfferPayload,
17
20
  getIssuerFromCredentialOfferPayload,
18
21
  getSupportedCredentials,
19
22
  getTypesFromCredentialSupported,
20
- JWK,
21
23
  KID_JWK_X5C_ERROR,
22
24
  NotificationRequest,
23
25
  NotificationResult,
@@ -50,6 +52,7 @@ export interface OpenID4VCIClientStateV1_0_13 {
50
52
  alg?: Alg | string;
51
53
  endpointMetadata?: EndpointMetadataResultV1_0_13;
52
54
  accessTokenResponse?: AccessTokenResponse;
55
+ dpopResponseParams?: DPoPResponseParams;
53
56
  authorizationRequestOpts?: AuthorizationRequestOpts;
54
57
  authorizationCodeResponse?: AuthorizationResponse;
55
58
  pkce: PKCEOpts;
@@ -258,16 +261,13 @@ export class OpenID4VCIClientV1_0_13 {
258
261
  this._state.pkce = generateMissingPKCEOpts({ ...this._state.pkce, ...pkce });
259
262
  }
260
263
 
261
- public async acquireAccessToken(opts?: {
262
- pin?: string;
263
- clientId?: string;
264
- codeVerifier?: string;
265
- authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
266
- code?: string; // Directly pass in a code from an auth response
267
- redirectUri?: string;
268
- additionalRequestParams?: Record<string, any>;
269
- asOpts?: AuthorizationServerOpts;
270
- }): Promise<AccessTokenResponse> {
264
+ public async acquireAccessToken(
265
+ opts?: Omit<AccessTokenRequestOpts, 'credentialOffer' | 'credentialIssuer' | 'metadata' | 'additionalParams'> & {
266
+ clientId?: string;
267
+ authorizationResponse?: string | AuthorizationResponse; // Pass in an auth response, either as URI/redirect, or object
268
+ additionalRequestParams?: Record<string, any>;
269
+ },
270
+ ): Promise<AccessTokenResponse & { params?: DPoPResponseParams }> {
271
271
  const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
272
272
  let { redirectUri } = opts ?? {};
273
273
  if (opts?.authorizationResponse) {
@@ -324,6 +324,7 @@ export class OpenID4VCIClientV1_0_13 {
324
324
  code,
325
325
  redirectUri,
326
326
  asOpts,
327
+ ...(opts?.createDPoPOpts && { createDPoPOpts: opts.createDPoPOpts }),
327
328
  ...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
328
329
  });
329
330
 
@@ -343,10 +344,11 @@ export class OpenID4VCIClientV1_0_13 {
343
344
  );
344
345
  }
345
346
  this._state.accessTokenResponse = response.successBody;
347
+ this._state.dpopResponseParams = response.params;
346
348
  this._state.accessToken = response.successBody.access_token;
347
349
  }
348
350
 
349
- return this.accessTokenResponse;
351
+ return { ...this.accessTokenResponse, ...(this.dpopResponseParams && { params: this.dpopResponseParams }) };
350
352
  }
351
353
 
352
354
  public async acquireCredentials({
@@ -361,6 +363,7 @@ export class OpenID4VCIClientV1_0_13 {
361
363
  jti,
362
364
  deferredCredentialAwait,
363
365
  deferredCredentialIntervalInMS,
366
+ createDPoPOpts,
364
367
  }: {
365
368
  credentialIdentifier?: string;
366
369
  credentialTypes?: string | string[];
@@ -374,6 +377,7 @@ export class OpenID4VCIClientV1_0_13 {
374
377
  deferredCredentialAwait?: boolean;
375
378
  deferredCredentialIntervalInMS?: number;
376
379
  experimentalHolderIssuanceSupported?: boolean;
380
+ createDPoPOpts?: CreateDPoPClientOpts;
377
381
  }): Promise<CredentialResponse & { access_token: string }> {
378
382
  if ([jwk, kid].filter((v) => v !== undefined).length > 1) {
379
383
  throw new Error(KID_JWK_X5C_ERROR + `. jwk: ${jwk !== undefined}, kid: ${kid !== undefined}`);
@@ -471,7 +475,9 @@ export class OpenID4VCIClientV1_0_13 {
471
475
  const response = await credentialRequestClient.acquireCredentialsUsingProof({
472
476
  proofInput: proofBuilder,
473
477
  ...(credentialIdentifier ? { credentialIdentifier, subjectIssuance } : { format, context, credentialTypes, subjectIssuance }),
478
+ createDPoPOpts,
474
479
  });
480
+ this._state.dpopResponseParams = response.params;
475
481
  if (response.errorBody) {
476
482
  debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
477
483
  throw Error(
@@ -487,7 +493,7 @@ export class OpenID4VCIClientV1_0_13 {
487
493
  } for issuer ${this.getIssuer()} failed as there was no success response body`,
488
494
  );
489
495
  }
490
- return { ...response.successBody, access_token: response.access_token };
496
+ return { ...response.successBody, ...(this.dpopResponseParams && { params: this.dpopResponseParams }), access_token: response.access_token };
491
497
  }
492
498
 
493
499
  public async exportState(): Promise<string> {
@@ -604,6 +610,10 @@ export class OpenID4VCIClientV1_0_13 {
604
610
  return this._state.accessTokenResponse!;
605
611
  }
606
612
 
613
+ get dpopResponseParams(): DPoPResponseParams | undefined {
614
+ return this._state.dpopResponseParams;
615
+ }
616
+
607
617
  public getIssuer(): string {
608
618
  this.assertIssuerData();
609
619
  return this._state.credentialIssuer;
@@ -1,9 +1,9 @@
1
+ import { JWK } from '@sphereon/oid4vc-common';
1
2
  import {
2
3
  AccessTokenResponse,
3
4
  Alg,
4
5
  createProofOfPossession,
5
6
  EndpointMetadata,
6
- JWK,
7
7
  Jwt,
8
8
  NO_JWT_PROVIDED,
9
9
  OpenId4VCIVersion,
@@ -1,11 +1,4 @@
1
- import {
2
- AccessTokenRequest,
3
- AccessTokenResponse,
4
- GrantTypes,
5
- OpenIDResponse,
6
- PRE_AUTH_CODE_LITERAL,
7
- WellKnownEndpoints,
8
- } from '@sphereon/oid4vci-common';
1
+ import { AccessTokenRequest, AccessTokenResponse, GrantTypes, PRE_AUTH_CODE_LITERAL, WellKnownEndpoints } from '@sphereon/oid4vci-common';
9
2
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
10
3
  // @ts-ignore
11
4
  import nock from 'nock';
@@ -50,7 +43,7 @@ describe('AccessTokenClient should', () => {
50
43
  };
51
44
  nock(MOCK_URL).post(/.*/).reply(200, JSON.stringify(body));
52
45
 
53
- const accessTokenResponse: OpenIDResponse<AccessTokenResponse> = await accessTokenClient.acquireAccessTokenUsingRequest({
46
+ const accessTokenResponse = await accessTokenClient.acquireAccessTokenUsingRequest({
54
47
  accessTokenRequest,
55
48
  pinMetadata: {
56
49
  isPinRequired: true,
@@ -88,7 +81,7 @@ describe('AccessTokenClient should', () => {
88
81
  };
89
82
  nock(MOCK_URL).post(/.*/).reply(200, JSON.stringify(body));
90
83
 
91
- const accessTokenResponse: OpenIDResponse<AccessTokenResponse> = await accessTokenClient.acquireAccessTokenUsingRequest({
84
+ const accessTokenResponse = await accessTokenClient.acquireAccessTokenUsingRequest({
92
85
  accessTokenRequest,
93
86
  asOpts: { as: MOCK_URL },
94
87
  });
@@ -227,7 +220,7 @@ describe('AccessTokenClient should', () => {
227
220
  .post(/.*/)
228
221
  .reply(200, {});
229
222
 
230
- const response: OpenIDResponse<AccessTokenResponse> = await accessTokenClient.acquireAccessToken({
223
+ const response = await accessTokenClient.acquireAccessToken({
231
224
  credentialOffer: INITIATION_TEST,
232
225
  pin: '1234',
233
226
  });
@@ -1,12 +1,12 @@
1
1
  import * as crypto from 'crypto';
2
2
 
3
+ import { uuidv4 } from '@sphereon/oid4vc-common';
3
4
  import { Alg, Jwt, ProofOfPossessionCallbacks } from '@sphereon/oid4vci-common';
4
5
  import { CredentialMapper } from '@sphereon/ssi-types';
5
6
  import * as didts from '@transmute/did-key.js';
6
7
  import { fetch } from 'cross-fetch';
7
8
  import debug from 'debug';
8
9
  import { importJWK, JWK, SignJWT } from 'jose';
9
- import { v4 } from 'uuid';
10
10
 
11
11
  import { OpenID4VCIClientV1_0_11 } from '..';
12
12
 
@@ -94,7 +94,7 @@ async function getCredentialOffer(format: 'ldp_vc' | 'jwt_vc_json'): Promise<Cre
94
94
  credentials: ['GuestCredential'],
95
95
  grants: {
96
96
  'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
97
- 'pre-authorized_code': v4().substring(0, 10),
97
+ 'pre-authorized_code': uuidv4().substring(0, 10),
98
98
  user_pin_required: false,
99
99
  },
100
100
  },
@@ -165,7 +165,7 @@ describe('ismapolis bug report #63, https://github.com/Sphereon-Opensource/OID4V
165
165
  format: 'jwt_vc_json',
166
166
  alg: Alg.ES256K,
167
167
  kid: didDocument.verificationMethod[0].id,
168
- jti: v4(),
168
+ jti: uuidv4(),
169
169
  });
170
170
  console.log(JSON.stringify(credentialResponse.credential));
171
171
  });
@@ -1,5 +1,5 @@
1
+ import { uuidv4 } from '@sphereon/oid4vc-common';
1
2
  import { AccessTokenRequest, AccessTokenRequestOpts, Jwt, OpenId4VCIVersion } from '@sphereon/oid4vci-common';
2
- import { v4 } from 'uuid';
3
3
 
4
4
  import { ProofOfPossessionBuilder } from '../ProofOfPossessionBuilder';
5
5
 
@@ -35,7 +35,7 @@ export const createJwtBearerClientAssertion = async (
35
35
  iss: clientId,
36
36
  sub: clientId,
37
37
  aud: credentialIssuer,
38
- jti: v4(),
38
+ jti: uuidv4(),
39
39
  exp: Date.now() / 1000 + 60,
40
40
  iat: Date.now() / 1000 - 60,
41
41
  },
@@ -0,0 +1,35 @@
1
+ import { dpopTokenRequestNonceError } from '@sphereon/oid4vc-common';
2
+ import { OpenIDResponse } from 'oid4vci-common';
3
+
4
+ export type RetryRequestWithDPoPNonce = { ok: true; dpopNonce: string } | { ok: false };
5
+
6
+ export function shouldRetryTokenRequestWithDPoPNonce(response: OpenIDResponse<unknown, unknown>): RetryRequestWithDPoPNonce {
7
+ if (!response.errorBody || response.errorBody.error !== dpopTokenRequestNonceError) {
8
+ return { ok: false };
9
+ }
10
+
11
+ const dPoPNonce = response.origResponse.headers.get('DPoP-Nonce');
12
+ if (!dPoPNonce) {
13
+ throw new Error('Missing required DPoP-Nonce header.');
14
+ }
15
+
16
+ return { ok: true, dpopNonce: dPoPNonce };
17
+ }
18
+
19
+ export function shouldRetryResourceRequestWithDPoPNonce(response: OpenIDResponse<unknown, unknown>): RetryRequestWithDPoPNonce {
20
+ if (!response.errorBody || response.origResponse.status !== 401) {
21
+ return { ok: false };
22
+ }
23
+
24
+ const wwwAuthenticateHeader = response.origResponse.headers.get('WWW-Authenticate');
25
+ if (!wwwAuthenticateHeader?.includes(dpopTokenRequestNonceError)) {
26
+ return { ok: false };
27
+ }
28
+
29
+ const dPoPNonce = response.origResponse.headers.get('DPoP-Nonce');
30
+ if (!dPoPNonce) {
31
+ throw new Error('Missing required DPoP-Nonce header.');
32
+ }
33
+
34
+ return { ok: true, dpopNonce: dPoPNonce };
35
+ }
@@ -19,12 +19,10 @@ export async function sendNotification(
19
19
  const error = response.errorBody?.error !== undefined;
20
20
  const result = {
21
21
  error,
22
- response: error ? await response.errorBody?.json() : undefined,
22
+ response: error ? response.errorBody : undefined,
23
23
  };
24
24
  if (error) {
25
- LOG.warning(
26
- `Notification endpoint returned an error for event '${request.event}' and id ${request.notification_id}: ${await response.errorBody?.json()}`,
27
- );
25
+ LOG.warning(`Notification endpoint returned an error for event '${request.event}' and id ${request.notification_id}: ${response.errorBody}`);
28
26
  } else {
29
27
  LOG.debug(`Notification endpoint returned success for event '${request.event}' and id ${request.notification_id}`);
30
28
  }
package/lib/index.ts CHANGED
@@ -22,5 +22,4 @@ export * from './MetadataClientV1_0_11';
22
22
  export * from './OpenID4VCIClient';
23
23
  export * from './OpenID4VCIClientV1_0_13';
24
24
  export * from './OpenID4VCIClientV1_0_11';
25
- export * from './IssuerSessionClient';
26
25
  export * from './ProofOfPossessionBuilder';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sphereon/oid4vci-client",
3
- "version": "0.15.2-unstable.8+bdd7117",
3
+ "version": "0.16.1-next.13+282e7a1",
4
4
  "description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
5
5
  "source": "lib/index.ts",
6
6
  "main": "dist/index.js",
@@ -15,8 +15,9 @@
15
15
  "build": "tsc"
16
16
  },
17
17
  "dependencies": {
18
- "@sphereon/oid4vci-common": "0.15.2-unstable.8+bdd7117",
19
- "@sphereon/ssi-types": "0.28.0",
18
+ "@sphereon/oid4vc-common": "0.16.1-next.13+282e7a1",
19
+ "@sphereon/oid4vci-common": "0.16.1-next.13+282e7a1",
20
+ "@sphereon/ssi-types": "0.29.0",
20
21
  "cross-fetch": "^3.1.8",
21
22
  "debug": "^4.3.5"
22
23
  },
@@ -69,5 +70,5 @@
69
70
  "OIDC4VCI",
70
71
  "OID4VCI"
71
72
  ],
72
- "gitHead": "bdd711734c65ba2a33b14ee5eacd0a9d619d800e"
73
+ "gitHead": "282e7a1c6b9becaf12b81302a5c84d34f525ae7a"
73
74
  }
@@ -1,3 +0,0 @@
1
- import { IssuerSessionIdRequestOpts, IssuerSessionResponse } from '@sphereon/oid4vci-common';
2
- export declare const acquireIssuerSessionId: (opts: IssuerSessionIdRequestOpts) => Promise<IssuerSessionResponse>;
3
- //# sourceMappingURL=IssuerSessionClient.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IssuerSessionClient.d.ts","sourceRoot":"","sources":["../lib/IssuerSessionClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAwB,MAAM,0BAA0B,CAAC;AAInH,eAAO,MAAM,sBAAsB,SAAgB,0BAA0B,KAAG,OAAO,CAAC,qBAAqB,CAY5G,CAAA"}
@@ -1,28 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.acquireIssuerSessionId = void 0;
13
- const oid4vci_common_1 = require("@sphereon/oid4vci-common");
14
- const index_1 = require("./index");
15
- const acquireIssuerSessionId = (opts) => __awaiter(void 0, void 0, void 0, function* () {
16
- index_1.LOG.debug(`acquiring issuer session endpoint from endpoint ${opts.sessionEndpoint}`);
17
- const sessionResponse = yield (0, oid4vci_common_1.post)(opts.sessionEndpoint);
18
- if (sessionResponse.errorBody !== undefined) {
19
- return Promise.reject(`an error occurred while requesting a issuer session token from endpoint ${opts.sessionEndpoint}:
20
- ${sessionResponse.errorBody.error} - ${sessionResponse.errorBody.error_description}`);
21
- }
22
- if (sessionResponse.successBody === undefined || !Object.keys(sessionResponse.successBody).includes('session_id')) {
23
- return Promise.reject(`an error occurred while requesting a issuer session token from endpoint ${opts.sessionEndpoint}, missing session_token response`);
24
- }
25
- return sessionResponse.successBody;
26
- });
27
- exports.acquireIssuerSessionId = acquireIssuerSessionId;
28
- //# sourceMappingURL=IssuerSessionClient.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IssuerSessionClient.js","sourceRoot":"","sources":["../lib/IssuerSessionClient.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6DAAmH;AAEnH,mCAA8B;AAEvB,MAAM,sBAAsB,GAAG,CAAO,IAAgC,EAAkC,EAAE;IAC/G,WAAG,CAAC,KAAK,CAAC,mDAAmD,IAAI,CAAC,eAAe,EAAE,CAAC,CAAA;IACpF,MAAM,eAAe,GAAG,MAAM,IAAA,qBAAI,EAAC,IAAI,CAAC,eAAe,CAA0C,CAAA;IACjG,IAAI,eAAe,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5C,OAAO,OAAO,CAAC,MAAM,CAAC,2EAA2E,IAAI,CAAC,eAAe;OAClH,eAAe,CAAC,SAAS,CAAC,KAAK,MAAM,eAAe,CAAC,SAAS,CAAC,iBAAiB,EAAE,CAAC,CAAA;IACxF,CAAC;IACD,IAAI,eAAe,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAClH,OAAO,OAAO,CAAC,MAAM,CAAC,2EAA2E,IAAI,CAAC,eAAe,kCAAkC,CAAC,CAAA;IAE1J,CAAC;IACD,OAAO,eAAe,CAAC,WAAW,CAAA;AACpC,CAAC,CAAA,CAAA;AAZY,QAAA,sBAAsB,0BAYlC"}
@@ -1,17 +0,0 @@
1
- import { IssuerSessionIdRequestOpts, IssuerSessionResponse, OpenIDResponse, post } from '@sphereon/oid4vci-common';
2
-
3
- import { LOG } from './index';
4
-
5
- export const acquireIssuerSessionId = async (opts: IssuerSessionIdRequestOpts): Promise<IssuerSessionResponse> => {
6
- LOG.debug(`acquiring issuer session endpoint from endpoint ${opts.sessionEndpoint}`)
7
- const sessionResponse = await post(opts.sessionEndpoint) as OpenIDResponse<IssuerSessionResponse>
8
- if (sessionResponse.errorBody !== undefined) {
9
- return Promise.reject(`an error occurred while requesting a issuer session token from endpoint ${opts.sessionEndpoint}:
10
- ${sessionResponse.errorBody.error} - ${sessionResponse.errorBody.error_description}`)
11
- }
12
- if (sessionResponse.successBody === undefined || !Object.keys(sessionResponse.successBody).includes('session_id')) {
13
- return Promise.reject(`an error occurred while requesting a issuer session token from endpoint ${opts.sessionEndpoint}, missing session_token response`)
14
-
15
- }
16
- return sessionResponse.successBody
17
- }