@sphereon/oid4vci-client 0.16.1-next.4 → 0.16.1-next.402
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +10 -9
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.js +9 -8
- package/dist/AccessTokenClientV1_0_11.js.map +1 -1
- package/dist/AuthorizationCodeClient.d.ts +11 -1
- package/dist/AuthorizationCodeClient.d.ts.map +1 -1
- package/dist/AuthorizationCodeClient.js +66 -6
- package/dist/AuthorizationCodeClient.js.map +1 -1
- package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -1
- package/dist/CredentialOfferClient.d.ts.map +1 -1
- package/dist/CredentialOfferClient.js +14 -15
- package/dist/CredentialOfferClient.js.map +1 -1
- package/dist/CredentialOfferClientV1_0_11.js +1 -1
- package/dist/CredentialOfferClientV1_0_11.js.map +1 -1
- package/dist/CredentialOfferClientV1_0_13.d.ts.map +1 -1
- package/dist/CredentialOfferClientV1_0_13.js +18 -17
- package/dist/CredentialOfferClientV1_0_13.js.map +1 -1
- package/dist/CredentialRequestClient.d.ts +37 -13
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js +57 -14
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientBuilder.d.ts +1 -0
- package/dist/CredentialRequestClientBuilder.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilder.js +4 -0
- package/dist/CredentialRequestClientBuilder.js.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_11.d.ts +2 -0
- package/dist/CredentialRequestClientBuilderV1_0_11.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_11.js +4 -0
- package/dist/CredentialRequestClientBuilderV1_0_11.js.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_13.d.ts +2 -0
- package/dist/CredentialRequestClientBuilderV1_0_13.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_13.js +6 -1
- package/dist/CredentialRequestClientBuilderV1_0_13.js.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.d.ts +4 -4
- package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.js +10 -0
- 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 +13 -5
- package/dist/MetadataClient.js.map +1 -1
- package/dist/MetadataClientV1_0_11.d.ts.map +1 -1
- package/dist/MetadataClientV1_0_11.js +8 -1
- package/dist/MetadataClientV1_0_11.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 +13 -5
- package/dist/MetadataClientV1_0_13.js.map +1 -1
- package/dist/OpenID4VCIClient.d.ts +15 -7
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +64 -22
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.d.ts +9 -5
- package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.js +42 -17
- package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.d.ts +29 -7
- package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.js +117 -47
- package/dist/OpenID4VCIClientV1_0_13.js.map +1 -1
- package/dist/ProofOfPossessionBuilder.d.ts +11 -11
- package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
- package/dist/ProofOfPossessionBuilder.js.map +1 -1
- package/dist/functions/AccessTokenUtil.js +2 -2
- package/dist/functions/AccessTokenUtil.js.map +1 -1
- package/dist/functions/CredentialOfferCommons.d.ts +19 -0
- package/dist/functions/CredentialOfferCommons.d.ts.map +1 -0
- package/dist/functions/CredentialOfferCommons.js +50 -0
- package/dist/functions/CredentialOfferCommons.js.map +1 -0
- package/dist/functions/index.d.ts +1 -0
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +1 -0
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/notifications.d.ts +2 -2
- package/dist/functions/notifications.d.ts.map +1 -1
- package/dist/functions/notifications.js.map +1 -1
- package/lib/AccessTokenClient.ts +13 -12
- package/lib/AccessTokenClientV1_0_11.ts +11 -11
- package/lib/AuthorizationCodeClient.ts +92 -4
- package/lib/AuthorizationCodeClientV1_0_11.ts +2 -2
- package/lib/CredentialOfferClient.ts +12 -21
- package/lib/CredentialOfferClientV1_0_11.ts +1 -1
- package/lib/CredentialOfferClientV1_0_13.ts +17 -23
- package/lib/CredentialRequestClient.ts +98 -21
- package/lib/CredentialRequestClientBuilder.ts +4 -0
- package/lib/CredentialRequestClientBuilderV1_0_11.ts +6 -0
- package/lib/CredentialRequestClientBuilderV1_0_13.ts +10 -1
- package/lib/CredentialRequestClientV1_0_11.ts +14 -4
- package/lib/MetadataClient.ts +13 -2
- package/lib/MetadataClientV1_0_11.ts +10 -1
- package/lib/MetadataClientV1_0_13.ts +12 -2
- package/lib/OpenID4VCIClient.ts +80 -13
- package/lib/OpenID4VCIClientV1_0_11.ts +57 -12
- package/lib/OpenID4VCIClientV1_0_13.ts +160 -46
- package/lib/ProofOfPossessionBuilder.ts +13 -13
- package/lib/__tests__/AccessTokenClient.spec.ts +0 -2
- package/lib/__tests__/CredentialRequestClient.spec.ts +53 -0
- package/lib/__tests__/CredentialRequestClientBuilder.spec.ts +1 -1
- package/lib/__tests__/IT.spec.ts +1 -4
- package/lib/__tests__/MetadataClient.spec.ts +24 -2
- package/lib/__tests__/OpenID4VCIClient.spec.ts +44 -1
- package/lib/__tests__/OpenID4VCIClientV1_0_11.spec.ts +43 -0
- package/lib/__tests__/OpenID4VCIClientV1_0_13.spec.ts +43 -0
- package/lib/__tests__/SdJwt.spec.ts +16 -3
- package/lib/__tests__/SphereonE2E.spec.test.ts +1 -1
- package/lib/functions/AccessTokenUtil.ts +2 -2
- package/lib/functions/CredentialOfferCommons.ts +52 -0
- package/lib/functions/index.ts +1 -0
- package/lib/functions/notifications.ts +2 -2
- package/package.json +5 -6
|
@@ -2,8 +2,10 @@ 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,
|
|
8
|
+
ExperimentalSubjectIssuance,
|
|
7
9
|
getCredentialRequestForVersion,
|
|
8
10
|
getUniformFormat,
|
|
9
11
|
isDeferredCredentialResponse,
|
|
@@ -16,7 +18,6 @@ import {
|
|
|
16
18
|
UniformCredentialRequest,
|
|
17
19
|
URL_NOT_VALID,
|
|
18
20
|
} from '@sphereon/oid4vci-common';
|
|
19
|
-
import { ExperimentalSubjectIssuance } from '@sphereon/oid4vci-common/dist/experimental/holder-vci';
|
|
20
21
|
import { CredentialFormat } from '@sphereon/ssi-types';
|
|
21
22
|
import Debug from 'debug';
|
|
22
23
|
|
|
@@ -40,10 +41,20 @@ export interface CredentialRequestOpts {
|
|
|
40
41
|
token: string;
|
|
41
42
|
version: OpenId4VCIVersion;
|
|
42
43
|
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
44
|
+
issuerState?: string;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
export
|
|
46
|
-
|
|
47
|
+
export type CreateCredentialRequestOpts = {
|
|
48
|
+
credentialIdentifier?: string;
|
|
49
|
+
credentialTypes?: string | string[];
|
|
50
|
+
context?: string[];
|
|
51
|
+
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
52
|
+
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
53
|
+
version: OpenId4VCIVersion;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export async function buildProof(
|
|
57
|
+
proofInput: ProofOfPossessionBuilder | ProofOfPossession,
|
|
47
58
|
opts: {
|
|
48
59
|
version: OpenId4VCIVersion;
|
|
49
60
|
cNonce?: string;
|
|
@@ -85,8 +96,35 @@ export class CredentialRequestClient {
|
|
|
85
96
|
this._credentialRequestOpts = { ...builder };
|
|
86
97
|
}
|
|
87
98
|
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Typically you should not use this method, as it omits a proof from the request.
|
|
101
|
+
* There are certain issuers that in specific circumstances can do without this proof, because they have other means of user binding
|
|
102
|
+
* like using DPoP together with an authorization code flow. These are however rare, so you should be using the acquireCredentialsUsingProof normally
|
|
103
|
+
* @param opts
|
|
104
|
+
*/
|
|
105
|
+
public async acquireCredentialsWithoutProof(opts: {
|
|
106
|
+
credentialIdentifier?: string;
|
|
107
|
+
credentialTypes?: string | string[];
|
|
108
|
+
context?: string[];
|
|
109
|
+
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
110
|
+
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
111
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
112
|
+
}): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
113
|
+
const { credentialIdentifier, credentialTypes, format, context, subjectIssuance } = opts;
|
|
114
|
+
|
|
115
|
+
const request = await this.createCredentialRequestWithoutProof({
|
|
116
|
+
credentialTypes,
|
|
117
|
+
context,
|
|
118
|
+
format,
|
|
119
|
+
version: this.version(),
|
|
120
|
+
credentialIdentifier,
|
|
121
|
+
subjectIssuance,
|
|
122
|
+
});
|
|
123
|
+
return await this.acquireCredentialsUsingRequestWithoutProof(request, opts.createDPoPOpts);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public async acquireCredentialsUsingProof(opts: {
|
|
127
|
+
proofInput: ProofOfPossessionBuilder | ProofOfPossession;
|
|
90
128
|
credentialIdentifier?: string;
|
|
91
129
|
credentialTypes?: string | string[];
|
|
92
130
|
context?: string[];
|
|
@@ -108,9 +146,23 @@ export class CredentialRequestClient {
|
|
|
108
146
|
return await this.acquireCredentialsUsingRequest(request, opts.createDPoPOpts);
|
|
109
147
|
}
|
|
110
148
|
|
|
149
|
+
public async acquireCredentialsUsingRequestWithoutProof(
|
|
150
|
+
uniformRequest: UniformCredentialRequest,
|
|
151
|
+
createDPoPOpts?: CreateDPoPClientOpts,
|
|
152
|
+
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
153
|
+
return await this.acquireCredentialsUsingRequestImpl(uniformRequest, createDPoPOpts);
|
|
154
|
+
}
|
|
155
|
+
|
|
111
156
|
public async acquireCredentialsUsingRequest(
|
|
112
157
|
uniformRequest: UniformCredentialRequest,
|
|
113
158
|
createDPoPOpts?: CreateDPoPClientOpts,
|
|
159
|
+
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
160
|
+
return await this.acquireCredentialsUsingRequestImpl(uniformRequest, createDPoPOpts);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private async acquireCredentialsUsingRequestImpl(
|
|
164
|
+
uniformRequest: UniformCredentialRequest & { proof?: ProofOfPossession },
|
|
165
|
+
createDPoPOpts?: CreateDPoPClientOpts,
|
|
114
166
|
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
115
167
|
if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
|
|
116
168
|
throw new Error('Versions below v1.0.13 (draft 13) are not supported by the V13 credential request client.');
|
|
@@ -194,24 +246,35 @@ export class CredentialRequestClient {
|
|
|
194
246
|
});
|
|
195
247
|
}
|
|
196
248
|
|
|
197
|
-
public async
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
249
|
+
public async createCredentialRequestWithoutProof(opts: CreateCredentialRequestOpts): Promise<CredentialRequestWithoutProofV1_0_13> {
|
|
250
|
+
return await this.createCredentialRequestImpl(opts);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
public async createCredentialRequest(
|
|
254
|
+
opts: CreateCredentialRequestOpts & {
|
|
255
|
+
proofInput: ProofOfPossessionBuilder | ProofOfPossession;
|
|
256
|
+
},
|
|
257
|
+
): Promise<CredentialRequestV1_0_13> {
|
|
258
|
+
return await this.createCredentialRequestImpl(opts);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private async createCredentialRequestImpl(
|
|
262
|
+
opts: CreateCredentialRequestOpts & {
|
|
263
|
+
proofInput?: ProofOfPossessionBuilder | ProofOfPossession;
|
|
264
|
+
},
|
|
265
|
+
): Promise<CredentialRequestV1_0_13> {
|
|
206
266
|
const { proofInput, credentialIdentifier: credential_identifier } = opts;
|
|
207
|
-
|
|
267
|
+
let proof: ProofOfPossession | undefined = undefined;
|
|
268
|
+
if (proofInput) {
|
|
269
|
+
proof = await buildProof(proofInput, opts);
|
|
270
|
+
}
|
|
208
271
|
if (credential_identifier) {
|
|
209
272
|
if (opts.format || opts.credentialTypes || opts.context) {
|
|
210
273
|
throw Error(`You cannot mix credential_identifier with format, credential types and/or context`);
|
|
211
274
|
}
|
|
212
275
|
return {
|
|
213
276
|
credential_identifier,
|
|
214
|
-
proof,
|
|
277
|
+
...(proof && { proof }),
|
|
215
278
|
};
|
|
216
279
|
}
|
|
217
280
|
const formatSelection = opts.format ?? this.credentialRequestOpts.format;
|
|
@@ -231,6 +294,7 @@ export class CredentialRequestClient {
|
|
|
231
294
|
if (types.length === 0) {
|
|
232
295
|
throw Error(`Credential type(s) need to be provided`);
|
|
233
296
|
}
|
|
297
|
+
const issuer_state = this.credentialRequestOpts.issuerState;
|
|
234
298
|
|
|
235
299
|
// TODO: we should move format specific logic
|
|
236
300
|
if (format === 'jwt_vc_json' || format === 'jwt_vc') {
|
|
@@ -239,7 +303,8 @@ export class CredentialRequestClient {
|
|
|
239
303
|
type: types,
|
|
240
304
|
},
|
|
241
305
|
format,
|
|
242
|
-
|
|
306
|
+
...(issuer_state && { issuer_state }),
|
|
307
|
+
...(proof && { proof }),
|
|
243
308
|
...opts.subjectIssuance,
|
|
244
309
|
};
|
|
245
310
|
} else if (format === 'jwt_vc_json-ld' || format === 'ldp_vc') {
|
|
@@ -249,7 +314,8 @@ export class CredentialRequestClient {
|
|
|
249
314
|
|
|
250
315
|
return {
|
|
251
316
|
format,
|
|
252
|
-
|
|
317
|
+
...(issuer_state && { issuer_state }),
|
|
318
|
+
...(proof && { proof }),
|
|
253
319
|
...opts.subjectIssuance,
|
|
254
320
|
|
|
255
321
|
credential_definition: {
|
|
@@ -261,16 +327,27 @@ export class CredentialRequestClient {
|
|
|
261
327
|
if (types.length > 1) {
|
|
262
328
|
throw Error(`Only a single credential type is supported for ${format}`);
|
|
263
329
|
}
|
|
264
|
-
// fixme: this isn't up to the CredentialRequest that we see in the version v1_0_13
|
|
265
330
|
return {
|
|
266
331
|
format,
|
|
267
|
-
|
|
332
|
+
...(issuer_state && { issuer_state }),
|
|
333
|
+
...(proof && { proof }),
|
|
268
334
|
vct: types[0],
|
|
269
335
|
...opts.subjectIssuance,
|
|
270
336
|
};
|
|
337
|
+
} else if (format === 'mso_mdoc') {
|
|
338
|
+
if (types.length > 1) {
|
|
339
|
+
throw Error(`Only a single credential type is supported for ${format}`);
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
format,
|
|
343
|
+
...(issuer_state && { issuer_state }),
|
|
344
|
+
...(proof && { proof }),
|
|
345
|
+
doctype: types[0],
|
|
346
|
+
...opts.subjectIssuance,
|
|
347
|
+
};
|
|
271
348
|
}
|
|
272
349
|
|
|
273
|
-
throw new Error(`Unsupported format: ${format}`);
|
|
350
|
+
throw new Error(`Unsupported credential format: ${format}`);
|
|
274
351
|
}
|
|
275
352
|
|
|
276
353
|
private version(): OpenId4VCIVersion {
|
|
@@ -168,6 +168,10 @@ export class CredentialRequestClientBuilder {
|
|
|
168
168
|
return this;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
public withIssuerState(issuerState?: string): this {
|
|
172
|
+
this._builder.withIssuerState(issuerState);
|
|
173
|
+
return this;
|
|
174
|
+
}
|
|
171
175
|
public withCredentialType(credentialTypes: string | string[]): this {
|
|
172
176
|
this._builder.withCredentialType(credentialTypes);
|
|
173
177
|
return this;
|
|
@@ -28,6 +28,7 @@ export class CredentialRequestClientBuilderV1_0_11 {
|
|
|
28
28
|
token?: string;
|
|
29
29
|
version?: OpenId4VCIVersion;
|
|
30
30
|
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
31
|
+
issuerState?: string;
|
|
31
32
|
|
|
32
33
|
public static fromCredentialIssuer({
|
|
33
34
|
credentialIssuer,
|
|
@@ -98,6 +99,11 @@ export class CredentialRequestClientBuilderV1_0_11 {
|
|
|
98
99
|
});
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
public withIssuerState(issuerState?: string): this {
|
|
103
|
+
this.issuerState = issuerState;
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
|
|
101
107
|
public withCredentialEndpointFromMetadata(metadata: CredentialIssuerMetadata): this {
|
|
102
108
|
this.credentialEndpoint = metadata.credential_endpoint;
|
|
103
109
|
return this;
|
|
@@ -27,6 +27,7 @@ export class CredentialRequestClientBuilderV1_0_13 {
|
|
|
27
27
|
token?: string;
|
|
28
28
|
version?: OpenId4VCIVersion;
|
|
29
29
|
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
30
|
+
issuerState?: string;
|
|
30
31
|
|
|
31
32
|
public static fromCredentialIssuer({
|
|
32
33
|
credentialIssuer,
|
|
@@ -86,6 +87,7 @@ export class CredentialRequestClientBuilderV1_0_13 {
|
|
|
86
87
|
if (ids.length && ids.length === 1) {
|
|
87
88
|
builder.withCredentialIdentifier(ids[0]);
|
|
88
89
|
}
|
|
90
|
+
|
|
89
91
|
return builder;
|
|
90
92
|
}
|
|
91
93
|
|
|
@@ -96,11 +98,13 @@ export class CredentialRequestClientBuilderV1_0_13 {
|
|
|
96
98
|
credentialOffer: CredentialOfferRequestWithBaseUrl;
|
|
97
99
|
metadata?: EndpointMetadata;
|
|
98
100
|
}): CredentialRequestClientBuilderV1_0_13 {
|
|
99
|
-
|
|
101
|
+
const builder = CredentialRequestClientBuilderV1_0_13.fromCredentialOfferRequest({
|
|
100
102
|
request: credentialOffer,
|
|
101
103
|
metadata,
|
|
102
104
|
version: credentialOffer.version,
|
|
103
105
|
});
|
|
106
|
+
|
|
107
|
+
return builder;
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
public withCredentialEndpointFromMetadata(metadata: CredentialIssuerMetadataV1_0_13): this {
|
|
@@ -113,6 +117,11 @@ export class CredentialRequestClientBuilderV1_0_13 {
|
|
|
113
117
|
return this;
|
|
114
118
|
}
|
|
115
119
|
|
|
120
|
+
public withIssuerState(issuerState?: string): this {
|
|
121
|
+
this.issuerState = issuerState;
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
|
|
116
125
|
public withDeferredCredentialEndpointFromMetadata(metadata: CredentialIssuerMetadataV1_0_13): this {
|
|
117
126
|
this.deferredCredentialEndpoint = metadata.deferred_credential_endpoint;
|
|
118
127
|
return this;
|
|
@@ -62,8 +62,8 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
62
62
|
this._credentialRequestOpts = { ...builder };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
public async acquireCredentialsUsingProof
|
|
66
|
-
proofInput: ProofOfPossessionBuilder
|
|
65
|
+
public async acquireCredentialsUsingProof(opts: {
|
|
66
|
+
proofInput: ProofOfPossessionBuilder | ProofOfPossession;
|
|
67
67
|
credentialTypes?: string | string[];
|
|
68
68
|
context?: string[];
|
|
69
69
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
@@ -153,8 +153,8 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
public async createCredentialRequest
|
|
157
|
-
proofInput: ProofOfPossessionBuilder
|
|
156
|
+
public async createCredentialRequest(opts: {
|
|
157
|
+
proofInput: ProofOfPossessionBuilder | ProofOfPossession;
|
|
158
158
|
credentialTypes?: string | string[];
|
|
159
159
|
context?: string[];
|
|
160
160
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
@@ -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
|
|
|
@@ -70,6 +70,7 @@ export class MetadataClient {
|
|
|
70
70
|
let credential_endpoint: string | undefined;
|
|
71
71
|
let deferred_credential_endpoint: string | undefined;
|
|
72
72
|
let authorization_endpoint: string | undefined;
|
|
73
|
+
let authorization_challenge_endpoint: string | undefined;
|
|
73
74
|
let authorizationServerType: AuthorizationServerType = 'OID4VCI';
|
|
74
75
|
let authorization_servers: string[] | undefined = [issuer];
|
|
75
76
|
let authorization_server: string | undefined = undefined;
|
|
@@ -84,6 +85,7 @@ export class MetadataClient {
|
|
|
84
85
|
if (credentialIssuerMetadata.token_endpoint) {
|
|
85
86
|
token_endpoint = credentialIssuerMetadata.token_endpoint;
|
|
86
87
|
}
|
|
88
|
+
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
|
|
87
89
|
if (credentialIssuerMetadata.authorization_servers) {
|
|
88
90
|
authorization_servers = credentialIssuerMetadata.authorization_servers as string[];
|
|
89
91
|
} else if (credentialIssuerMetadata.authorization_server) {
|
|
@@ -130,8 +132,14 @@ export class MetadataClient {
|
|
|
130
132
|
);
|
|
131
133
|
}
|
|
132
134
|
authorization_endpoint = authMetadata.authorization_endpoint;
|
|
135
|
+
if (authorization_challenge_endpoint && authMetadata.authorization_challenge_endpoint !== authorization_challenge_endpoint) {
|
|
136
|
+
throw Error(
|
|
137
|
+
`Credential issuer has a different authorization_challenge_endpoint (${authorization_challenge_endpoint}) from the Authorization Server (${authMetadata.authorization_challenge_endpoint})`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
authorization_challenge_endpoint = authMetadata.authorization_challenge_endpoint;
|
|
133
141
|
if (!authMetadata.token_endpoint) {
|
|
134
|
-
throw Error(`Authorization
|
|
142
|
+
throw Error(`Authorization Server ${authorization_servers} did not provide a token_endpoint`);
|
|
135
143
|
} else if (token_endpoint && authMetadata.token_endpoint !== token_endpoint) {
|
|
136
144
|
throw Error(
|
|
137
145
|
`Credential issuer has a different token_endpoint (${token_endpoint}) from the Authorization Server (${authMetadata.token_endpoint})`,
|
|
@@ -185,6 +193,7 @@ export class MetadataClient {
|
|
|
185
193
|
: (authMetadata as CredentialIssuerMetadataV1_0_13);
|
|
186
194
|
}
|
|
187
195
|
debug(`Issuer ${issuer} token endpoint ${token_endpoint}, credential endpoint ${credential_endpoint}`);
|
|
196
|
+
|
|
188
197
|
return {
|
|
189
198
|
issuer,
|
|
190
199
|
token_endpoint,
|
|
@@ -192,6 +201,7 @@ export class MetadataClient {
|
|
|
192
201
|
deferred_credential_endpoint,
|
|
193
202
|
...(authorization_server ? { authorization_server } : { authorization_servers: authorization_servers }),
|
|
194
203
|
authorization_endpoint,
|
|
204
|
+
authorization_challenge_endpoint,
|
|
195
205
|
authorizationServerType,
|
|
196
206
|
credentialIssuerMetadata: authorization_server
|
|
197
207
|
? (credentialIssuerMetadata as IssuerMetadataV1_0_08 & Partial<AuthorizationServerMetadata>)
|
|
@@ -204,6 +214,7 @@ export class MetadataClient {
|
|
|
204
214
|
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
|
|
205
215
|
*
|
|
206
216
|
* @param issuerHost The issuer hostname
|
|
217
|
+
* @param opts
|
|
207
218
|
*/
|
|
208
219
|
public static async retrieveOpenID4VCIServerMetadata(
|
|
209
220
|
issuerHost: string,
|
|
@@ -50,6 +50,7 @@ export class MetadataClientV1_0_11 {
|
|
|
50
50
|
let credential_endpoint: string | undefined;
|
|
51
51
|
let deferred_credential_endpoint: string | undefined;
|
|
52
52
|
let authorization_endpoint: string | undefined;
|
|
53
|
+
let authorization_challenge_endpoint: string | undefined;
|
|
53
54
|
let authorizationServerType: AuthorizationServerType = 'OID4VCI';
|
|
54
55
|
let authorization_server: string = issuer;
|
|
55
56
|
const oid4vciResponse = await MetadataClientV1_0_11.retrieveOpenID4VCIServerMetadata(issuer, { errorOnNotFound: false }); // We will handle errors later, given we will also try other metadata locations
|
|
@@ -61,6 +62,7 @@ export class MetadataClientV1_0_11 {
|
|
|
61
62
|
if (credentialIssuerMetadata.token_endpoint) {
|
|
62
63
|
token_endpoint = credentialIssuerMetadata.token_endpoint;
|
|
63
64
|
}
|
|
65
|
+
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
|
|
64
66
|
if (credentialIssuerMetadata.authorization_server) {
|
|
65
67
|
authorization_server = credentialIssuerMetadata.authorization_server;
|
|
66
68
|
}
|
|
@@ -105,8 +107,14 @@ export class MetadataClientV1_0_11 {
|
|
|
105
107
|
);
|
|
106
108
|
}
|
|
107
109
|
authorization_endpoint = authMetadata.authorization_endpoint;
|
|
110
|
+
if (authorization_challenge_endpoint && authMetadata.authorization_challenge_endpoint !== authorization_challenge_endpoint) {
|
|
111
|
+
throw Error(
|
|
112
|
+
`Credential issuer has a different authorization_challenge_endpoint (${authorization_challenge_endpoint}) from the Authorization Server (${authMetadata.authorization_challenge_endpoint})`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
authorization_challenge_endpoint = authMetadata.authorization_challenge_endpoint;
|
|
108
116
|
if (!authMetadata.token_endpoint) {
|
|
109
|
-
throw Error(`Authorization
|
|
117
|
+
throw Error(`Authorization Server ${authorization_server} did not provide a token_endpoint`);
|
|
110
118
|
} else if (token_endpoint && authMetadata.token_endpoint !== token_endpoint) {
|
|
111
119
|
throw Error(
|
|
112
120
|
`Credential issuer has a different token_endpoint (${token_endpoint}) from the Authorization Server (${authMetadata.token_endpoint})`,
|
|
@@ -165,6 +173,7 @@ export class MetadataClientV1_0_11 {
|
|
|
165
173
|
deferred_credential_endpoint,
|
|
166
174
|
authorization_server,
|
|
167
175
|
authorization_endpoint,
|
|
176
|
+
authorization_challenge_endpoint,
|
|
168
177
|
authorizationServerType,
|
|
169
178
|
credentialIssuerMetadata: credentialIssuerMetadata as unknown as Partial<AuthorizationServerMetadata> & IssuerMetadataV1_0_08,
|
|
170
179
|
authorizationServerMetadata: authMetadata,
|
|
@@ -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
|
|
|
@@ -50,6 +50,7 @@ export class MetadataClientV1_0_13 {
|
|
|
50
50
|
let credential_endpoint: string | undefined;
|
|
51
51
|
let deferred_credential_endpoint: string | undefined;
|
|
52
52
|
let authorization_endpoint: string | undefined;
|
|
53
|
+
let authorization_challenge_endpoint: string | undefined;
|
|
53
54
|
let authorizationServerType: AuthorizationServerType = 'OID4VCI';
|
|
54
55
|
let authorization_servers: string[] = [issuer];
|
|
55
56
|
const oid4vciResponse = await MetadataClientV1_0_13.retrieveOpenID4VCIServerMetadata(issuer, { errorOnNotFound: false }); // We will handle errors later, given we will also try other metadata locations
|
|
@@ -61,6 +62,7 @@ export class MetadataClientV1_0_13 {
|
|
|
61
62
|
if (credentialIssuerMetadata.token_endpoint) {
|
|
62
63
|
token_endpoint = credentialIssuerMetadata.token_endpoint;
|
|
63
64
|
}
|
|
65
|
+
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
|
|
64
66
|
if (credentialIssuerMetadata.authorization_servers) {
|
|
65
67
|
authorization_servers = credentialIssuerMetadata.authorization_servers;
|
|
66
68
|
}
|
|
@@ -104,8 +106,14 @@ export class MetadataClientV1_0_13 {
|
|
|
104
106
|
);
|
|
105
107
|
}
|
|
106
108
|
authorization_endpoint = authMetadata.authorization_endpoint;
|
|
109
|
+
if (authorization_challenge_endpoint && authMetadata.authorization_challenge_endpoint !== authorization_challenge_endpoint) {
|
|
110
|
+
throw Error(
|
|
111
|
+
`Credential issuer has a different authorization_challenge_endpoint (${authorization_challenge_endpoint}) from the Authorization Server (${authMetadata.authorization_challenge_endpoint})`,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
authorization_challenge_endpoint = authMetadata.authorization_challenge_endpoint;
|
|
107
115
|
if (!authMetadata.token_endpoint) {
|
|
108
|
-
throw Error(`Authorization
|
|
116
|
+
throw Error(`Authorization Server ${authorization_servers} did not provide a token_endpoint`);
|
|
109
117
|
} else if (token_endpoint && authMetadata.token_endpoint !== token_endpoint) {
|
|
110
118
|
throw Error(
|
|
111
119
|
`Credential issuer has a different token_endpoint (${token_endpoint}) from the Authorization Server (${authMetadata.token_endpoint})`,
|
|
@@ -164,6 +172,7 @@ export class MetadataClientV1_0_13 {
|
|
|
164
172
|
deferred_credential_endpoint,
|
|
165
173
|
authorization_server: authorization_servers[0],
|
|
166
174
|
authorization_endpoint,
|
|
175
|
+
authorization_challenge_endpoint,
|
|
167
176
|
authorizationServerType,
|
|
168
177
|
credentialIssuerMetadata: credentialIssuerMetadata,
|
|
169
178
|
authorizationServerMetadata: authMetadata,
|
|
@@ -174,6 +183,7 @@ export class MetadataClientV1_0_13 {
|
|
|
174
183
|
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
|
|
175
184
|
*
|
|
176
185
|
* @param issuerHost The issuer hostname
|
|
186
|
+
* @param opts
|
|
177
187
|
*/
|
|
178
188
|
public static async retrieveOpenID4VCIServerMetadata(
|
|
179
189
|
issuerHost: string,
|