@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.
- package/dist/AccessTokenClient.d.ts +7 -5
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +25 -5
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.d.ts +7 -5
- package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
- package/dist/AccessTokenClientV1_0_11.js +25 -5
- 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 +1 -1
- package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -1
- package/dist/CredentialRequestClient.d.ts +6 -4
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js +23 -5
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.d.ts +5 -3
- package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -1
- package/dist/CredentialRequestClientV1_0_11.js +32 -4
- 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 -9
- 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 -17
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.d.ts +10 -9
- 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 +10 -9
- package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.js +11 -6
- package/dist/OpenID4VCIClientV1_0_13.js.map +1 -1
- package/dist/ProofOfPossessionBuilder.d.ts +2 -1
- package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
- package/dist/ProofOfPossessionBuilder.js.map +1 -1
- package/dist/functions/AccessTokenUtil.d.ts.map +1 -1
- package/dist/functions/AccessTokenUtil.js +2 -2
- package/dist/functions/AccessTokenUtil.js.map +1 -1
- package/dist/functions/dpopUtil.d.ts +10 -0
- package/dist/functions/dpopUtil.d.ts.map +1 -0
- package/dist/functions/dpopUtil.js +30 -0
- package/dist/functions/dpopUtil.js.map +1 -0
- package/dist/functions/notifications.d.ts.map +1 -1
- package/dist/functions/notifications.js +3 -3
- package/dist/functions/notifications.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/lib/AccessTokenClient.ts +44 -7
- package/lib/AccessTokenClientV1_0_11.ts +44 -7
- package/lib/AuthorizationCodeClient.ts +4 -3
- package/lib/AuthorizationCodeClientV1_0_11.ts +3 -3
- package/lib/CredentialRequestClient.ts +49 -7
- package/lib/CredentialRequestClientV1_0_11.ts +48 -5
- package/lib/MetadataClient.ts +2 -1
- package/lib/MetadataClientV1_0_13.ts +2 -7
- package/lib/OpenID4VCIClient.ts +26 -28
- package/lib/OpenID4VCIClientV1_0_11.ts +25 -14
- package/lib/OpenID4VCIClientV1_0_13.ts +23 -13
- package/lib/ProofOfPossessionBuilder.ts +1 -1
- package/lib/__tests__/AccessTokenClient.spec.ts +4 -11
- package/lib/__tests__/SphereonE2E.spec.test.ts +3 -3
- package/lib/functions/AccessTokenUtil.ts +2 -2
- package/lib/functions/dpopUtil.ts +35 -0
- package/lib/functions/notifications.ts +2 -4
- package/lib/index.ts +0 -1
- package/package.json +5 -4
- package/dist/IssuerSessionClient.d.ts +0 -3
- package/dist/IssuerSessionClient.d.ts.map +0 -1
- package/dist/IssuerSessionClient.js +0 -28
- package/dist/IssuerSessionClient.js.map +0 -1
- package/lib/IssuerSessionClient.ts +0 -17
- package/lib/__tests__/IssuerSessionClient.spec.ts +0 -64
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,eAAO,MAAM,GAAG,EAAE,aAAa,CAAC,MAAM,CAA8C,CAAC;AAErF,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,eAAO,MAAM,GAAG,EAAE,aAAa,CAAC,MAAM,CAA8C,CAAC;AAErF,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,5 @@ __exportStar(require("./MetadataClientV1_0_11"), exports);
|
|
|
36
36
|
__exportStar(require("./OpenID4VCIClient"), exports);
|
|
37
37
|
__exportStar(require("./OpenID4VCIClientV1_0_13"), exports);
|
|
38
38
|
__exportStar(require("./OpenID4VCIClientV1_0_11"), exports);
|
|
39
|
-
__exportStar(require("./IssuerSessionClient"), exports);
|
|
40
39
|
__exportStar(require("./ProofOfPossessionBuilder"), exports);
|
|
41
40
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAAuD;AAG1C,QAAA,GAAG,GAA0B,4BAAW,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;AAErF,sDAAoC;AACpC,6DAA2C;AAC3C,4DAA0C;AAC1C,mEAAiD;AACjD,4DAA0C;AAC1C,0DAAwC;AACxC,iEAA+C;AAC/C,iEAA+C;AAC/C,mEAAiD;AACjD,mEAAiD;AACjD,0EAAwD;AACxD,0EAAwD;AACxD,8CAA4B;AAC5B,mDAAiC;AACjC,0DAAwC;AACxC,0DAAwC;AACxC,qDAAmC;AACnC,4DAA0C;AAC1C,4DAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAAuD;AAG1C,QAAA,GAAG,GAA0B,4BAAW,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;AAErF,sDAAoC;AACpC,6DAA2C;AAC3C,4DAA0C;AAC1C,mEAAiD;AACjD,4DAA0C;AAC1C,0DAAwC;AACxC,iEAA+C;AAC/C,iEAA+C;AAC/C,mEAAiD;AACjD,mEAAiD;AACjD,0EAAwD;AACxD,0EAAwD;AACxD,8CAA4B;AAC5B,mDAAiC;AACjC,0DAAwC;AACxC,0DAAwC;AACxC,qDAAmC;AACnC,4DAA0C;AAC1C,4DAA0C;AAC1C,6DAA2C"}
|
package/lib/AccessTokenClient.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createDPoP, CreateDPoPClientOpts, getCreateDPoPOptions } from '@sphereon/oid4vc-common';
|
|
1
2
|
import {
|
|
2
3
|
AccessTokenRequest,
|
|
3
4
|
AccessTokenRequestOpts,
|
|
@@ -6,6 +7,7 @@ import {
|
|
|
6
7
|
AuthorizationServerOpts,
|
|
7
8
|
AuthzFlowType,
|
|
8
9
|
convertJsonToURI,
|
|
10
|
+
DPoPResponseParams,
|
|
9
11
|
EndpointMetadata,
|
|
10
12
|
formPost,
|
|
11
13
|
getIssuerFromCredentialOfferPayload,
|
|
@@ -24,11 +26,12 @@ import { ObjectUtils } from '@sphereon/ssi-types';
|
|
|
24
26
|
|
|
25
27
|
import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13';
|
|
26
28
|
import { createJwtBearerClientAssertion } from './functions';
|
|
29
|
+
import { shouldRetryTokenRequestWithDPoPNonce } from './functions/dpopUtil';
|
|
27
30
|
import { LOG } from './types';
|
|
28
31
|
|
|
29
32
|
export class AccessTokenClient {
|
|
30
|
-
public async acquireAccessToken(opts: AccessTokenRequestOpts): Promise<OpenIDResponse<AccessTokenResponse>> {
|
|
31
|
-
const { asOpts, pin, codeVerifier, code, redirectUri, metadata } = opts;
|
|
33
|
+
public async acquireAccessToken(opts: AccessTokenRequestOpts): Promise<OpenIDResponse<AccessTokenResponse, DPoPResponseParams>> {
|
|
34
|
+
const { asOpts, pin, codeVerifier, code, redirectUri, metadata, createDPoPOpts } = opts;
|
|
32
35
|
|
|
33
36
|
const credentialOffer = opts.credentialOffer ? await assertedUniformCredentialOffer(opts.credentialOffer) : undefined;
|
|
34
37
|
const pinMetadata: TxCodeAndPinRequired | undefined = credentialOffer && this.getPinMetadata(credentialOffer.credential_offer);
|
|
@@ -59,6 +62,7 @@ export class AccessTokenClient {
|
|
|
59
62
|
metadata,
|
|
60
63
|
asOpts,
|
|
61
64
|
issuerOpts,
|
|
65
|
+
createDPoPOpts: createDPoPOpts,
|
|
62
66
|
});
|
|
63
67
|
}
|
|
64
68
|
|
|
@@ -68,13 +72,15 @@ export class AccessTokenClient {
|
|
|
68
72
|
metadata,
|
|
69
73
|
asOpts,
|
|
70
74
|
issuerOpts,
|
|
75
|
+
createDPoPOpts,
|
|
71
76
|
}: {
|
|
72
77
|
accessTokenRequest: AccessTokenRequest;
|
|
73
78
|
pinMetadata?: TxCodeAndPinRequired;
|
|
74
79
|
metadata?: EndpointMetadata;
|
|
75
80
|
asOpts?: AuthorizationServerOpts;
|
|
76
81
|
issuerOpts?: IssuerOpts;
|
|
77
|
-
|
|
82
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
83
|
+
}): Promise<OpenIDResponse<AccessTokenResponse, DPoPResponseParams>> {
|
|
78
84
|
this.validate(accessTokenRequest, pinMetadata);
|
|
79
85
|
|
|
80
86
|
const requestTokenURL = AccessTokenClient.determineTokenURL({
|
|
@@ -87,10 +93,34 @@ export class AccessTokenClient {
|
|
|
87
93
|
: undefined,
|
|
88
94
|
});
|
|
89
95
|
|
|
90
|
-
|
|
96
|
+
const useDpop = createDPoPOpts?.dPoPSigningAlgValuesSupported && createDPoPOpts.dPoPSigningAlgValuesSupported.length > 0;
|
|
97
|
+
let dPoP = useDpop ? await createDPoP(getCreateDPoPOptions(createDPoPOpts, requestTokenURL)) : undefined;
|
|
98
|
+
|
|
99
|
+
let response = await this.sendAuthCode(requestTokenURL, accessTokenRequest, dPoP ? { headers: { dpop: dPoP } } : undefined);
|
|
100
|
+
|
|
101
|
+
let nextDPoPNonce = createDPoPOpts?.jwtPayloadProps.nonce;
|
|
102
|
+
const retryWithNonce = shouldRetryTokenRequestWithDPoPNonce(response);
|
|
103
|
+
if (retryWithNonce.ok && createDPoPOpts) {
|
|
104
|
+
createDPoPOpts.jwtPayloadProps.nonce = retryWithNonce.dpopNonce;
|
|
105
|
+
|
|
106
|
+
dPoP = await createDPoP(getCreateDPoPOptions(createDPoPOpts, requestTokenURL));
|
|
107
|
+
response = await this.sendAuthCode(requestTokenURL, accessTokenRequest, dPoP ? { headers: { dpop: dPoP } } : undefined);
|
|
108
|
+
const successDPoPNonce = response.origResponse.headers.get('DPoP-Nonce');
|
|
109
|
+
|
|
110
|
+
nextDPoPNonce = successDPoPNonce ?? retryWithNonce.dpopNonce;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (response.successBody && createDPoPOpts && response.successBody.token_type !== 'DPoP') {
|
|
114
|
+
throw new Error('Invalid token type returned. Expected DPoP. Received: ' + response.successBody.token_type);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
...response,
|
|
119
|
+
...(nextDPoPNonce && { params: { dpop: { dpopNonce: nextDPoPNonce } } }),
|
|
120
|
+
};
|
|
91
121
|
}
|
|
92
122
|
|
|
93
|
-
public async createAccessTokenRequest(opts: AccessTokenRequestOpts): Promise<AccessTokenRequest> {
|
|
123
|
+
public async createAccessTokenRequest(opts: Omit<AccessTokenRequestOpts, 'createDPoPOpts'>): Promise<AccessTokenRequest> {
|
|
94
124
|
const { asOpts, pin, codeVerifier, code, redirectUri } = opts;
|
|
95
125
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
96
126
|
// @ts-ignore
|
|
@@ -208,6 +238,7 @@ export class AccessTokenClient {
|
|
|
208
238
|
throw new Error('Authorization flow requires the code to be present');
|
|
209
239
|
}
|
|
210
240
|
}
|
|
241
|
+
|
|
211
242
|
private validate(accessTokenRequest: AccessTokenRequest, pinMeta?: TxCodeAndPinRequired): void {
|
|
212
243
|
if (accessTokenRequest.grant_type === GrantTypes.PRE_AUTHORIZED_CODE) {
|
|
213
244
|
this.assertPreAuthorizedGrantType(accessTokenRequest.grant_type);
|
|
@@ -222,8 +253,14 @@ export class AccessTokenClient {
|
|
|
222
253
|
}
|
|
223
254
|
}
|
|
224
255
|
|
|
225
|
-
private async sendAuthCode(
|
|
226
|
-
|
|
256
|
+
private async sendAuthCode(
|
|
257
|
+
requestTokenURL: string,
|
|
258
|
+
accessTokenRequest: AccessTokenRequest,
|
|
259
|
+
opts?: { headers?: Record<string, string> },
|
|
260
|
+
): Promise<OpenIDResponse<AccessTokenResponse, DPoPResponseParams>> {
|
|
261
|
+
return await formPost(requestTokenURL, convertJsonToURI(accessTokenRequest, { mode: JsonURIMode.X_FORM_WWW_URLENCODED }), {
|
|
262
|
+
customHeaders: opts?.headers ? opts.headers : undefined,
|
|
263
|
+
});
|
|
227
264
|
}
|
|
228
265
|
|
|
229
266
|
public static determineTokenURL({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createDPoP, CreateDPoPClientOpts, getCreateDPoPOptions } from '@sphereon/oid4vc-common';
|
|
1
2
|
import {
|
|
2
3
|
AccessTokenRequest,
|
|
3
4
|
AccessTokenRequestOpts,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
convertJsonToURI,
|
|
9
10
|
CredentialOfferV1_0_11,
|
|
10
11
|
CredentialOfferV1_0_13,
|
|
12
|
+
DPoPResponseParams,
|
|
11
13
|
EndpointMetadata,
|
|
12
14
|
formPost,
|
|
13
15
|
getIssuerFromCredentialOfferPayload,
|
|
@@ -27,12 +29,13 @@ import Debug from 'debug';
|
|
|
27
29
|
|
|
28
30
|
import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13';
|
|
29
31
|
import { createJwtBearerClientAssertion } from './functions';
|
|
32
|
+
import { shouldRetryTokenRequestWithDPoPNonce } from './functions/dpopUtil';
|
|
30
33
|
|
|
31
34
|
const debug = Debug('sphereon:oid4vci:token');
|
|
32
35
|
|
|
33
36
|
export class AccessTokenClientV1_0_11 {
|
|
34
|
-
public async acquireAccessToken(opts: AccessTokenRequestOpts): Promise<OpenIDResponse<AccessTokenResponse>> {
|
|
35
|
-
const { asOpts, pin, codeVerifier, code, redirectUri, metadata } = opts;
|
|
37
|
+
public async acquireAccessToken(opts: AccessTokenRequestOpts): Promise<OpenIDResponse<AccessTokenResponse, DPoPResponseParams>> {
|
|
38
|
+
const { asOpts, pin, codeVerifier, code, redirectUri, metadata, createDPoPOpts } = opts;
|
|
36
39
|
|
|
37
40
|
const credentialOffer = opts.credentialOffer ? await assertedUniformCredentialOffer(opts.credentialOffer) : undefined;
|
|
38
41
|
const isPinRequired = credentialOffer && this.isPinRequiredValue(credentialOffer.credential_offer);
|
|
@@ -63,6 +66,7 @@ export class AccessTokenClientV1_0_11 {
|
|
|
63
66
|
metadata,
|
|
64
67
|
asOpts,
|
|
65
68
|
issuerOpts,
|
|
69
|
+
createDPoPOpts,
|
|
66
70
|
});
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -71,6 +75,7 @@ export class AccessTokenClientV1_0_11 {
|
|
|
71
75
|
isPinRequired,
|
|
72
76
|
metadata,
|
|
73
77
|
asOpts,
|
|
78
|
+
createDPoPOpts,
|
|
74
79
|
issuerOpts,
|
|
75
80
|
}: {
|
|
76
81
|
accessTokenRequest: AccessTokenRequest;
|
|
@@ -78,7 +83,8 @@ export class AccessTokenClientV1_0_11 {
|
|
|
78
83
|
metadata?: EndpointMetadata;
|
|
79
84
|
asOpts?: AuthorizationServerOpts;
|
|
80
85
|
issuerOpts?: IssuerOpts;
|
|
81
|
-
|
|
86
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
87
|
+
}): Promise<OpenIDResponse<AccessTokenResponse, DPoPResponseParams>> {
|
|
82
88
|
this.validate(accessTokenRequest, isPinRequired);
|
|
83
89
|
|
|
84
90
|
const requestTokenURL = AccessTokenClientV1_0_11.determineTokenURL({
|
|
@@ -91,10 +97,34 @@ export class AccessTokenClientV1_0_11 {
|
|
|
91
97
|
: undefined,
|
|
92
98
|
});
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
const useDpop = createDPoPOpts?.dPoPSigningAlgValuesSupported && createDPoPOpts.dPoPSigningAlgValuesSupported.length > 0;
|
|
101
|
+
let dPoP = useDpop ? await createDPoP(getCreateDPoPOptions(createDPoPOpts, requestTokenURL)) : undefined;
|
|
102
|
+
|
|
103
|
+
let response = await this.sendAuthCode(requestTokenURL, accessTokenRequest, dPoP ? { headers: { dpop: dPoP } } : undefined);
|
|
104
|
+
|
|
105
|
+
let nextDPoPNonce = createDPoPOpts?.jwtPayloadProps.nonce;
|
|
106
|
+
const retryWithNonce = shouldRetryTokenRequestWithDPoPNonce(response);
|
|
107
|
+
if (retryWithNonce.ok && createDPoPOpts) {
|
|
108
|
+
createDPoPOpts.jwtPayloadProps.nonce = retryWithNonce.dpopNonce;
|
|
109
|
+
|
|
110
|
+
dPoP = await createDPoP(getCreateDPoPOptions(createDPoPOpts, requestTokenURL));
|
|
111
|
+
response = await this.sendAuthCode(requestTokenURL, accessTokenRequest, dPoP ? { headers: { dpop: dPoP } } : undefined);
|
|
112
|
+
const successDPoPNonce = response.origResponse.headers.get('DPoP-Nonce');
|
|
113
|
+
|
|
114
|
+
nextDPoPNonce = successDPoPNonce ?? retryWithNonce.dpopNonce;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (response.successBody && createDPoPOpts && response.successBody.token_type !== 'DPoP') {
|
|
118
|
+
throw new Error('Invalid token type returned. Expected DPoP. Received: ' + response.successBody.token_type);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
...response,
|
|
123
|
+
...(nextDPoPNonce && { params: { dpop: { dpopNonce: nextDPoPNonce } } }),
|
|
124
|
+
};
|
|
95
125
|
}
|
|
96
126
|
|
|
97
|
-
public async createAccessTokenRequest(opts: AccessTokenRequestOpts): Promise<AccessTokenRequest> {
|
|
127
|
+
public async createAccessTokenRequest(opts: Omit<AccessTokenRequestOpts, 'createDPoPOpts'>): Promise<AccessTokenRequest> {
|
|
98
128
|
const { asOpts, pin, codeVerifier, code, redirectUri } = opts;
|
|
99
129
|
const credentialOfferRequest = opts.credentialOffer
|
|
100
130
|
? await toUniformCredentialOfferRequest(opts.credentialOffer as CredentialOfferV1_0_11 | CredentialOfferV1_0_13)
|
|
@@ -190,6 +220,7 @@ export class AccessTokenClientV1_0_11 {
|
|
|
190
220
|
throw new Error('Authorization flow requires the code to be present');
|
|
191
221
|
}
|
|
192
222
|
}
|
|
223
|
+
|
|
193
224
|
private validate(accessTokenRequest: AccessTokenRequest, isPinRequired?: boolean): void {
|
|
194
225
|
if (accessTokenRequest.grant_type === GrantTypes.PRE_AUTHORIZED_CODE) {
|
|
195
226
|
this.assertPreAuthorizedGrantType(accessTokenRequest.grant_type);
|
|
@@ -204,8 +235,14 @@ export class AccessTokenClientV1_0_11 {
|
|
|
204
235
|
}
|
|
205
236
|
}
|
|
206
237
|
|
|
207
|
-
private async sendAuthCode(
|
|
208
|
-
|
|
238
|
+
private async sendAuthCode(
|
|
239
|
+
requestTokenURL: string,
|
|
240
|
+
accessTokenRequest: AccessTokenRequest,
|
|
241
|
+
opts?: { headers?: Record<string, string> },
|
|
242
|
+
): Promise<OpenIDResponse<AccessTokenResponse>> {
|
|
243
|
+
return await formPost(requestTokenURL, convertJsonToURI(accessTokenRequest, { mode: JsonURIMode.X_FORM_WWW_URLENCODED }), {
|
|
244
|
+
customHeaders: opts?.headers ? opts.headers : undefined,
|
|
245
|
+
});
|
|
209
246
|
}
|
|
210
247
|
|
|
211
248
|
public static determineTokenURL({
|
|
@@ -114,7 +114,7 @@ export const createAuthorizationRequestUrl = async ({
|
|
|
114
114
|
const client_id = clientId ?? authorizationRequest.clientId;
|
|
115
115
|
|
|
116
116
|
// Authorization server metadata takes precedence
|
|
117
|
-
const authorizationMetadata = endpointMetadata.authorizationServerMetadata ?? endpointMetadata.credentialIssuerMetadata
|
|
117
|
+
const authorizationMetadata = endpointMetadata.authorizationServerMetadata ?? endpointMetadata.credentialIssuerMetadata;
|
|
118
118
|
|
|
119
119
|
let { authorizationDetails } = authorizationRequest;
|
|
120
120
|
const parMode = authorizationMetadata?.require_pushed_authorization_requests
|
|
@@ -148,8 +148,9 @@ export const createAuthorizationRequestUrl = async ({
|
|
|
148
148
|
|
|
149
149
|
// SD-JWT VC
|
|
150
150
|
const vct = cred.format === 'vc+sd-jwt' ? cred.vct : undefined;
|
|
151
|
+
const doctype = cred.format === 'mso_mdoc' ? cred.doctype : undefined;
|
|
151
152
|
|
|
152
|
-
// W3C credentials
|
|
153
|
+
// W3C credentials have a credential definition, the rest does not
|
|
153
154
|
let credential_definition: undefined | Partial<CredentialDefinitionJwtVcJsonV1_0_13 | CredentialDefinitionJwtVcJsonLdAndLdpVcV1_0_13> =
|
|
154
155
|
undefined;
|
|
155
156
|
if (isW3cCredentialSupported(cred)) {
|
|
@@ -171,6 +172,7 @@ export const createAuthorizationRequestUrl = async ({
|
|
|
171
172
|
...(credential_configuration_id && { credential_configuration_id }),
|
|
172
173
|
...(format && { format }),
|
|
173
174
|
...(vct && { vct, claims: cred.claims ? removeDisplayAndValueTypes(cred.claims) : undefined }),
|
|
175
|
+
...(doctype && { doctype, claims: cred.claims ? removeDisplayAndValueTypes(cred.claims) : undefined }),
|
|
174
176
|
} as AuthorizationDetails;
|
|
175
177
|
});
|
|
176
178
|
if (!authorizationDetails || authorizationDetails.length === 0) {
|
|
@@ -182,7 +184,6 @@ export const createAuthorizationRequestUrl = async ({
|
|
|
182
184
|
}
|
|
183
185
|
const parEndpoint = authorizationMetadata?.pushed_authorization_request_endpoint;
|
|
184
186
|
|
|
185
|
-
|
|
186
187
|
let queryObj: Record<string, any> | PushedAuthorizationResponse = {
|
|
187
188
|
response_type: ResponseType.AUTH_CODE,
|
|
188
189
|
...(!pkce.disabled && {
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
CodeChallengeMethod,
|
|
5
5
|
convertJsonToURI,
|
|
6
6
|
CreateRequestObjectMode,
|
|
7
|
-
|
|
7
|
+
CredentialOfferFormatV1_0_11,
|
|
8
8
|
CredentialOfferPayloadV1_0_11,
|
|
9
9
|
CredentialOfferRequestWithBaseUrl,
|
|
10
10
|
CredentialsSupportedLegacy,
|
|
@@ -40,14 +40,14 @@ export const createAuthorizationRequestUrlV1_0_11 = async ({
|
|
|
40
40
|
|
|
41
41
|
const parMode = endpointMetadata?.credentialIssuerMetadata?.require_pushed_authorization_requests
|
|
42
42
|
? PARMode.REQUIRE
|
|
43
|
-
: authorizationRequest.parMode ?? PARMode.AUTO;
|
|
43
|
+
: (authorizationRequest.parMode ?? PARMode.AUTO);
|
|
44
44
|
// Scope and authorization_details can be used in the same authorization request
|
|
45
45
|
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rar-23#name-relationship-to-scope-param
|
|
46
46
|
if (!scope && !authorizationDetails) {
|
|
47
47
|
if (!credentialOffer) {
|
|
48
48
|
throw Error('Please provide a scope or authorization_details if no credential offer is present');
|
|
49
49
|
}
|
|
50
|
-
const creds: (
|
|
50
|
+
const creds: (CredentialOfferFormatV1_0_11 | string)[] = (credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials;
|
|
51
51
|
|
|
52
52
|
// FIXME: complains about VCT for sd-jwt
|
|
53
53
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { createDPoP, CreateDPoPClientOpts, getCreateDPoPOptions } from '@sphereon/oid4vc-common';
|
|
1
2
|
import {
|
|
2
3
|
acquireDeferredCredential,
|
|
3
4
|
CredentialRequestV1_0_13,
|
|
4
5
|
CredentialResponse,
|
|
6
|
+
DPoPResponseParams,
|
|
5
7
|
getCredentialRequestForVersion,
|
|
6
8
|
getUniformFormat,
|
|
7
9
|
isDeferredCredentialResponse,
|
|
@@ -14,13 +16,14 @@ import {
|
|
|
14
16
|
UniformCredentialRequest,
|
|
15
17
|
URL_NOT_VALID,
|
|
16
18
|
} from '@sphereon/oid4vci-common';
|
|
17
|
-
import { ExperimentalSubjectIssuance } from '@sphereon/oid4vci-common
|
|
19
|
+
import { ExperimentalSubjectIssuance } from '@sphereon/oid4vci-common';
|
|
18
20
|
import { CredentialFormat } from '@sphereon/ssi-types';
|
|
19
21
|
import Debug from 'debug';
|
|
20
22
|
|
|
21
23
|
import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
|
|
22
24
|
import { CredentialRequestClientBuilderV1_0_13 } from './CredentialRequestClientBuilderV1_0_13';
|
|
23
25
|
import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
|
|
26
|
+
import { shouldRetryResourceRequestWithDPoPNonce } from './functions/dpopUtil';
|
|
24
27
|
|
|
25
28
|
const debug = Debug('sphereon:oid4vci:credential');
|
|
26
29
|
|
|
@@ -89,7 +92,8 @@ export class CredentialRequestClient {
|
|
|
89
92
|
context?: string[];
|
|
90
93
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
91
94
|
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
92
|
-
|
|
95
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
96
|
+
}): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
93
97
|
const { credentialIdentifier, credentialTypes, proofInput, format, context, subjectIssuance } = opts;
|
|
94
98
|
|
|
95
99
|
const request = await this.createCredentialRequest({
|
|
@@ -101,12 +105,13 @@ export class CredentialRequestClient {
|
|
|
101
105
|
credentialIdentifier,
|
|
102
106
|
subjectIssuance,
|
|
103
107
|
});
|
|
104
|
-
return await this.acquireCredentialsUsingRequest(request);
|
|
108
|
+
return await this.acquireCredentialsUsingRequest(request, opts.createDPoPOpts);
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
public async acquireCredentialsUsingRequest(
|
|
108
112
|
uniformRequest: UniformCredentialRequest,
|
|
109
|
-
|
|
113
|
+
createDPoPOpts?: CreateDPoPClientOpts,
|
|
114
|
+
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
110
115
|
if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
|
|
111
116
|
throw new Error('Versions below v1.0.13 (draft 13) are not supported by the V13 credential request client.');
|
|
112
117
|
}
|
|
@@ -119,9 +124,33 @@ export class CredentialRequestClient {
|
|
|
119
124
|
debug(`Acquiring credential(s) from: ${credentialEndpoint}`);
|
|
120
125
|
debug(`request\n: ${JSON.stringify(request, null, 2)}`);
|
|
121
126
|
const requestToken: string = this.credentialRequestOpts.token;
|
|
122
|
-
|
|
127
|
+
|
|
128
|
+
let dPoP = createDPoPOpts ? await createDPoP(getCreateDPoPOptions(createDPoPOpts, credentialEndpoint, { accessToken: requestToken })) : undefined;
|
|
129
|
+
|
|
130
|
+
let response = (await post(credentialEndpoint, JSON.stringify(request), {
|
|
131
|
+
bearerToken: requestToken,
|
|
132
|
+
...(dPoP && { customHeaders: { dpop: dPoP } }),
|
|
133
|
+
})) as OpenIDResponse<CredentialResponse> & {
|
|
123
134
|
access_token: string;
|
|
124
135
|
};
|
|
136
|
+
|
|
137
|
+
let nextDPoPNonce = createDPoPOpts?.jwtPayloadProps.nonce;
|
|
138
|
+
const retryWithNonce = shouldRetryResourceRequestWithDPoPNonce(response);
|
|
139
|
+
if (retryWithNonce.ok && createDPoPOpts) {
|
|
140
|
+
createDPoPOpts.jwtPayloadProps.nonce = retryWithNonce.dpopNonce;
|
|
141
|
+
dPoP = await createDPoP(getCreateDPoPOptions(createDPoPOpts, credentialEndpoint, { accessToken: requestToken }));
|
|
142
|
+
|
|
143
|
+
response = (await post(credentialEndpoint, JSON.stringify(request), {
|
|
144
|
+
bearerToken: requestToken,
|
|
145
|
+
...(createDPoPOpts && { customHeaders: { dpop: dPoP } }),
|
|
146
|
+
})) as OpenIDResponse<CredentialResponse> & {
|
|
147
|
+
access_token: string;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const successDPoPNonce = response.origResponse.headers.get('DPoP-Nonce');
|
|
151
|
+
nextDPoPNonce = successDPoPNonce ?? retryWithNonce.dpopNonce;
|
|
152
|
+
}
|
|
153
|
+
|
|
125
154
|
this._isDeferred = isDeferredCredentialResponse(response);
|
|
126
155
|
if (this.isDeferred() && this.credentialRequestOpts.deferredCredentialAwait && response.successBody) {
|
|
127
156
|
response = await this.acquireDeferredCredential(response.successBody, { bearerToken: this.credentialRequestOpts.token });
|
|
@@ -134,7 +163,11 @@ export class CredentialRequestClient {
|
|
|
134
163
|
}
|
|
135
164
|
}
|
|
136
165
|
debug(`Credential endpoint ${credentialEndpoint} response:\r\n${JSON.stringify(response, null, 2)}`);
|
|
137
|
-
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
...response,
|
|
169
|
+
...(nextDPoPNonce && { params: { dpop: { dpopNonce: nextDPoPNonce } } }),
|
|
170
|
+
};
|
|
138
171
|
}
|
|
139
172
|
|
|
140
173
|
public async acquireDeferredCredential(
|
|
@@ -228,13 +261,22 @@ export class CredentialRequestClient {
|
|
|
228
261
|
if (types.length > 1) {
|
|
229
262
|
throw Error(`Only a single credential type is supported for ${format}`);
|
|
230
263
|
}
|
|
231
|
-
// fixme: this isn't up to the CredentialRequest that we see in the version v1_0_13
|
|
232
264
|
return {
|
|
233
265
|
format,
|
|
234
266
|
proof,
|
|
235
267
|
vct: types[0],
|
|
236
268
|
...opts.subjectIssuance,
|
|
237
269
|
};
|
|
270
|
+
} else if (format === 'mso_mdoc') {
|
|
271
|
+
if (types.length > 1) {
|
|
272
|
+
throw Error(`Only a single credential type is supported for ${format}`);
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
format,
|
|
276
|
+
proof,
|
|
277
|
+
doctype: types[0],
|
|
278
|
+
...opts.subjectIssuance,
|
|
279
|
+
};
|
|
238
280
|
}
|
|
239
281
|
|
|
240
282
|
throw new Error(`Unsupported format: ${format}`);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { createDPoP, CreateDPoPClientOpts, getCreateDPoPOptions } from '@sphereon/oid4vc-common';
|
|
1
2
|
import {
|
|
2
3
|
acquireDeferredCredential,
|
|
3
4
|
CredentialResponse,
|
|
5
|
+
DPoPResponseParams,
|
|
4
6
|
getCredentialRequestForVersion,
|
|
5
7
|
getUniformFormat,
|
|
6
8
|
isDeferredCredentialResponse,
|
|
@@ -20,6 +22,7 @@ import Debug from 'debug';
|
|
|
20
22
|
import { buildProof } from './CredentialRequestClient';
|
|
21
23
|
import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
|
|
22
24
|
import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
|
|
25
|
+
import { shouldRetryResourceRequestWithDPoPNonce } from './functions/dpopUtil';
|
|
23
26
|
|
|
24
27
|
const debug = Debug('sphereon:oid4vci:credential');
|
|
25
28
|
|
|
@@ -64,16 +67,18 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
64
67
|
credentialTypes?: string | string[];
|
|
65
68
|
context?: string[];
|
|
66
69
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
67
|
-
|
|
70
|
+
createDPoPOpts?: CreateDPoPClientOpts;
|
|
71
|
+
}): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
68
72
|
const { credentialTypes, proofInput, format, context } = opts;
|
|
69
73
|
|
|
70
74
|
const request = await this.createCredentialRequest({ proofInput, credentialTypes, context, format, version: this.version() });
|
|
71
|
-
return await this.acquireCredentialsUsingRequest(request);
|
|
75
|
+
return await this.acquireCredentialsUsingRequest(request, opts.createDPoPOpts);
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
public async acquireCredentialsUsingRequest(
|
|
75
79
|
uniformRequest: UniformCredentialRequest,
|
|
76
|
-
|
|
80
|
+
createDPoPOpts?: CreateDPoPClientOpts,
|
|
81
|
+
): Promise<OpenIDResponse<CredentialResponse, DPoPResponseParams> & { access_token: string }> {
|
|
77
82
|
const request = getCredentialRequestForVersion(uniformRequest, this.version());
|
|
78
83
|
const credentialEndpoint: string = this.credentialRequestOpts.credentialEndpoint;
|
|
79
84
|
if (!isValidURL(credentialEndpoint)) {
|
|
@@ -83,9 +88,33 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
83
88
|
debug(`Acquiring credential(s) from: ${credentialEndpoint}`);
|
|
84
89
|
debug(`request\n: ${JSON.stringify(request, null, 2)}`);
|
|
85
90
|
const requestToken: string = this.credentialRequestOpts.token;
|
|
86
|
-
|
|
91
|
+
|
|
92
|
+
let dPoP = createDPoPOpts ? await createDPoP(getCreateDPoPOptions(createDPoPOpts, credentialEndpoint, { accessToken: requestToken })) : undefined;
|
|
93
|
+
|
|
94
|
+
let response = (await post(credentialEndpoint, JSON.stringify(request), {
|
|
95
|
+
bearerToken: requestToken,
|
|
96
|
+
customHeaders: { ...(createDPoPOpts && { dpop: dPoP }) },
|
|
97
|
+
})) as OpenIDResponse<CredentialResponse> & {
|
|
87
98
|
access_token: string;
|
|
88
99
|
};
|
|
100
|
+
|
|
101
|
+
let nextDPoPNonce = createDPoPOpts?.jwtPayloadProps.nonce;
|
|
102
|
+
const retryWithNonce = shouldRetryResourceRequestWithDPoPNonce(response);
|
|
103
|
+
if (retryWithNonce.ok && createDPoPOpts) {
|
|
104
|
+
createDPoPOpts.jwtPayloadProps.nonce = retryWithNonce.dpopNonce;
|
|
105
|
+
dPoP = await createDPoP(getCreateDPoPOptions(createDPoPOpts, credentialEndpoint, { accessToken: requestToken }));
|
|
106
|
+
|
|
107
|
+
response = (await post(credentialEndpoint, JSON.stringify(request), {
|
|
108
|
+
bearerToken: requestToken,
|
|
109
|
+
customHeaders: { ...(createDPoPOpts && { dpop: dPoP }) },
|
|
110
|
+
})) as OpenIDResponse<CredentialResponse> & {
|
|
111
|
+
access_token: string;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const successDPoPNonce = response.origResponse.headers.get('DPoP-Nonce');
|
|
115
|
+
nextDPoPNonce = successDPoPNonce ?? retryWithNonce.dpopNonce;
|
|
116
|
+
}
|
|
117
|
+
|
|
89
118
|
this._isDeferred = isDeferredCredentialResponse(response);
|
|
90
119
|
if (this.isDeferred() && this.credentialRequestOpts.deferredCredentialAwait && response.successBody) {
|
|
91
120
|
response = await this.acquireDeferredCredential(response.successBody, { bearerToken: this.credentialRequestOpts.token });
|
|
@@ -93,7 +122,11 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
93
122
|
response.access_token = requestToken;
|
|
94
123
|
|
|
95
124
|
debug(`Credential endpoint ${credentialEndpoint} response:\r\n${JSON.stringify(response, null, 2)}`);
|
|
96
|
-
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
...response,
|
|
128
|
+
...(nextDPoPNonce && { params: { dpop: { dpopNonce: nextDPoPNonce } } }),
|
|
129
|
+
};
|
|
97
130
|
}
|
|
98
131
|
|
|
99
132
|
public async acquireDeferredCredential(
|
|
@@ -182,6 +215,16 @@ export class CredentialRequestClientV1_0_11 {
|
|
|
182
215
|
proof,
|
|
183
216
|
vct: types[0],
|
|
184
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
|
+
};
|
|
185
228
|
}
|
|
186
229
|
|
|
187
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
|
|
|
@@ -50,7 +50,6 @@ 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 session_endpoint: string | undefined;
|
|
54
53
|
let authorizationServerType: AuthorizationServerType = 'OID4VCI';
|
|
55
54
|
let authorization_servers: string[] = [issuer];
|
|
56
55
|
const oid4vciResponse = await MetadataClientV1_0_13.retrieveOpenID4VCIServerMetadata(issuer, { errorOnNotFound: false }); // We will handle errors later, given we will also try other metadata locations
|
|
@@ -158,16 +157,11 @@ export class MetadataClientV1_0_13 {
|
|
|
158
157
|
credentialIssuerMetadata = authMetadata as CredentialIssuerMetadataV1_0_13;
|
|
159
158
|
}
|
|
160
159
|
debug(`Issuer ${issuer} token endpoint ${token_endpoint}, credential endpoint ${credential_endpoint}`);
|
|
161
|
-
|
|
162
|
-
if(credentialIssuerMetadata?.session_endpoint !== undefined) {
|
|
163
|
-
session_endpoint = credentialIssuerMetadata.session_endpoint
|
|
164
|
-
}
|
|
165
160
|
return {
|
|
166
161
|
issuer,
|
|
167
162
|
token_endpoint,
|
|
168
163
|
credential_endpoint,
|
|
169
164
|
deferred_credential_endpoint,
|
|
170
|
-
session_endpoint,
|
|
171
165
|
authorization_server: authorization_servers[0],
|
|
172
166
|
authorization_endpoint,
|
|
173
167
|
authorizationServerType,
|
|
@@ -180,6 +174,7 @@ export class MetadataClientV1_0_13 {
|
|
|
180
174
|
* Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata
|
|
181
175
|
*
|
|
182
176
|
* @param issuerHost The issuer hostname
|
|
177
|
+
* @param opts
|
|
183
178
|
*/
|
|
184
179
|
public static async retrieveOpenID4VCIServerMetadata(
|
|
185
180
|
issuerHost: string,
|