@sphereon/oid4vci-client 0.16.1-next.3 → 0.16.1-next.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +11 -10
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
- package/dist/AccessTokenClientV1_0_11.js +10 -9
- package/dist/AccessTokenClientV1_0_11.js.map +1 -1
- package/dist/AuthorizationCodeClient.d.ts.map +1 -1
- package/dist/AuthorizationCodeClient.js +3 -2
- package/dist/AuthorizationCodeClient.js.map +1 -1
- package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -1
- package/dist/CredentialRequestClient.d.ts +36 -12
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js +59 -23
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.js +11 -1
- package/dist/CredentialRequestClientV1_0_11.js.map +1 -1
- package/dist/MetadataClient.d.ts +1 -0
- package/dist/MetadataClient.d.ts.map +1 -1
- package/dist/MetadataClient.js +5 -4
- package/dist/MetadataClient.js.map +1 -1
- package/dist/MetadataClientV1_0_13.d.ts +1 -0
- package/dist/MetadataClientV1_0_13.d.ts.map +1 -1
- package/dist/MetadataClientV1_0_13.js +5 -4
- package/dist/MetadataClientV1_0_13.js.map +1 -1
- package/dist/OpenID4VCIClient.d.ts +10 -10
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +11 -5
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.d.ts +10 -10
- package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.js +14 -7
- package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.d.ts +27 -10
- package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.js +64 -28
- package/dist/OpenID4VCIClientV1_0_13.js.map +1 -1
- package/dist/ProofOfPossessionBuilder.d.ts +1 -1
- package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
- package/lib/AccessTokenClient.ts +15 -13
- package/lib/AccessTokenClientV1_0_11.ts +13 -12
- package/lib/AuthorizationCodeClient.ts +3 -1
- package/lib/AuthorizationCodeClientV1_0_11.ts +2 -2
- package/lib/CredentialRequestClient.ts +97 -24
- package/lib/CredentialRequestClientV1_0_11.ts +11 -1
- package/lib/MetadataClient.ts +2 -1
- package/lib/MetadataClientV1_0_13.ts +2 -1
- package/lib/OpenID4VCIClient.ts +23 -14
- package/lib/OpenID4VCIClientV1_0_11.ts +25 -14
- package/lib/OpenID4VCIClientV1_0_13.ts +103 -41
- package/lib/ProofOfPossessionBuilder.ts +1 -1
- package/lib/__tests__/IT.spec.ts +1 -1
- package/package.json +5 -5
|
@@ -2,6 +2,7 @@ import { createDPoP, CreateDPoPClientOpts, getCreateDPoPOptions } from '@sphereo
|
|
|
2
2
|
import {
|
|
3
3
|
acquireDeferredCredential,
|
|
4
4
|
CredentialRequestV1_0_13,
|
|
5
|
+
CredentialRequestWithoutProofV1_0_13,
|
|
5
6
|
CredentialResponse,
|
|
6
7
|
DPoPResponseParams,
|
|
7
8
|
getCredentialRequestForVersion,
|
|
@@ -16,8 +17,8 @@ import {
|
|
|
16
17
|
UniformCredentialRequest,
|
|
17
18
|
URL_NOT_VALID,
|
|
18
19
|
} from '@sphereon/oid4vci-common';
|
|
19
|
-
import { ExperimentalSubjectIssuance } from '@sphereon/oid4vci-common
|
|
20
|
-
import { CredentialFormat } from '@sphereon/ssi-types';
|
|
20
|
+
import { ExperimentalSubjectIssuance } from '@sphereon/oid4vci-common';
|
|
21
|
+
import { CredentialFormat, DIDDocument } from '@sphereon/ssi-types';
|
|
21
22
|
import Debug from 'debug';
|
|
22
23
|
|
|
23
24
|
import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
|
|
@@ -42,7 +43,16 @@ export interface CredentialRequestOpts {
|
|
|
42
43
|
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
export
|
|
46
|
+
export type CreateCredentialRequestOpts<DIDDoc = DIDDocument> = {
|
|
47
|
+
credentialIdentifier?: string;
|
|
48
|
+
credentialTypes?: string | string[];
|
|
49
|
+
context?: string[];
|
|
50
|
+
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
51
|
+
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
52
|
+
version: OpenId4VCIVersion;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export async function buildProof<DIDDoc = DIDDocument>(
|
|
46
56
|
proofInput: ProofOfPossessionBuilder<DIDDoc> | ProofOfPossession,
|
|
47
57
|
opts: {
|
|
48
58
|
version: OpenId4VCIVersion;
|
|
@@ -85,7 +95,34 @@ export class CredentialRequestClient {
|
|
|
85
95
|
this._credentialRequestOpts = { ...builder };
|
|
86
96
|
}
|
|
87
97
|
|
|
88
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Typically you should not use this method, as it omits a proof from the request.
|
|
100
|
+
* There are certain issuers that in specific circumstances can do without this proof, because they have other means of user binding
|
|
101
|
+
* like using DPoP together with an authorization code flow. These are however rare, so you should be using the acquireCredentialsUsingProof normally
|
|
102
|
+
* @param opts
|
|
103
|
+
*/
|
|
104
|
+
public async acquireCredentialsWithoutProof<DIDDoc = DIDDocument>(opts: {
|
|
105
|
+
credentialIdentifier?: string;
|
|
106
|
+
credentialTypes?: string | string[];
|
|
107
|
+
context?: string[];
|
|
108
|
+
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
109
|
+
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
110
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
111
|
+
}): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
112
|
+
const { credentialIdentifier, credentialTypes, format, context, subjectIssuance } = opts;
|
|
113
|
+
|
|
114
|
+
const request = await this.createCredentialRequestWithoutProof<DIDDoc>({
|
|
115
|
+
credentialTypes,
|
|
116
|
+
context,
|
|
117
|
+
format,
|
|
118
|
+
version: this.version(),
|
|
119
|
+
credentialIdentifier,
|
|
120
|
+
subjectIssuance,
|
|
121
|
+
});
|
|
122
|
+
return await this.acquireCredentialsUsingRequestWithoutProof(request, opts.createDPoPOpts);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public async acquireCredentialsUsingProof<DIDDoc = DIDDocument>(opts: {
|
|
89
126
|
proofInput: ProofOfPossessionBuilder<DIDDoc> | ProofOfPossession;
|
|
90
127
|
credentialIdentifier?: string;
|
|
91
128
|
credentialTypes?: string | string[];
|
|
@@ -96,7 +133,7 @@ export class CredentialRequestClient {
|
|
|
96
133
|
}): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
97
134
|
const { credentialIdentifier, credentialTypes, proofInput, format, context, subjectIssuance } = opts;
|
|
98
135
|
|
|
99
|
-
const request = await this.createCredentialRequest({
|
|
136
|
+
const request = await this.createCredentialRequest<DIDDoc>({
|
|
100
137
|
proofInput,
|
|
101
138
|
credentialTypes,
|
|
102
139
|
context,
|
|
@@ -108,9 +145,23 @@ export class CredentialRequestClient {
|
|
|
108
145
|
return await this.acquireCredentialsUsingRequest(request, opts.createDPoPOpts);
|
|
109
146
|
}
|
|
110
147
|
|
|
148
|
+
public async acquireCredentialsUsingRequestWithoutProof(
|
|
149
|
+
uniformRequest: UniformCredentialRequest,
|
|
150
|
+
createDPoPOpts?: CreateDPoPClientOpts,
|
|
151
|
+
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
152
|
+
return await this.acquireCredentialsUsingRequestImpl(uniformRequest, createDPoPOpts);
|
|
153
|
+
}
|
|
154
|
+
|
|
111
155
|
public async acquireCredentialsUsingRequest(
|
|
112
156
|
uniformRequest: UniformCredentialRequest,
|
|
113
157
|
createDPoPOpts?: CreateDPoPClientOpts,
|
|
158
|
+
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
159
|
+
return await this.acquireCredentialsUsingRequestImpl(uniformRequest, createDPoPOpts);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private async acquireCredentialsUsingRequestImpl(
|
|
163
|
+
uniformRequest: UniformCredentialRequest & { proof?: ProofOfPossession },
|
|
164
|
+
createDPoPOpts?: CreateDPoPClientOpts,
|
|
114
165
|
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
115
166
|
if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
|
|
116
167
|
throw new Error('Versions below v1.0.13 (draft 13) are not supported by the V13 credential request client.');
|
|
@@ -129,7 +180,7 @@ export class CredentialRequestClient {
|
|
|
129
180
|
|
|
130
181
|
let response = (await post(credentialEndpoint, JSON.stringify(request), {
|
|
131
182
|
bearerToken: requestToken,
|
|
132
|
-
|
|
183
|
+
...(dPoP && { customHeaders: { dpop: dPoP } }),
|
|
133
184
|
})) as OpenIDResponse<CredentialResponse> & {
|
|
134
185
|
access_token: string;
|
|
135
186
|
};
|
|
@@ -142,7 +193,7 @@ export class CredentialRequestClient {
|
|
|
142
193
|
|
|
143
194
|
response = (await post(credentialEndpoint, JSON.stringify(request), {
|
|
144
195
|
bearerToken: requestToken,
|
|
145
|
-
|
|
196
|
+
...(createDPoPOpts && { customHeaders: { dpop: dPoP } }),
|
|
146
197
|
})) as OpenIDResponse<CredentialResponse> & {
|
|
147
198
|
access_token: string;
|
|
148
199
|
};
|
|
@@ -166,7 +217,7 @@ export class CredentialRequestClient {
|
|
|
166
217
|
|
|
167
218
|
return {
|
|
168
219
|
...response,
|
|
169
|
-
|
|
220
|
+
...(nextDPoPNonce && { params: { dpop: { dpopNonce: nextDPoPNonce } } }),
|
|
170
221
|
};
|
|
171
222
|
}
|
|
172
223
|
|
|
@@ -194,24 +245,37 @@ export class CredentialRequestClient {
|
|
|
194
245
|
});
|
|
195
246
|
}
|
|
196
247
|
|
|
197
|
-
public async
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
248
|
+
public async createCredentialRequestWithoutProof<DIDDoc = DIDDocument>(
|
|
249
|
+
opts: CreateCredentialRequestOpts<DIDDoc>,
|
|
250
|
+
): Promise<CredentialRequestWithoutProofV1_0_13> {
|
|
251
|
+
return await this.createCredentialRequestImpl(opts);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public async createCredentialRequest<DIDDoc = DIDDocument>(
|
|
255
|
+
opts: CreateCredentialRequestOpts<DIDDoc> & {
|
|
256
|
+
proofInput: ProofOfPossessionBuilder<DIDDoc> | ProofOfPossession;
|
|
257
|
+
},
|
|
258
|
+
): Promise<CredentialRequestV1_0_13> {
|
|
259
|
+
return await this.createCredentialRequestImpl(opts);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private async createCredentialRequestImpl<DIDDoc = DIDDocument>(
|
|
263
|
+
opts: CreateCredentialRequestOpts<DIDDoc> & {
|
|
264
|
+
proofInput?: ProofOfPossessionBuilder<DIDDoc> | ProofOfPossession;
|
|
265
|
+
},
|
|
266
|
+
): Promise<CredentialRequestV1_0_13> {
|
|
206
267
|
const { proofInput, credentialIdentifier: credential_identifier } = opts;
|
|
207
|
-
|
|
268
|
+
let proof: ProofOfPossession | undefined = undefined;
|
|
269
|
+
if (proofInput) {
|
|
270
|
+
proof = await buildProof(proofInput, opts);
|
|
271
|
+
}
|
|
208
272
|
if (credential_identifier) {
|
|
209
273
|
if (opts.format || opts.credentialTypes || opts.context) {
|
|
210
274
|
throw Error(`You cannot mix credential_identifier with format, credential types and/or context`);
|
|
211
275
|
}
|
|
212
276
|
return {
|
|
213
277
|
credential_identifier,
|
|
214
|
-
proof,
|
|
278
|
+
...(proof && { proof }),
|
|
215
279
|
};
|
|
216
280
|
}
|
|
217
281
|
const formatSelection = opts.format ?? this.credentialRequestOpts.format;
|
|
@@ -239,7 +303,7 @@ export class CredentialRequestClient {
|
|
|
239
303
|
type: types,
|
|
240
304
|
},
|
|
241
305
|
format,
|
|
242
|
-
proof,
|
|
306
|
+
...(proof && { proof }),
|
|
243
307
|
...opts.subjectIssuance,
|
|
244
308
|
};
|
|
245
309
|
} else if (format === 'jwt_vc_json-ld' || format === 'ldp_vc') {
|
|
@@ -249,7 +313,7 @@ export class CredentialRequestClient {
|
|
|
249
313
|
|
|
250
314
|
return {
|
|
251
315
|
format,
|
|
252
|
-
proof,
|
|
316
|
+
...(proof && { proof }),
|
|
253
317
|
...opts.subjectIssuance,
|
|
254
318
|
|
|
255
319
|
credential_definition: {
|
|
@@ -261,16 +325,25 @@ export class CredentialRequestClient {
|
|
|
261
325
|
if (types.length > 1) {
|
|
262
326
|
throw Error(`Only a single credential type is supported for ${format}`);
|
|
263
327
|
}
|
|
264
|
-
// fixme: this isn't up to the CredentialRequest that we see in the version v1_0_13
|
|
265
328
|
return {
|
|
266
329
|
format,
|
|
267
|
-
proof,
|
|
330
|
+
...(proof && { proof }),
|
|
268
331
|
vct: types[0],
|
|
269
332
|
...opts.subjectIssuance,
|
|
270
333
|
};
|
|
334
|
+
} else if (format === 'mso_mdoc') {
|
|
335
|
+
if (types.length > 1) {
|
|
336
|
+
throw Error(`Only a single credential type is supported for ${format}`);
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
format,
|
|
340
|
+
...(proof && { proof }),
|
|
341
|
+
doctype: types[0],
|
|
342
|
+
...opts.subjectIssuance,
|
|
343
|
+
};
|
|
271
344
|
}
|
|
272
345
|
|
|
273
|
-
throw new Error(`Unsupported format: ${format}`);
|
|
346
|
+
throw new Error(`Unsupported credential format: ${format}`);
|
|
274
347
|
}
|
|
275
348
|
|
|
276
349
|
private version(): OpenId4VCIVersion {
|
|
@@ -125,7 +125,7 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
125
125
|
|
|
126
126
|
return {
|
|
127
127
|
...response,
|
|
128
|
-
|
|
128
|
+
...(nextDPoPNonce && { params: { dpop: { dpopNonce: nextDPoPNonce } } }),
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -215,6 +215,16 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
215
215
|
proof,
|
|
216
216
|
vct: types[0],
|
|
217
217
|
};
|
|
218
|
+
} else if (format === 'mso_mdoc') {
|
|
219
|
+
if (types.length > 1) {
|
|
220
|
+
throw Error(`Only a single credential type is supported for ${format}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
format,
|
|
225
|
+
proof,
|
|
226
|
+
doctype: types[0],
|
|
227
|
+
};
|
|
218
228
|
}
|
|
219
229
|
|
|
220
230
|
throw new Error(`Unsupported format: ${format}`);
|
package/lib/MetadataClient.ts
CHANGED
|
@@ -19,7 +19,7 @@ import Debug from 'debug';
|
|
|
19
19
|
|
|
20
20
|
import { MetadataClientV1_0_11 } from './MetadataClientV1_0_11';
|
|
21
21
|
import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13';
|
|
22
|
-
import { retrieveWellknown } from './functions
|
|
22
|
+
import { retrieveWellknown } from './functions';
|
|
23
23
|
|
|
24
24
|
const debug = Debug('sphereon:oid4vci:metadata');
|
|
25
25
|
|
|
@@ -204,6 +204,7 @@ export class MetadataClient {
|
|
|
204
204
|
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
|
|
205
205
|
*
|
|
206
206
|
* @param issuerHost The issuer hostname
|
|
207
|
+
* @param opts
|
|
207
208
|
*/
|
|
208
209
|
public static async retrieveOpenID4VCIServerMetadata(
|
|
209
210
|
issuerHost: string,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '@sphereon/oid4vci-common';
|
|
13
13
|
import Debug from 'debug';
|
|
14
14
|
|
|
15
|
-
import { retrieveWellknown } from './functions
|
|
15
|
+
import { retrieveWellknown } from './functions';
|
|
16
16
|
|
|
17
17
|
const debug = Debug('sphereon:oid4vci:metadata');
|
|
18
18
|
|
|
@@ -174,6 +174,7 @@ export class MetadataClientV1_0_13 {
|
|
|
174
174
|
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
|
|
175
175
|
*
|
|
176
176
|
* @param issuerHost The issuer hostname
|
|
177
|
+
* @param opts
|
|
177
178
|
*/
|
|
178
179
|
public static async retrieveOpenID4VCIServerMetadata(
|
|
179
180
|
issuerHost: string,
|
package/lib/OpenID4VCIClient.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { JWK } from '@sphereon/oid4vc-common';
|
|
1
|
+
import { CreateDPoPClientOpts, JWK } from '@sphereon/oid4vc-common';
|
|
2
2
|
import {
|
|
3
|
+
AccessTokenRequestOpts,
|
|
3
4
|
AccessTokenResponse,
|
|
4
5
|
Alg,
|
|
5
6
|
AuthorizationRequestOpts,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
CredentialsSupportedLegacy,
|
|
17
18
|
DefaultURISchemes,
|
|
18
19
|
determineVersionsFromIssuerMetadata,
|
|
20
|
+
DPoPResponseParams,
|
|
19
21
|
EndpointMetadataResultV1_0_11,
|
|
20
22
|
EndpointMetadataResultV1_0_13,
|
|
21
23
|
ExperimentalSubjectIssuance,
|
|
@@ -268,16 +270,13 @@ export class OpenID4VCIClient {
|
|
|
268
270
|
this._state.pkce = generateMissingPKCEOpts({ ...this._state.pkce, ...pkce });
|
|
269
271
|
}
|
|
270
272
|
|
|
271
|
-
public async acquireAccessToken(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
additionalRequestParams?: Record<string, any>;
|
|
279
|
-
asOpts?: AuthorizationServerOpts;
|
|
280
|
-
}): 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 }> {
|
|
281
280
|
const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
|
|
282
281
|
let { redirectUri } = opts ?? {};
|
|
283
282
|
if (opts?.authorizationResponse) {
|
|
@@ -336,6 +335,7 @@ export class OpenID4VCIClient {
|
|
|
336
335
|
code,
|
|
337
336
|
redirectUri,
|
|
338
337
|
asOpts,
|
|
338
|
+
...(opts?.createDPoPOpts && { createDPoPOpts: opts.createDPoPOpts }),
|
|
339
339
|
...(opts?.additionalRequestParams && { additionalParams: opts.additionalRequestParams }),
|
|
340
340
|
});
|
|
341
341
|
|
|
@@ -355,10 +355,11 @@ export class OpenID4VCIClient {
|
|
|
355
355
|
);
|
|
356
356
|
}
|
|
357
357
|
this._state.accessTokenResponse = response.successBody;
|
|
358
|
+
this._state.dpopResponseParams = response.params;
|
|
358
359
|
this._state.accessToken = response.successBody.access_token;
|
|
359
360
|
}
|
|
360
361
|
|
|
361
|
-
return this.accessTokenResponse;
|
|
362
|
+
return { ...this.accessTokenResponse, ...(this.dpopResponseParams && { params: this.dpopResponseParams }) };
|
|
362
363
|
}
|
|
363
364
|
|
|
364
365
|
public async acquireCredentials({
|
|
@@ -372,6 +373,7 @@ export class OpenID4VCIClient {
|
|
|
372
373
|
jti,
|
|
373
374
|
deferredCredentialAwait,
|
|
374
375
|
deferredCredentialIntervalInMS,
|
|
376
|
+
createDPoPOpts,
|
|
375
377
|
}: {
|
|
376
378
|
credentialTypes: string | string[];
|
|
377
379
|
context?: string[];
|
|
@@ -384,7 +386,8 @@ export class OpenID4VCIClient {
|
|
|
384
386
|
deferredCredentialAwait?: boolean;
|
|
385
387
|
deferredCredentialIntervalInMS?: number;
|
|
386
388
|
experimentalHolderIssuanceSupported?: boolean;
|
|
387
|
-
|
|
389
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
390
|
+
}): Promise<CredentialResponse & { params?: DPoPResponseParams; access_token: string }> {
|
|
388
391
|
if ([jwk, kid].filter((v) => v !== undefined).length > 1) {
|
|
389
392
|
throw new Error(KID_JWK_X5C_ERROR + `. jwk: ${jwk !== undefined}, kid: ${kid !== undefined}`);
|
|
390
393
|
}
|
|
@@ -487,7 +490,9 @@ export class OpenID4VCIClient {
|
|
|
487
490
|
context,
|
|
488
491
|
format,
|
|
489
492
|
subjectIssuance,
|
|
493
|
+
createDPoPOpts,
|
|
490
494
|
});
|
|
495
|
+
this._state.dpopResponseParams = response.params;
|
|
491
496
|
if (response.errorBody) {
|
|
492
497
|
debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
|
|
493
498
|
throw Error(
|
|
@@ -503,7 +508,7 @@ export class OpenID4VCIClient {
|
|
|
503
508
|
} for issuer ${this.getIssuer()} failed as there was no success response body`,
|
|
504
509
|
);
|
|
505
510
|
}
|
|
506
|
-
return { ...response.successBody, access_token: response.access_token };
|
|
511
|
+
return { ...response.successBody, ...(this.dpopResponseParams && { params: this.dpopResponseParams }), access_token: response.access_token };
|
|
507
512
|
}
|
|
508
513
|
|
|
509
514
|
public async exportState(): Promise<string> {
|
|
@@ -625,6 +630,10 @@ export class OpenID4VCIClient {
|
|
|
625
630
|
return this._state.accessTokenResponse!;
|
|
626
631
|
}
|
|
627
632
|
|
|
633
|
+
get dpopResponseParams(): DPoPResponseParams | undefined {
|
|
634
|
+
return this._state.dpopResponseParams;
|
|
635
|
+
}
|
|
636
|
+
|
|
628
637
|
public getIssuer(): string {
|
|
629
638
|
this.assertIssuerData();
|
|
630
639
|
return this._state.credentialIssuer;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { JWK } from '@sphereon/oid4vc-common';
|
|
1
|
+
import { CreateDPoPClientOpts, JWK } from '@sphereon/oid4vc-common';
|
|
2
2
|
import {
|
|
3
|
+
AccessTokenRequestOpts,
|
|
3
4
|
AccessTokenResponse,
|
|
4
5
|
Alg,
|
|
5
6
|
AuthorizationRequestOpts,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
CredentialResponse,
|
|
15
16
|
CredentialsSupportedLegacy,
|
|
16
17
|
DefaultURISchemes,
|
|
18
|
+
DPoPResponseParams,
|
|
17
19
|
EndpointMetadataResultV1_0_11,
|
|
18
20
|
getClientIdFromCredentialOfferPayload,
|
|
19
21
|
getIssuerFromCredentialOfferPayload,
|
|
@@ -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
|
|
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(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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;
|