@sphereon/oid4vci-client 0.10.3 → 0.10.4-next.119
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 +24 -5
- package/dist/AccessTokenClient.d.ts +5 -5
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +51 -37
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.d.ts +29 -0
- package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -0
- package/dist/AccessTokenClientV1_0_11.js +209 -0
- package/dist/AccessTokenClientV1_0_11.js.map +1 -0
- package/dist/AuthorizationCodeClient.d.ts +9 -4
- package/dist/AuthorizationCodeClient.d.ts.map +1 -1
- package/dist/AuthorizationCodeClient.js +102 -18
- package/dist/AuthorizationCodeClient.js.map +1 -1
- package/dist/AuthorizationCodeClientV1_0_11.d.ts +9 -0
- package/dist/AuthorizationCodeClientV1_0_11.d.ts.map +1 -0
- package/dist/AuthorizationCodeClientV1_0_11.js +134 -0
- package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -0
- package/dist/CredentialOfferClient.d.ts.map +1 -1
- package/dist/CredentialOfferClient.js +18 -13
- package/dist/CredentialOfferClient.js.map +1 -1
- package/dist/CredentialOfferClientV1_0_11.d.ts +10 -0
- package/dist/CredentialOfferClientV1_0_11.d.ts.map +1 -0
- package/dist/CredentialOfferClientV1_0_11.js +101 -0
- package/dist/CredentialOfferClientV1_0_11.js.map +1 -0
- package/dist/CredentialOfferClientV1_0_13.d.ts +10 -0
- package/dist/CredentialOfferClientV1_0_13.d.ts.map +1 -0
- package/dist/CredentialOfferClientV1_0_13.js +94 -0
- package/dist/CredentialOfferClientV1_0_13.js.map +1 -0
- package/dist/CredentialRequestClient.d.ts +20 -7
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js +46 -30
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientBuilder.d.ts +11 -6
- package/dist/CredentialRequestClientBuilder.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilder.js +22 -9
- package/dist/CredentialRequestClientBuilder.js.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_11.d.ts +48 -0
- package/dist/CredentialRequestClientBuilderV1_0_11.d.ts.map +1 -0
- package/dist/CredentialRequestClientBuilderV1_0_11.js +121 -0
- package/dist/CredentialRequestClientBuilderV1_0_11.js.map +1 -0
- package/dist/CredentialRequestClientV1_0_11.d.ts +50 -0
- package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -0
- package/dist/CredentialRequestClientV1_0_11.js +151 -0
- package/dist/CredentialRequestClientV1_0_11.js.map +1 -0
- package/dist/MetadataClient.d.ts +5 -15
- package/dist/MetadataClient.d.ts.map +1 -1
- package/dist/MetadataClient.js +41 -44
- package/dist/MetadataClient.js.map +1 -1
- package/dist/MetadataClientV1_0_11.d.ts +31 -0
- package/dist/MetadataClientV1_0_11.d.ts.map +1 -0
- package/dist/MetadataClientV1_0_11.js +182 -0
- package/dist/MetadataClientV1_0_11.js.map +1 -0
- package/dist/MetadataClientV1_0_13.d.ts +31 -0
- package/dist/MetadataClientV1_0_13.d.ts.map +1 -0
- package/dist/MetadataClientV1_0_13.js +181 -0
- package/dist/MetadataClientV1_0_13.js.map +1 -0
- package/dist/OpenID4VCIClient.d.ts +14 -19
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +111 -61
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.d.ts +108 -0
- package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -0
- package/dist/OpenID4VCIClientV1_0_11.js +449 -0
- package/dist/OpenID4VCIClientV1_0_11.js.map +1 -0
- package/dist/OpenID4VCIClientV1_0_13.d.ts +112 -0
- package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -0
- package/dist/OpenID4VCIClientV1_0_13.js +478 -0
- package/dist/OpenID4VCIClientV1_0_13.js.map +1 -0
- package/dist/ProofOfPossessionBuilder.d.ts +14 -3
- package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
- package/dist/ProofOfPossessionBuilder.js +20 -21
- package/dist/ProofOfPossessionBuilder.js.map +1 -1
- package/dist/functions/OpenIDUtils.d.ts +12 -0
- package/dist/functions/OpenIDUtils.d.ts.map +1 -0
- package/dist/functions/OpenIDUtils.js +37 -0
- package/dist/functions/OpenIDUtils.js.map +1 -0
- package/dist/functions/index.d.ts +2 -3
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +2 -3
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/notifications.d.ts +4 -0
- package/dist/functions/notifications.d.ts.map +1 -0
- package/dist/functions/notifications.js +39 -0
- package/dist/functions/notifications.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -1
- package/lib/AccessTokenClient.ts +59 -34
- package/lib/AccessTokenClientV1_0_11.ts +250 -0
- package/lib/AuthorizationCodeClient.ts +131 -28
- package/lib/AuthorizationCodeClientV1_0_11.ts +170 -0
- package/lib/CredentialOfferClient.ts +21 -8
- package/lib/CredentialOfferClientV1_0_11.ts +112 -0
- package/lib/CredentialOfferClientV1_0_13.ts +103 -0
- package/lib/CredentialRequestClient.ts +65 -26
- package/lib/CredentialRequestClientBuilder.ts +34 -16
- package/lib/CredentialRequestClientBuilderV1_0_11.ts +163 -0
- package/lib/CredentialRequestClientV1_0_11.ts +197 -0
- package/lib/MetadataClient.ts +64 -49
- package/lib/MetadataClientV1_0_11.ts +189 -0
- package/lib/MetadataClientV1_0_13.ts +188 -0
- package/lib/OpenID4VCIClient.ts +132 -68
- package/lib/OpenID4VCIClientV1_0_11.ts +635 -0
- package/lib/OpenID4VCIClientV1_0_13.ts +677 -0
- package/lib/ProofOfPossessionBuilder.ts +41 -11
- package/lib/__tests__/AccessTokenClient.spec.ts +40 -12
- package/lib/__tests__/AuthorizationDetailsBuilder.spec.ts +0 -12
- package/lib/__tests__/CredentialRequestClient.spec.ts +87 -50
- package/lib/__tests__/CredentialRequestClientBuilder.spec.ts +18 -12
- package/lib/__tests__/CredentialRequestClientV1_0_11.spec.ts +317 -0
- package/lib/__tests__/EBSIE2E.spec.test.ts +2 -2
- package/lib/__tests__/HttpUtils.spec.ts +1 -1
- package/lib/__tests__/IT.spec.ts +264 -14
- package/lib/__tests__/IssuanceInitiation.spec.ts +59 -4
- package/lib/__tests__/IssuanceInitiationV1_0_11.spec.ts +62 -0
- package/lib/__tests__/MattrE2E.spec.test.ts +2 -2
- package/lib/__tests__/MetadataClient.spec.ts +53 -3
- package/lib/__tests__/MetadataMocks.ts +42 -2
- package/lib/__tests__/OpenID4VCIClient.spec.ts +58 -2
- package/lib/__tests__/{OpenID4VCIClientPAR.spec.ts → OpenID4VCIClientPARV1_0_11.spec.ts} +5 -5
- package/lib/__tests__/OpenID4VCIClientV1_0_11.spec.ts +226 -0
- package/lib/__tests__/OpenID4VCIClientV1_0_13.spec.ts +204 -0
- package/lib/__tests__/ProofOfPossessionBuilder.spec.ts +1 -1
- package/lib/__tests__/SdJwt.spec.ts +36 -30
- package/lib/__tests__/SphereonE2E.spec.test.ts +10 -7
- package/lib/__tests__/data/VciDataFixtures.ts +712 -27
- package/lib/functions/OpenIDUtils.ts +25 -0
- package/lib/functions/index.ts +2 -3
- package/lib/functions/notifications.ts +32 -0
- package/lib/index.ts +16 -1
- package/lib/types/index.ts +6 -0
- package/package.json +4 -4
- package/dist/functions/ProofUtil.d.ts +0 -30
- package/dist/functions/ProofUtil.d.ts.map +0 -1
- package/dist/functions/ProofUtil.js +0 -106
- package/dist/functions/ProofUtil.js.map +0 -1
- package/lib/functions/ProofUtil.ts +0 -128
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AccessTokenResponse,
|
|
3
3
|
Alg,
|
|
4
|
+
createProofOfPossession,
|
|
4
5
|
EndpointMetadata,
|
|
5
6
|
JWK,
|
|
6
7
|
Jwt,
|
|
7
8
|
NO_JWT_PROVIDED,
|
|
8
9
|
OpenId4VCIVersion,
|
|
10
|
+
PoPMode,
|
|
9
11
|
PROOF_CANT_BE_CONSTRUCTED,
|
|
10
12
|
ProofOfPossession,
|
|
11
13
|
ProofOfPossessionCallbacks,
|
|
12
14
|
Typ,
|
|
13
15
|
} from '@sphereon/oid4vci-common';
|
|
14
16
|
|
|
15
|
-
import { createProofOfPossession } from './functions';
|
|
16
|
-
|
|
17
17
|
export class ProofOfPossessionBuilder<DIDDoc> {
|
|
18
18
|
private readonly proof?: ProofOfPossession;
|
|
19
19
|
private readonly callbacks?: ProofOfPossessionCallbacks<DIDDoc>;
|
|
20
20
|
private readonly version: OpenId4VCIVersion;
|
|
21
|
+
private readonly mode: PoPMode = 'pop';
|
|
21
22
|
|
|
22
23
|
private kid?: string;
|
|
23
24
|
private jwk?: JWK;
|
|
25
|
+
private aud?: string | string[];
|
|
24
26
|
private clientId?: string;
|
|
25
27
|
private issuer?: string;
|
|
26
28
|
private jwt?: Jwt;
|
|
@@ -35,54 +37,80 @@ export class ProofOfPossessionBuilder<DIDDoc> {
|
|
|
35
37
|
jwt,
|
|
36
38
|
accessTokenResponse,
|
|
37
39
|
version,
|
|
40
|
+
mode = 'pop',
|
|
38
41
|
}: {
|
|
39
42
|
proof?: ProofOfPossession;
|
|
40
43
|
callbacks?: ProofOfPossessionCallbacks<DIDDoc>;
|
|
41
44
|
accessTokenResponse?: AccessTokenResponse;
|
|
42
45
|
jwt?: Jwt;
|
|
43
46
|
version: OpenId4VCIVersion;
|
|
47
|
+
mode?: PoPMode;
|
|
44
48
|
}) {
|
|
49
|
+
this.mode = mode;
|
|
45
50
|
this.proof = proof;
|
|
46
51
|
this.callbacks = callbacks;
|
|
47
52
|
this.version = version;
|
|
48
53
|
if (jwt) {
|
|
49
54
|
this.withJwt(jwt);
|
|
50
55
|
} else {
|
|
51
|
-
this.withTyp(version < OpenId4VCIVersion.VER_1_0_11 ? 'jwt' : 'openid4vci-proof+jwt');
|
|
56
|
+
this.withTyp(version < OpenId4VCIVersion.VER_1_0_11 || mode === 'jwt' ? 'jwt' : 'openid4vci-proof+jwt');
|
|
52
57
|
}
|
|
53
58
|
if (accessTokenResponse) {
|
|
54
59
|
this.withAccessTokenResponse(accessTokenResponse);
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
static manual<DIDDoc>({
|
|
64
|
+
jwt,
|
|
65
|
+
callbacks,
|
|
66
|
+
version,
|
|
67
|
+
mode = 'jwt',
|
|
68
|
+
}: {
|
|
69
|
+
jwt?: Jwt;
|
|
70
|
+
callbacks: ProofOfPossessionCallbacks<DIDDoc>;
|
|
71
|
+
version: OpenId4VCIVersion;
|
|
72
|
+
mode?: PoPMode;
|
|
73
|
+
}): ProofOfPossessionBuilder<DIDDoc> {
|
|
74
|
+
return new ProofOfPossessionBuilder({ callbacks, jwt, version, mode });
|
|
75
|
+
}
|
|
76
|
+
|
|
58
77
|
static fromJwt<DIDDoc>({
|
|
59
78
|
jwt,
|
|
60
79
|
callbacks,
|
|
61
80
|
version,
|
|
81
|
+
mode = 'pop',
|
|
62
82
|
}: {
|
|
63
83
|
jwt: Jwt;
|
|
64
84
|
callbacks: ProofOfPossessionCallbacks<DIDDoc>;
|
|
65
85
|
version: OpenId4VCIVersion;
|
|
86
|
+
mode?: PoPMode;
|
|
66
87
|
}): ProofOfPossessionBuilder<DIDDoc> {
|
|
67
|
-
return new ProofOfPossessionBuilder({ callbacks, jwt, version });
|
|
88
|
+
return new ProofOfPossessionBuilder({ callbacks, jwt, version, mode });
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
static fromAccessTokenResponse<DIDDoc>({
|
|
71
92
|
accessTokenResponse,
|
|
72
93
|
callbacks,
|
|
73
94
|
version,
|
|
95
|
+
mode = 'pop',
|
|
74
96
|
}: {
|
|
75
97
|
accessTokenResponse: AccessTokenResponse;
|
|
76
98
|
callbacks: ProofOfPossessionCallbacks<DIDDoc>;
|
|
77
99
|
version: OpenId4VCIVersion;
|
|
100
|
+
mode?: PoPMode;
|
|
78
101
|
}): ProofOfPossessionBuilder<DIDDoc> {
|
|
79
|
-
return new ProofOfPossessionBuilder({ callbacks, accessTokenResponse, version });
|
|
102
|
+
return new ProofOfPossessionBuilder({ callbacks, accessTokenResponse, version, mode });
|
|
80
103
|
}
|
|
81
104
|
|
|
82
105
|
static fromProof<DIDDoc>(proof: ProofOfPossession, version: OpenId4VCIVersion): ProofOfPossessionBuilder<DIDDoc> {
|
|
83
106
|
return new ProofOfPossessionBuilder({ proof, version });
|
|
84
107
|
}
|
|
85
108
|
|
|
109
|
+
withAud(aud: string | string[]): this {
|
|
110
|
+
this.aud = aud;
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
|
|
86
114
|
withClientId(clientId: string): this {
|
|
87
115
|
this.clientId = clientId;
|
|
88
116
|
return this;
|
|
@@ -114,7 +142,7 @@ export class ProofOfPossessionBuilder<DIDDoc> {
|
|
|
114
142
|
}
|
|
115
143
|
|
|
116
144
|
withTyp(typ: Typ): this {
|
|
117
|
-
if (this.version >= OpenId4VCIVersion.VER_1_0_11) {
|
|
145
|
+
if (this.mode === 'pop' && this.version >= OpenId4VCIVersion.VER_1_0_11) {
|
|
118
146
|
if (!!typ && typ !== 'openid4vci-proof+jwt') {
|
|
119
147
|
throw Error('typ must be openid4vci-proof+jwt for version 1.0.11 and up');
|
|
120
148
|
}
|
|
@@ -161,7 +189,7 @@ export class ProofOfPossessionBuilder<DIDDoc> {
|
|
|
161
189
|
if (jwt.header.typ) {
|
|
162
190
|
this.withTyp(jwt.header.typ as Typ);
|
|
163
191
|
}
|
|
164
|
-
if (this.version >= OpenId4VCIVersion.VER_1_0_11) {
|
|
192
|
+
if (!this.typ && this.version >= OpenId4VCIVersion.VER_1_0_11) {
|
|
165
193
|
this.withTyp('openid4vci-proof+jwt');
|
|
166
194
|
}
|
|
167
195
|
this.withAlg(jwt.header.alg);
|
|
@@ -172,8 +200,8 @@ export class ProofOfPossessionBuilder<DIDDoc> {
|
|
|
172
200
|
}
|
|
173
201
|
|
|
174
202
|
if (jwt.payload) {
|
|
175
|
-
if (jwt.payload.iss) this.withClientId(jwt.payload.iss);
|
|
176
|
-
if (jwt.payload.aud) this.withIssuer(jwt.payload.aud);
|
|
203
|
+
if (jwt.payload.iss) this.mode === 'pop' ? this.withClientId(jwt.payload.iss) : this.withIssuer(jwt.payload.iss);
|
|
204
|
+
if (jwt.payload.aud) this.mode === 'pop' ? this.withIssuer(jwt.payload.aud) : this.withAud(jwt.payload.aud);
|
|
177
205
|
if (jwt.payload.jti) this.withJti(jwt.payload.jti);
|
|
178
206
|
if (jwt.payload.nonce) this.withAccessTokenNonce(jwt.payload.nonce);
|
|
179
207
|
}
|
|
@@ -185,16 +213,18 @@ export class ProofOfPossessionBuilder<DIDDoc> {
|
|
|
185
213
|
return Promise.resolve(this.proof);
|
|
186
214
|
} else if (this.callbacks) {
|
|
187
215
|
return await createProofOfPossession(
|
|
216
|
+
this.mode,
|
|
188
217
|
this.callbacks,
|
|
189
218
|
{
|
|
190
|
-
typ: this.typ ?? (this.version < OpenId4VCIVersion.VER_1_0_11 ? 'jwt' : 'openid4vci-proof+jwt'),
|
|
219
|
+
typ: this.typ ?? (this.version < OpenId4VCIVersion.VER_1_0_11 || this.mode === 'jwt' ? 'jwt' : 'openid4vci-proof+jwt'),
|
|
191
220
|
kid: this.kid,
|
|
192
221
|
jwk: this.jwk,
|
|
193
222
|
jti: this.jti,
|
|
194
223
|
alg: this.alg,
|
|
224
|
+
aud: this.aud,
|
|
195
225
|
issuer: this.issuer,
|
|
196
226
|
clientId: this.clientId,
|
|
197
|
-
nonce: this.cNonce,
|
|
227
|
+
...(this.cNonce && { nonce: this.cNonce }),
|
|
198
228
|
},
|
|
199
229
|
this.jwt,
|
|
200
230
|
);
|
|
@@ -28,6 +28,7 @@ describe('AccessTokenClient should', () => {
|
|
|
28
28
|
|
|
29
29
|
const accessTokenRequest: AccessTokenRequest = {
|
|
30
30
|
grant_type: GrantTypes.PRE_AUTHORIZED_CODE,
|
|
31
|
+
user_pin: '20221013',
|
|
31
32
|
'pre-authorized_code': '20221013',
|
|
32
33
|
client_id: 'sphereon',
|
|
33
34
|
} as AccessTokenRequest;
|
|
@@ -44,6 +45,13 @@ describe('AccessTokenClient should', () => {
|
|
|
44
45
|
|
|
45
46
|
const accessTokenResponse: OpenIDResponse<AccessTokenResponse> = await accessTokenClient.acquireAccessTokenUsingRequest({
|
|
46
47
|
accessTokenRequest,
|
|
48
|
+
pinMetadata: {
|
|
49
|
+
isPinRequired: true,
|
|
50
|
+
txCode: {
|
|
51
|
+
length: accessTokenRequest['pre-authorized_code'].length,
|
|
52
|
+
input_mode: 'numeric',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
47
55
|
asOpts: { as: MOCK_URL },
|
|
48
56
|
});
|
|
49
57
|
|
|
@@ -121,10 +129,16 @@ describe('AccessTokenClient should', () => {
|
|
|
121
129
|
await expect(
|
|
122
130
|
accessTokenClient.acquireAccessTokenUsingRequest({
|
|
123
131
|
accessTokenRequest,
|
|
124
|
-
|
|
132
|
+
pinMetadata: {
|
|
133
|
+
isPinRequired: true,
|
|
134
|
+
txCode: {
|
|
135
|
+
length: 6,
|
|
136
|
+
input_mode: 'text',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
125
139
|
asOpts: { as: MOCK_URL },
|
|
126
140
|
}),
|
|
127
|
-
).rejects.toThrow('A valid pin
|
|
141
|
+
).rejects.toThrow('A valid pin must be present according to the specified transaction code requirements.');
|
|
128
142
|
},
|
|
129
143
|
UNIT_TEST_TIMEOUT,
|
|
130
144
|
);
|
|
@@ -146,10 +160,16 @@ describe('AccessTokenClient should', () => {
|
|
|
146
160
|
await expect(
|
|
147
161
|
accessTokenClient.acquireAccessTokenUsingRequest({
|
|
148
162
|
accessTokenRequest,
|
|
149
|
-
|
|
163
|
+
pinMetadata: {
|
|
164
|
+
isPinRequired: true,
|
|
165
|
+
txCode: {
|
|
166
|
+
length: 6,
|
|
167
|
+
input_mode: 'text',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
150
170
|
asOpts: { as: MOCK_URL },
|
|
151
171
|
}),
|
|
152
|
-
).rejects.toThrow(Error('A valid pin
|
|
172
|
+
).rejects.toThrow(Error('A valid pin must be present according to the specified transaction code requirements.'));
|
|
153
173
|
},
|
|
154
174
|
UNIT_TEST_TIMEOUT,
|
|
155
175
|
);
|
|
@@ -178,7 +198,13 @@ describe('AccessTokenClient should', () => {
|
|
|
178
198
|
|
|
179
199
|
const response = await accessTokenClient.acquireAccessTokenUsingRequest({
|
|
180
200
|
accessTokenRequest,
|
|
181
|
-
|
|
201
|
+
pinMetadata: {
|
|
202
|
+
isPinRequired: true,
|
|
203
|
+
txCode: {
|
|
204
|
+
length: 8,
|
|
205
|
+
input_mode: 'text',
|
|
206
|
+
},
|
|
207
|
+
},
|
|
182
208
|
asOpts: { as: MOCK_URL },
|
|
183
209
|
});
|
|
184
210
|
expect(response.successBody).toEqual(body);
|
|
@@ -190,13 +216,15 @@ describe('AccessTokenClient should', () => {
|
|
|
190
216
|
const accessTokenClient: AccessTokenClient = new AccessTokenClient();
|
|
191
217
|
|
|
192
218
|
nock(MOCK_URL).post(/.*/).reply(200, {});
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
nock(INITIATION_TEST.credential_offer.credential_issuer + 'token')
|
|
220
|
+
.post(/.*/)
|
|
221
|
+
.reply(200, {});
|
|
222
|
+
|
|
223
|
+
const response: OpenIDResponse<AccessTokenResponse> = await accessTokenClient.acquireAccessToken({
|
|
224
|
+
credentialOffer: INITIATION_TEST,
|
|
225
|
+
pin: '1234',
|
|
226
|
+
});
|
|
227
|
+
expect(response.successBody).toBeDefined();
|
|
200
228
|
});
|
|
201
229
|
|
|
202
230
|
it('get error if no as, issuer and metadata values are present', async () => {
|
|
@@ -50,16 +50,4 @@ describe('AuthorizationDetailsBuilder test', () => {
|
|
|
50
50
|
new AuthorizationDetailsBuilder().withType('openid_credential').withLocations(['test1']).buildJwtVcJson();
|
|
51
51
|
}).toThrow(Error('Type and format are required properties'));
|
|
52
52
|
});
|
|
53
|
-
it('should be able to add random field to the object', () => {
|
|
54
|
-
const actual = new AuthorizationDetailsBuilder()
|
|
55
|
-
.withFormats('jwt_vc' as OID4VCICredentialFormat)
|
|
56
|
-
.withType('openid_credential')
|
|
57
|
-
.buildJwtVcJson();
|
|
58
|
-
actual['random'] = 'test';
|
|
59
|
-
expect(actual).toEqual({
|
|
60
|
-
type: 'openid_credential',
|
|
61
|
-
format: 'jwt_vc',
|
|
62
|
-
random: 'test',
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
53
|
});
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
// Walt uses a self signed cert
|
|
2
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
3
|
+
|
|
1
4
|
import { KeyObject } from 'crypto';
|
|
2
5
|
|
|
3
6
|
import {
|
|
4
7
|
Alg,
|
|
8
|
+
CredentialRequestV1_0_13,
|
|
5
9
|
EndpointMetadata,
|
|
6
10
|
getCredentialRequestForVersion,
|
|
7
11
|
getIssuerFromCredentialOfferPayload,
|
|
@@ -16,19 +20,29 @@ import * as jose from 'jose';
|
|
|
16
20
|
// @ts-ignore
|
|
17
21
|
import nock from 'nock';
|
|
18
22
|
|
|
19
|
-
import {
|
|
20
|
-
|
|
23
|
+
import {
|
|
24
|
+
CredentialOfferClientV1_0_11,
|
|
25
|
+
CredentialRequestClientBuilder,
|
|
26
|
+
CredentialRequestClientBuilderV1_0_11,
|
|
27
|
+
MetadataClientV1_0_11,
|
|
28
|
+
ProofOfPossessionBuilder,
|
|
29
|
+
} from '..';
|
|
21
30
|
|
|
22
31
|
import { IDENTIPROOF_ISSUER_URL, IDENTIPROOF_OID4VCI_METADATA, INITIATION_TEST, WALT_OID4VCI_METADATA } from './MetadataMocks';
|
|
23
32
|
import { getMockData } from './data/VciDataFixtures';
|
|
24
33
|
|
|
25
34
|
const partialJWT = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmN';
|
|
26
35
|
|
|
27
|
-
const
|
|
36
|
+
const jwt1_0_08: Jwt = {
|
|
28
37
|
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
|
|
29
38
|
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
|
|
30
39
|
};
|
|
31
40
|
|
|
41
|
+
const jwt1_0_13: Jwt = {
|
|
42
|
+
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'openid4vci-proof+jwt' },
|
|
43
|
+
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
|
|
44
|
+
};
|
|
45
|
+
|
|
32
46
|
const kid = 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1';
|
|
33
47
|
|
|
34
48
|
let keypair: KeyPair;
|
|
@@ -67,36 +81,6 @@ afterEach(async () => {
|
|
|
67
81
|
nock.cleanAll();
|
|
68
82
|
});
|
|
69
83
|
describe('Credential Request Client ', () => {
|
|
70
|
-
it('should get a failed credential response with an unsupported format', async function () {
|
|
71
|
-
const basePath = 'https://sphereonjunit2022101301.com/';
|
|
72
|
-
nock(basePath).post(/.*/).reply(500, {
|
|
73
|
-
error: 'unsupported_format',
|
|
74
|
-
error_description: 'This is a mock error message',
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const credReqClient = CredentialRequestClientBuilder.fromCredentialOffer({ credentialOffer: INITIATION_TEST })
|
|
78
|
-
.withCredentialEndpoint(basePath + '/credential')
|
|
79
|
-
.withFormat('ldp_vc')
|
|
80
|
-
.withCredentialType('https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential')
|
|
81
|
-
.build();
|
|
82
|
-
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
83
|
-
jwt,
|
|
84
|
-
callbacks: {
|
|
85
|
-
signCallback: proofOfPossessionCallbackFunction,
|
|
86
|
-
},
|
|
87
|
-
version: OpenId4VCIVersion.VER_1_0_08,
|
|
88
|
-
})
|
|
89
|
-
// .withEndpointMetadata(metadata)
|
|
90
|
-
.withClientId('sphereon:wallet')
|
|
91
|
-
.withKid(kid)
|
|
92
|
-
.build();
|
|
93
|
-
expect(credReqClient.getCredentialEndpoint()).toEqual(basePath + '/credential');
|
|
94
|
-
const credentialRequest = await credReqClient.createCredentialRequest({ proofInput: proof, version: OpenId4VCIVersion.VER_1_0_08 });
|
|
95
|
-
expect(credentialRequest.proof?.jwt?.includes(partialJWT)).toBeTruthy();
|
|
96
|
-
const result = await credReqClient.acquireCredentialsUsingRequest(credentialRequest);
|
|
97
|
-
expect(result?.errorBody?.error).toBe('unsupported_format');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
84
|
it('should get success credential response', async function () {
|
|
101
85
|
const mockedVC =
|
|
102
86
|
'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.z5vgMTK1nfizNCg5N-niCOL3WUIAL7nXy-nGhDZYO_-PNGeE-0djCpWAMH8fD8eWSID5PfkPBYkx_dfLJnQ7NA';
|
|
@@ -112,20 +96,21 @@ describe('Credential Request Client ', () => {
|
|
|
112
96
|
.withCredentialType('https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential')
|
|
113
97
|
.build();
|
|
114
98
|
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
115
|
-
jwt,
|
|
99
|
+
jwt: jwt1_0_13,
|
|
116
100
|
callbacks: {
|
|
117
101
|
signCallback: proofOfPossessionCallbackFunction,
|
|
118
102
|
},
|
|
119
|
-
version: OpenId4VCIVersion.
|
|
103
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
120
104
|
})
|
|
121
105
|
// .withEndpointMetadata(metadata)
|
|
122
106
|
.withKid(kid)
|
|
123
107
|
.withClientId('sphereon:wallet')
|
|
124
108
|
.build();
|
|
125
109
|
const credentialRequest = await credReqClient.createCredentialRequest({
|
|
110
|
+
credentialTypes: 'OpenBadgeCredential',
|
|
126
111
|
proofInput: proof,
|
|
127
112
|
format: 'jwt',
|
|
128
|
-
version: OpenId4VCIVersion.
|
|
113
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
129
114
|
});
|
|
130
115
|
expect(credentialRequest.proof?.jwt?.includes(partialJWT)).toBeTruthy();
|
|
131
116
|
expect(credentialRequest.format).toEqual('jwt_vc');
|
|
@@ -137,10 +122,10 @@ describe('Credential Request Client ', () => {
|
|
|
137
122
|
const credReqClient = CredentialRequestClientBuilder.fromCredentialOfferRequest({ request: INITIATION_TEST })
|
|
138
123
|
.withCredentialEndpoint('httpsf://oidc4vci.demo.spruceid.com/credential')
|
|
139
124
|
.withFormat('jwt_vc')
|
|
140
|
-
.
|
|
125
|
+
.withCredentialIdentifier('https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential')
|
|
141
126
|
.build();
|
|
142
127
|
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
143
|
-
jwt,
|
|
128
|
+
jwt: jwt1_0_08,
|
|
144
129
|
callbacks: {
|
|
145
130
|
signCallback: proofOfPossessionCallbackFunction,
|
|
146
131
|
},
|
|
@@ -164,18 +149,19 @@ describe('Credential Request Client with Walt.id ', () => {
|
|
|
164
149
|
afterEach(() => {
|
|
165
150
|
nock.cleanAll();
|
|
166
151
|
});
|
|
167
|
-
|
|
152
|
+
// Walt id has cert issue
|
|
153
|
+
it.skip('should have correct metadata endpoints', async function () {
|
|
168
154
|
nock.cleanAll();
|
|
169
155
|
const WALT_IRR_URI =
|
|
170
156
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fjff.walt.id%2Fissuer-api%2Foidc%2F&credential_type=OpenBadgeCredential&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhOTUyZjUxNi1jYWVmLTQ4YjMtODIxYy00OTRkYzgyNjljZjAiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.YE5DlalcLC2ChGEg47CQDaN1gTxbaQqSclIVqsSAUHE&user_pin_required=false';
|
|
171
|
-
const credentialOffer = await
|
|
157
|
+
const credentialOffer = await CredentialOfferClientV1_0_11.fromURI(WALT_IRR_URI);
|
|
172
158
|
|
|
173
159
|
const request = credentialOffer.credential_offer;
|
|
174
|
-
const metadata = await
|
|
160
|
+
const metadata = await MetadataClientV1_0_11.retrieveAllMetadata(getIssuerFromCredentialOfferPayload(request) as string);
|
|
175
161
|
expect(metadata.credential_endpoint).toEqual(WALT_OID4VCI_METADATA.credential_endpoint);
|
|
176
162
|
expect(metadata.token_endpoint).toEqual(WALT_OID4VCI_METADATA.token_endpoint);
|
|
177
163
|
|
|
178
|
-
const credReqClient =
|
|
164
|
+
const credReqClient = CredentialRequestClientBuilderV1_0_11.fromCredentialOffer({
|
|
179
165
|
credentialOffer,
|
|
180
166
|
metadata,
|
|
181
167
|
}).build();
|
|
@@ -193,7 +179,7 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
193
179
|
});
|
|
194
180
|
it('should create correct CredentialRequest for Spruce', async () => {
|
|
195
181
|
const IRR_URI =
|
|
196
|
-
'openid-
|
|
182
|
+
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22:%22https://credential-issuer.example.com%22,%22credential_configuration_ids%22:%5B%22OpenBadgeCredential%22%5D,%22grants%22:%7B%22urn:ietf:params:oauth:grant-type:pre-authorized_code%22:%7B%22pre-authorized_code%22:%22oaKazRN8I0IbtZ0C7JuMn5%22,%22tx_code%22:%7B%22input_mode%22:%22text%22,%22description%22:%22Please%20enter%20the%20serial%20number%20of%20your%20physical%20drivers%20license%22%7D%7D%7D%7D';
|
|
197
183
|
const credentialRequest = await (
|
|
198
184
|
await CredentialRequestClientBuilder.fromURI({
|
|
199
185
|
uri: IRR_URI,
|
|
@@ -206,9 +192,9 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
206
192
|
proof_type: 'jwt',
|
|
207
193
|
jwt: getMockData('spruce')?.credential.request.proof.jwt as string,
|
|
208
194
|
},
|
|
209
|
-
credentialTypes:
|
|
195
|
+
credentialTypes: 'OpenBadgeCredential',
|
|
210
196
|
format: 'jwt_vc',
|
|
211
|
-
version: OpenId4VCIVersion.
|
|
197
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
212
198
|
});
|
|
213
199
|
const draft8CredentialRequest = getCredentialRequestForVersion(credentialRequest, OpenId4VCIVersion.VER_1_0_08);
|
|
214
200
|
expect(draft8CredentialRequest).toEqual(getMockData('spruce')?.credential.request);
|
|
@@ -219,7 +205,7 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
219
205
|
const IRR_URI =
|
|
220
206
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fjff.walt.id%2Fissuer-api%2Fdefault%2Foidc%2F&credential_type=OpenBadgeCredential&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIwMTc4OTNjYy04ZTY3LTQxNzItYWZlOS1lODcyYmYxNDBlNWMiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.ODfq2AIhOcB61dAb3zMrXBJjPJaf53zkeHh_AssYyYA&user_pin_required=false';
|
|
221
207
|
const credentialOffer = await (
|
|
222
|
-
await
|
|
208
|
+
await CredentialRequestClientBuilderV1_0_11.fromURI({
|
|
223
209
|
uri: IRR_URI,
|
|
224
210
|
metadata: getMockData('walt')?.metadata as unknown as EndpointMetadata,
|
|
225
211
|
})
|
|
@@ -253,9 +239,9 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
253
239
|
proof_type: 'jwt',
|
|
254
240
|
jwt: getMockData('uniissuer')?.credential.request.proof.jwt as string,
|
|
255
241
|
},
|
|
256
|
-
|
|
242
|
+
credentialIdentifier: 'OpenBadgeCredential',
|
|
257
243
|
format: 'jwt_vc',
|
|
258
|
-
version: OpenId4VCIVersion.
|
|
244
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
259
245
|
});
|
|
260
246
|
expect(credentialOffer).toEqual(getMockData('uniissuer')?.credential.request);
|
|
261
247
|
});
|
|
@@ -264,7 +250,7 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
264
250
|
const IRR_URI =
|
|
265
251
|
'openid-initiate-issuance://?issuer=https://launchpad.mattrlabs.com&credential_type=OpenBadgeCredential&pre-authorized_code=g0UCOj6RAN5AwHU6gczm_GzB4_lH6GW39Z0Dl2DOOiO';
|
|
266
252
|
const credentialOffer = await (
|
|
267
|
-
await
|
|
253
|
+
await CredentialRequestClientBuilderV1_0_11.fromURI({
|
|
268
254
|
uri: IRR_URI,
|
|
269
255
|
metadata: getMockData('mattr')?.metadata as unknown as EndpointMetadata,
|
|
270
256
|
})
|
|
@@ -287,7 +273,7 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
287
273
|
const IRR_URI =
|
|
288
274
|
'openid-initiate-issuance://?issuer=https://oidc4vc.diwala.io&credential_type=OpenBadgeCredential&pre-authorized_code=eyJhbGciOiJIUzI1NiJ9.eyJjcmVkZW50aWFsX3R5cGUiOiJPcGVuQmFkZ2VDcmVkZW50aWFsIiwiZXhwIjoxNjgxOTg0NDY3fQ.fEAHKz2nuWfiYHw406iNxr-81pWkNkbi31bWsYSf6Ng';
|
|
289
275
|
const credentialOffer = await (
|
|
290
|
-
await
|
|
276
|
+
await CredentialRequestClientBuilderV1_0_11.fromURI({
|
|
291
277
|
uri: IRR_URI,
|
|
292
278
|
metadata: getMockData('diwala')?.metadata as unknown as EndpointMetadata,
|
|
293
279
|
})
|
|
@@ -308,4 +294,55 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
308
294
|
|
|
309
295
|
expect(credentialRequest).toEqual(getMockData('diwala')?.credential.request);
|
|
310
296
|
});
|
|
297
|
+
|
|
298
|
+
// TODO: ksadjad remove the skipped test
|
|
299
|
+
it('should create correct CredentialRequest for credenco', async () => {
|
|
300
|
+
const IRR_URI =
|
|
301
|
+
'openid-credential-offer://mijnkvk.acc.credenco.com/?credential_offer_uri=https%3A%2F%2Fmijnkvk.acc.credenco.com%2Fopenid4vc%2FcredentialOffer%3Fid%3D32fc4ebf-9e31-4149-9877-e3c0b602d559';
|
|
302
|
+
nock('https://mijnkvk.acc.credenco.com')
|
|
303
|
+
.get('/openid4vc/credentialOffer?id=32fc4ebf-9e31-4149-9877-e3c0b602d559')
|
|
304
|
+
.reply(200, {
|
|
305
|
+
credential_issuer: 'https://mijnkvk.acc.credenco.com',
|
|
306
|
+
credential_configuration_ids: ['BevoegdheidUittreksel_jwt_vc_json'],
|
|
307
|
+
grants: {
|
|
308
|
+
authorization_code: {
|
|
309
|
+
issuer_state: '32fc4ebf-9e31-4149-9877-e3c0b602d559',
|
|
310
|
+
},
|
|
311
|
+
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
312
|
+
'pre-authorized_code':
|
|
313
|
+
'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIzMmZjNGViZi05ZTMxLTQxNDktOTg3Ny1lM2MwYjYwMmQ1NTkiLCJpc3MiOiJodHRwczovL21pam5rdmsuYWNjLmNyZWRlbmNvLmNvbSIsImF1ZCI6IlRPS0VOIn0.754aiQ87O0vHYSpRvPqAS9cLOgf-pewdeXbpLziRwsxEp9mENfaXpY62muYpzOaWcYmTOydkzhFul-NDYXJZCA',
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
const credentialOffer = await (
|
|
318
|
+
await CredentialRequestClientBuilder.fromURI({
|
|
319
|
+
uri: IRR_URI,
|
|
320
|
+
metadata: getMockData('credenco')?.metadata as unknown as EndpointMetadata,
|
|
321
|
+
})
|
|
322
|
+
)
|
|
323
|
+
.build()
|
|
324
|
+
.createCredentialRequest({
|
|
325
|
+
proofInput: {
|
|
326
|
+
proof_type: 'jwt',
|
|
327
|
+
jwt: getMockData('diwala')?.credential.request.proof.jwt as string,
|
|
328
|
+
},
|
|
329
|
+
credentialIdentifier: 'BevoegdheidUittreksel_jwt_vc_json',
|
|
330
|
+
// format: 'ldp_vc',
|
|
331
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// createCredentialRequest returns uniform format in draft 11
|
|
335
|
+
const credentialRequest: CredentialRequestV1_0_13 = getCredentialRequestForVersion(
|
|
336
|
+
credentialOffer,
|
|
337
|
+
OpenId4VCIVersion.VER_1_0_13,
|
|
338
|
+
) as CredentialRequestV1_0_13;
|
|
339
|
+
|
|
340
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
341
|
+
// @ts-ignore
|
|
342
|
+
expect(credentialRequest.credential_identifier).toEqual('BevoegdheidUittreksel_jwt_vc_json');
|
|
343
|
+
expect(credentialRequest.proof).toEqual({
|
|
344
|
+
jwt: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa3AxM3N6QUFMVFN0cDV1OGtMcnl5YW5vYWtrVWtFUGZXazdvOHY3dms0RW1KI3o2TWtwMTNzekFBTFRTdHA1dThrTHJ5eWFub2Fra1VrRVBmV2s3bzh2N3ZrNEVtSiJ9.eyJhdWQiOiJodHRwczovL29pZGM0dmMuZGl3YWxhLmlvIiwiaWF0IjoxNjgxOTE1MDk1LjIwMiwiZXhwIjoxNjgxOTE1NzU1LjIwMiwiaXNzIjoic3BoZXJlb246c3NpLXdhbGxldCIsImp0aSI6IjYxN2MwM2EzLTM3MTUtNGJlMy1hYjkxNzM4MTlmYzYxNTYzIn0.KA-cHjecaYp9FSaWHkz5cqtNyhBIVT_0I7cJnpHn03T4UWFvdhjhn8Hpe-BU247enFyWOWJ6v3NQZyZgle7xBA',
|
|
345
|
+
proof_type: 'jwt',
|
|
346
|
+
});
|
|
347
|
+
});
|
|
311
348
|
});
|
|
@@ -2,12 +2,12 @@ import { KeyObject } from 'crypto';
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Alg,
|
|
5
|
-
|
|
5
|
+
CredentialIssuerMetadataV1_0_13,
|
|
6
|
+
CredentialRequestV1_0_13,
|
|
6
7
|
Jwt,
|
|
7
8
|
JwtVerifyResult,
|
|
8
9
|
OpenId4VCIVersion,
|
|
9
10
|
ProofOfPossession,
|
|
10
|
-
UniformCredentialRequest,
|
|
11
11
|
} from '@sphereon/oid4vci-common';
|
|
12
12
|
import * as jose from 'jose';
|
|
13
13
|
|
|
@@ -17,9 +17,14 @@ import { IDENTIPROOF_ISSUER_URL, IDENTIPROOF_OID4VCI_METADATA, INITIATION_TEST_U
|
|
|
17
17
|
|
|
18
18
|
const partialJWT = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmN';
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
/*const jwtv1_0_08: Jwt = {
|
|
21
21
|
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
|
|
22
22
|
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
|
|
23
|
+
};*/
|
|
24
|
+
|
|
25
|
+
const jwtv1_0_11: Jwt = {
|
|
26
|
+
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'openid4vci-proof+jwt' },
|
|
27
|
+
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
|
|
23
28
|
};
|
|
24
29
|
|
|
25
30
|
const kid = 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1';
|
|
@@ -71,12 +76,12 @@ describe('Credential Request Client Builder', () => {
|
|
|
71
76
|
const credReqClient = (await CredentialRequestClientBuilder.fromURI({ uri: INITIATION_TEST_URI }))
|
|
72
77
|
.withCredentialEndpoint('https://oidc4vci.demo.spruceid.com/credential')
|
|
73
78
|
.withFormat('jwt_vc')
|
|
74
|
-
.
|
|
79
|
+
.withCredentialIdentifier('credentialType')
|
|
75
80
|
.withToken('token')
|
|
76
81
|
.build();
|
|
77
82
|
expect(credReqClient.credentialRequestOpts.credentialEndpoint).toBe('https://oidc4vci.demo.spruceid.com/credential');
|
|
78
83
|
expect(credReqClient.credentialRequestOpts.format).toBe('jwt_vc');
|
|
79
|
-
expect(credReqClient.credentialRequestOpts.
|
|
84
|
+
expect(credReqClient.credentialRequestOpts.credentialIdentifier).toStrictEqual('credentialType');
|
|
80
85
|
expect(credReqClient.credentialRequestOpts.token).toBe('token');
|
|
81
86
|
});
|
|
82
87
|
|
|
@@ -84,26 +89,27 @@ describe('Credential Request Client Builder', () => {
|
|
|
84
89
|
const credReqClient = (await CredentialRequestClientBuilder.fromURI({ uri: INITIATION_TEST_URI }))
|
|
85
90
|
.withCredentialEndpoint('https://oidc4vci.demo.spruceid.com/credential')
|
|
86
91
|
.withFormat('jwt_vc')
|
|
87
|
-
.
|
|
92
|
+
.withCredentialIdentifier('OpenBadgeCredential')
|
|
88
93
|
.build();
|
|
89
94
|
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
90
|
-
jwt,
|
|
95
|
+
jwt: jwtv1_0_11,
|
|
91
96
|
callbacks: {
|
|
92
97
|
signCallback: proofOfPossessionCallbackFunction,
|
|
93
98
|
verifyCallback: proofOfPossessionVerifierCallbackFunction,
|
|
94
99
|
},
|
|
95
|
-
version: OpenId4VCIVersion.
|
|
100
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
96
101
|
})
|
|
97
102
|
.withClientId('sphereon:wallet')
|
|
98
103
|
.withKid(kid)
|
|
99
104
|
.build();
|
|
100
105
|
await proofOfPossessionVerifierCallbackFunction({ ...proof, kid });
|
|
101
|
-
const credentialRequest:
|
|
106
|
+
const credentialRequest: CredentialRequestV1_0_13 = await credReqClient.createCredentialRequest({
|
|
102
107
|
proofInput: proof,
|
|
103
|
-
|
|
108
|
+
credentialIdentifier: 'OpenBadgeCredential',
|
|
109
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
104
110
|
});
|
|
105
111
|
expect(credentialRequest.proof?.jwt).toContain(partialJWT);
|
|
106
|
-
expect('
|
|
112
|
+
expect('credential_identifier' in credentialRequest).toBe(true);
|
|
107
113
|
if ('types' in credentialRequest) {
|
|
108
114
|
expect(credentialRequest.types).toStrictEqual(['https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential']);
|
|
109
115
|
}
|
|
@@ -124,7 +130,7 @@ describe('Credential Request Client Builder', () => {
|
|
|
124
130
|
it('should build correctly with endpoint from metadata', async () => {
|
|
125
131
|
const credReqClient = (await CredentialRequestClientBuilder.fromURI({ uri: INITIATION_TEST_URI }))
|
|
126
132
|
.withFormat('jwt_vc')
|
|
127
|
-
.withCredentialEndpointFromMetadata(IDENTIPROOF_OID4VCI_METADATA as unknown as
|
|
133
|
+
.withCredentialEndpointFromMetadata(IDENTIPROOF_OID4VCI_METADATA as unknown as CredentialIssuerMetadataV1_0_13)
|
|
128
134
|
.build();
|
|
129
135
|
expect(credReqClient.credentialRequestOpts.credentialEndpoint).toBe(`${IDENTIPROOF_ISSUER_URL}/credential`);
|
|
130
136
|
});
|