@sphereon/oid4vci-client 0.12.0 → 0.12.1-next.19
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.js +1 -1
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.js +1 -1
- package/dist/AccessTokenClientV1_0_11.js.map +1 -1
- package/dist/AuthorizationCodeClient.d.ts.map +1 -1
- package/dist/AuthorizationCodeClient.js +4 -1
- package/dist/AuthorizationCodeClient.js.map +1 -1
- package/dist/CredentialRequestClient.d.ts +3 -2
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientBuilder.d.ts +7 -15
- package/dist/CredentialRequestClientBuilder.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilder.js +79 -55
- package/dist/CredentialRequestClientBuilder.js.map +1 -1
- package/dist/CredentialRequestClientBuilderV1_0_13.d.ts +51 -0
- package/dist/CredentialRequestClientBuilderV1_0_13.d.ts.map +1 -0
- package/dist/CredentialRequestClientBuilderV1_0_13.js +130 -0
- package/dist/CredentialRequestClientBuilderV1_0_13.js.map +1 -0
- package/dist/OpenID4VCIClient.d.ts +1 -0
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +5 -5
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/lib/AccessTokenClient.ts +1 -1
- package/lib/AccessTokenClientV1_0_11.ts +1 -1
- package/lib/AuthorizationCodeClient.ts +7 -4
- package/lib/CredentialRequestClient.ts +3 -2
- package/lib/CredentialRequestClientBuilder.ts +98 -67
- package/lib/CredentialRequestClientBuilderV1_0_13.ts +173 -0
- package/lib/OpenID4VCIClient.ts +6 -4
- package/lib/__tests__/CredentialRequestClient.spec.ts +8 -13
- package/lib/__tests__/CredentialRequestClientBuilder.spec.ts +40 -2
- package/lib/__tests__/CredentialRequestClientV1_0_11.spec.ts +96 -0
- package/lib/__tests__/IT.spec.ts +148 -111
- package/lib/__tests__/MetadataMocks.ts +35 -0
- package/lib/__tests__/ProofOfPossessionBuilder.spec.ts +85 -0
- package/lib/__tests__/SdJwt.spec.ts +103 -0
- package/lib/index.ts +1 -0
- package/package.json +3 -3
|
@@ -28,14 +28,22 @@ import {
|
|
|
28
28
|
import { getMockData } from './data/VciDataFixtures';
|
|
29
29
|
|
|
30
30
|
const partialJWT = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmN';
|
|
31
|
+
const partialJWT_withoutDid = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJlYmZlYjFmNzEyZWJjNmYxYzI3N';
|
|
31
32
|
|
|
32
33
|
const jwt: Jwt = {
|
|
33
34
|
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
|
|
34
35
|
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
|
|
35
36
|
};
|
|
36
37
|
|
|
38
|
+
const jwt_withoutDid: Jwt = {
|
|
39
|
+
header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
|
|
40
|
+
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL },
|
|
41
|
+
};
|
|
42
|
+
|
|
37
43
|
const kid = 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1';
|
|
38
44
|
|
|
45
|
+
const kid_withoutDid = 'ebfeb1f712ebc6f1c276e12ec21/keys/1';
|
|
46
|
+
|
|
39
47
|
let keypair: KeyPair;
|
|
40
48
|
|
|
41
49
|
async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promise<string> {
|
|
@@ -102,6 +110,36 @@ describe('Credential Request Client ', () => {
|
|
|
102
110
|
expect(result?.errorBody?.error).toBe('unsupported_format');
|
|
103
111
|
});
|
|
104
112
|
|
|
113
|
+
it('should get a failed credential response with an unsupported format and without did', async function () {
|
|
114
|
+
const basePath = 'https://sphereonjunit2022101301.com/';
|
|
115
|
+
nock(basePath).post(/.*/).reply(500, {
|
|
116
|
+
error: 'unsupported_format',
|
|
117
|
+
error_description: 'This is a mock error message',
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const credReqClient = CredentialRequestClientBuilderV1_0_11.fromCredentialOffer({ credentialOffer: INITIATION_TEST_V1_0_08 })
|
|
121
|
+
.withCredentialEndpoint(basePath + '/credential')
|
|
122
|
+
.withFormat('ldp_vc')
|
|
123
|
+
.withCredentialType('https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential')
|
|
124
|
+
.build();
|
|
125
|
+
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
126
|
+
jwt: jwt_withoutDid,
|
|
127
|
+
callbacks: {
|
|
128
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
129
|
+
},
|
|
130
|
+
version: OpenId4VCIVersion.VER_1_0_08,
|
|
131
|
+
})
|
|
132
|
+
// .withEndpointMetadata(metadata)
|
|
133
|
+
.withClientId('sphereon:wallet')
|
|
134
|
+
.withKid(kid_withoutDid)
|
|
135
|
+
.build();
|
|
136
|
+
expect(credReqClient.getCredentialEndpoint()).toEqual(basePath + '/credential');
|
|
137
|
+
const credentialRequest = await credReqClient.createCredentialRequest({ proofInput: proof, version: OpenId4VCIVersion.VER_1_0_08 });
|
|
138
|
+
expect(credentialRequest.proof?.jwt?.includes(partialJWT_withoutDid)).toBeTruthy();
|
|
139
|
+
const result = await credReqClient.acquireCredentialsUsingRequest(credentialRequest);
|
|
140
|
+
expect(result?.errorBody?.error).toBe('unsupported_format');
|
|
141
|
+
});
|
|
142
|
+
|
|
105
143
|
it('should get success credential response', async function () {
|
|
106
144
|
const mockedVC =
|
|
107
145
|
'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.z5vgMTK1nfizNCg5N-niCOL3WUIAL7nXy-nGhDZYO_-PNGeE-0djCpWAMH8fD8eWSID5PfkPBYkx_dfLJnQ7NA';
|
|
@@ -138,6 +176,42 @@ describe('Credential Request Client ', () => {
|
|
|
138
176
|
expect(result?.successBody?.credential).toEqual(mockedVC);
|
|
139
177
|
});
|
|
140
178
|
|
|
179
|
+
it('should get success credential response without did', async function () {
|
|
180
|
+
const mockedVC =
|
|
181
|
+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJlYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsImlhdCI6MTcxODM1NzcxOH0.7iiOTuIjQRyrIincYyDW6m0nBYmDoYfXcTYFrywsKEY';
|
|
182
|
+
nock('https://oidc4vci.demo.spruceid.com')
|
|
183
|
+
.post(/credential/)
|
|
184
|
+
.reply(200, {
|
|
185
|
+
format: 'jwt-vc',
|
|
186
|
+
credential: mockedVC,
|
|
187
|
+
});
|
|
188
|
+
const credReqClient = CredentialRequestClientBuilderV1_0_11.fromCredentialOfferRequest({ request: INITIATION_TEST })
|
|
189
|
+
.withCredentialEndpoint('https://oidc4vci.demo.spruceid.com/credential')
|
|
190
|
+
.withFormat('jwt_vc')
|
|
191
|
+
.withCredentialType('https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential')
|
|
192
|
+
.build();
|
|
193
|
+
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
194
|
+
jwt: jwt_withoutDid,
|
|
195
|
+
callbacks: {
|
|
196
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
197
|
+
},
|
|
198
|
+
version: OpenId4VCIVersion.VER_1_0_08,
|
|
199
|
+
})
|
|
200
|
+
// .withEndpointMetadata(metadata)
|
|
201
|
+
.withKid(kid_withoutDid)
|
|
202
|
+
.withClientId('sphereon:wallet')
|
|
203
|
+
.build();
|
|
204
|
+
const credentialRequest = await credReqClient.createCredentialRequest({
|
|
205
|
+
proofInput: proof,
|
|
206
|
+
format: 'jwt',
|
|
207
|
+
version: OpenId4VCIVersion.VER_1_0_08,
|
|
208
|
+
});
|
|
209
|
+
expect(credentialRequest.proof?.jwt?.includes(partialJWT_withoutDid)).toBeTruthy();
|
|
210
|
+
expect(credentialRequest.format).toEqual('jwt_vc');
|
|
211
|
+
const result = await credReqClient.acquireCredentialsUsingRequest(credentialRequest);
|
|
212
|
+
expect(result?.successBody?.credential).toEqual(mockedVC);
|
|
213
|
+
});
|
|
214
|
+
|
|
141
215
|
it('should fail with invalid url', async () => {
|
|
142
216
|
const credReqClient = CredentialRequestClientBuilderV1_0_11.fromCredentialOfferRequest({ request: INITIATION_TEST })
|
|
143
217
|
.withCredentialEndpoint('httpsf://oidc4vci.demo.spruceid.com/credential')
|
|
@@ -159,6 +233,28 @@ describe('Credential Request Client ', () => {
|
|
|
159
233
|
Error(URL_NOT_VALID),
|
|
160
234
|
);
|
|
161
235
|
});
|
|
236
|
+
|
|
237
|
+
it('should fail with invalid url without did', async () => {
|
|
238
|
+
const credReqClient = CredentialRequestClientBuilderV1_0_11.fromCredentialOfferRequest({ request: INITIATION_TEST })
|
|
239
|
+
.withCredentialEndpoint('httpsf://oidc4vci.demo.spruceid.com/credential')
|
|
240
|
+
.withFormat('jwt_vc')
|
|
241
|
+
.withCredentialType('https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#OpenBadgeCredential')
|
|
242
|
+
.build();
|
|
243
|
+
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
244
|
+
jwt: jwt_withoutDid,
|
|
245
|
+
callbacks: {
|
|
246
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
247
|
+
},
|
|
248
|
+
version: OpenId4VCIVersion.VER_1_0_08,
|
|
249
|
+
})
|
|
250
|
+
// .withEndpointMetadata(metadata)
|
|
251
|
+
.withKid(kid_withoutDid)
|
|
252
|
+
.withClientId('sphereon:wallet')
|
|
253
|
+
.build();
|
|
254
|
+
await expect(credReqClient.acquireCredentialsUsingRequest({ format: 'jwt_vc_json', types: ['random'], proof })).rejects.toThrow(
|
|
255
|
+
Error(URL_NOT_VALID),
|
|
256
|
+
);
|
|
257
|
+
});
|
|
162
258
|
});
|
|
163
259
|
|
|
164
260
|
describe('Credential Request Client with Walt.id ', () => {
|
package/lib/__tests__/IT.spec.ts
CHANGED
|
@@ -13,32 +13,52 @@ import {
|
|
|
13
13
|
// @ts-ignore
|
|
14
14
|
import nock from 'nock';
|
|
15
15
|
|
|
16
|
-
import {
|
|
17
|
-
AccessTokenClient,
|
|
18
|
-
AccessTokenClientV1_0_11,
|
|
19
|
-
CredentialOfferClientV1_0_11,
|
|
20
|
-
CredentialRequestClientBuilder,
|
|
21
|
-
CredentialRequestClientBuilderV1_0_11,
|
|
22
|
-
OpenID4VCIClientV1_0_11,
|
|
23
|
-
ProofOfPossessionBuilder,
|
|
24
|
-
} from '..';
|
|
16
|
+
import { AccessTokenClient, AccessTokenClientV1_0_11, OpenID4VCIClient, OpenID4VCIClientV1_0_13, ProofOfPossessionBuilder } from '..';
|
|
25
17
|
import { CredentialOfferClient } from '../CredentialOfferClient';
|
|
18
|
+
import { CredentialRequestClientBuilder } from '../CredentialRequestClientBuilder';
|
|
26
19
|
|
|
27
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
IDENTIPROOF_AS_METADATA,
|
|
22
|
+
IDENTIPROOF_AS_URL,
|
|
23
|
+
IDENTIPROOF_ISSUER_URL,
|
|
24
|
+
IDENTIPROOF_OID4VCI_METADATA,
|
|
25
|
+
IDENTIPROOF_OID4VCI_METADATA_v13,
|
|
26
|
+
} from './MetadataMocks';
|
|
28
27
|
|
|
29
28
|
export const UNIT_TEST_TIMEOUT = 30000;
|
|
30
29
|
|
|
31
30
|
const ISSUER_URL = 'https://issuer.research.identiproof.io';
|
|
32
|
-
const
|
|
31
|
+
const jwtDid = {
|
|
33
32
|
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'openid4vci-proof+jwt' },
|
|
34
33
|
payload: { iss: 'test-clientId', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: ISSUER_URL },
|
|
35
34
|
};
|
|
36
35
|
|
|
36
|
+
const jwtWithoutDid = {
|
|
37
|
+
header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'openid4vci-proof+jwt' },
|
|
38
|
+
payload: { iss: 'test-clientId', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: ISSUER_URL },
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const mockedVC =
|
|
42
|
+
'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.z5vgMTK1nfizNCg5N-niCOL3WUIAL7nXy-nGhDZYO_-PNGeE-0djCpWAMH8fD8eWSID5PfkPBYkx_dfLJnQ7NA';
|
|
43
|
+
|
|
44
|
+
// Access token mocks
|
|
45
|
+
const mockedAccessTokenResponse: AccessTokenResponse = {
|
|
46
|
+
access_token: 'ey6546.546654.64565',
|
|
47
|
+
authorization_pending: false,
|
|
48
|
+
c_nonce: 'c_nonce2022101300',
|
|
49
|
+
c_nonce_expires_in: 2025101300,
|
|
50
|
+
interval: 2025101300,
|
|
51
|
+
token_type: 'Bearer',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const INITIATE_QR_V1_0_13 =
|
|
55
|
+
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22:%22https://issuer.research.identiproof.io%22,%22credential_configuration_ids%22:%5B%22OpenBadgeCredentialUrl%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,%22length%22:22,%22description%22:%22Please%20enter%20the%20serial%20number%20of%20your%20physical%20drivers%20license%22%7D%7D%7D%7D';
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
58
|
+
async function proofOfPossessionCallbackFunction(_args: Jwt, _kid?: string): Promise<string> {
|
|
59
|
+
return 'ey.val.ue';
|
|
60
|
+
}
|
|
37
61
|
describe('OID4VCI-Client should', () => {
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
39
|
-
async function proofOfPossessionCallbackFunction(_args: Jwt, _kid?: string): Promise<string> {
|
|
40
|
-
return 'ey.val.ue';
|
|
41
|
-
}
|
|
42
62
|
beforeEach(() => {
|
|
43
63
|
nock.cleanAll();
|
|
44
64
|
});
|
|
@@ -55,8 +75,6 @@ describe('OID4VCI-Client should', () => {
|
|
|
55
75
|
interval: 2025101300,
|
|
56
76
|
token_type: 'Bearer',
|
|
57
77
|
};
|
|
58
|
-
const mockedVC =
|
|
59
|
-
'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.z5vgMTK1nfizNCg5N-niCOL3WUIAL7nXy-nGhDZYO_-PNGeE-0djCpWAMH8fD8eWSID5PfkPBYkx_dfLJnQ7NA';
|
|
60
78
|
const INITIATE_QR_V1_0_08 =
|
|
61
79
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true';
|
|
62
80
|
const OFFER_QR_V1_0_08 =
|
|
@@ -67,14 +85,14 @@ describe('OID4VCI-Client should', () => {
|
|
|
67
85
|
'https://issuer.research.identiproof.io?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%22eyJhbGciOiJSU0Et...FYUaBy%22%7D%7D%7D';
|
|
68
86
|
const HTTPS_OFFER_QR_PRE_AUTHORIZED =
|
|
69
87
|
'https://issuer.research.identiproof.io?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D';
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22:%22https://issuer.research.identiproof.io%22,%22credential_configuration_ids%22:%5B%22OpenBadgeCredentialUrl%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,%22length%22:22,%22description%22:%22Please%20enter%20the%20serial%20number%20of%20your%20physical%20drivers%20license%22%7D%7D%7D%7D';
|
|
88
|
+
const HTTPS_OFFER_QR_PRE_AUTHORIZED_v13 =
|
|
89
|
+
'https://issuer.research.identiproof.io?credential_offer=%7B%0A%20%20%20%20%22credential_issuer%22%3A%20%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%0A%20%20%20%20%22credential_configuration_ids%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%22UniversityDegreeCredential%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22grants%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22pre-authorized_code%22%3A%20%22adhjhdjajkdkhjhdj%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22tx_code%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22length%22%3A%204%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22input_mode%22%3A%20%22numeric%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22description%22%3A%20%22Please%20provide%20the%20one-time%20code%20that%20was%20sent%20via%20e-mail%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D';
|
|
73
90
|
|
|
74
91
|
function succeedWithAFullFlowWithClientSetup() {
|
|
75
92
|
nock(IDENTIPROOF_ISSUER_URL).get('/.well-known/openid-credential-issuer').reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
|
|
76
93
|
nock(IDENTIPROOF_AS_URL).get('/.well-known/oauth-authorization-server').reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA));
|
|
77
94
|
nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {});
|
|
95
|
+
nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(200, {});
|
|
78
96
|
nock(IDENTIPROOF_AS_URL)
|
|
79
97
|
.post(/oauth2\/token.*/)
|
|
80
98
|
.reply(200, JSON.stringify(mockedAccessTokenResponse));
|
|
@@ -88,7 +106,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
88
106
|
|
|
89
107
|
it('succeed with a full flow with the client using OpenID4VCI version 9', async () => {
|
|
90
108
|
succeedWithAFullFlowWithClientSetup();
|
|
91
|
-
const client = await
|
|
109
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
92
110
|
uri: INITIATE_QR_V1_0_08,
|
|
93
111
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
94
112
|
alg: Alg.ES256,
|
|
@@ -99,7 +117,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
99
117
|
|
|
100
118
|
it('succeed with a full flow with the client using OpenID4VCI version 11 and deeplink', async () => {
|
|
101
119
|
succeedWithAFullFlowWithClientSetup();
|
|
102
|
-
const client = await
|
|
120
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
103
121
|
uri: OFFER_QR_V1_0_08,
|
|
104
122
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
105
123
|
alg: Alg.ES256,
|
|
@@ -110,7 +128,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
110
128
|
|
|
111
129
|
it('succeed with a full flow with the client using OpenID4VCI draft < 9 and https', async () => {
|
|
112
130
|
succeedWithAFullFlowWithClientSetup();
|
|
113
|
-
const client = await
|
|
131
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
114
132
|
uri: HTTPS_INITIATE_QR,
|
|
115
133
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
116
134
|
alg: Alg.ES256,
|
|
@@ -121,7 +139,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
121
139
|
|
|
122
140
|
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and authorization_code flow', async () => {
|
|
123
141
|
succeedWithAFullFlowWithClientSetup();
|
|
124
|
-
const client = await
|
|
142
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
125
143
|
uri: HTTPS_OFFER_QR_AUTHORIZATION_CODE,
|
|
126
144
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
127
145
|
alg: Alg.ES256,
|
|
@@ -132,7 +150,65 @@ describe('OID4VCI-Client should', () => {
|
|
|
132
150
|
|
|
133
151
|
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and preauthorized_code flow', async () => {
|
|
134
152
|
succeedWithAFullFlowWithClientSetup();
|
|
135
|
-
const client = await
|
|
153
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
154
|
+
uri: HTTPS_OFFER_QR_PRE_AUTHORIZED,
|
|
155
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
156
|
+
alg: Alg.ES256,
|
|
157
|
+
clientId: 'test-clientId',
|
|
158
|
+
});
|
|
159
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should succeed with a full flow with the client using OpenID4VCI draft >= 13, https and preauthorized_code flow without did', async () => {
|
|
163
|
+
nock(IDENTIPROOF_ISSUER_URL)
|
|
164
|
+
.get(WellKnownEndpoints.OPENID_CONFIGURATION)
|
|
165
|
+
.reply(200, {
|
|
166
|
+
token_endpoint: `${IDENTIPROOF_ISSUER_URL}/token`,
|
|
167
|
+
authorization_endpoint: `${IDENTIPROOF_ISSUER_URL}/authorize`,
|
|
168
|
+
});
|
|
169
|
+
nock(IDENTIPROOF_ISSUER_URL).post('/token').reply(200, {
|
|
170
|
+
access_token: 'ey6546.546654.64565',
|
|
171
|
+
authorization_pending: false,
|
|
172
|
+
c_nonce: 'c_nonce2022101300',
|
|
173
|
+
c_nonce_expires_in: 2025101300,
|
|
174
|
+
interval: 2025101300,
|
|
175
|
+
token_type: 'Bearer',
|
|
176
|
+
});
|
|
177
|
+
nock(IDENTIPROOF_ISSUER_URL).get('/.well-known/openid-credential-issuer').reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA_v13));
|
|
178
|
+
nock(ISSUER_URL)
|
|
179
|
+
.post(/credential/)
|
|
180
|
+
.reply(200, {
|
|
181
|
+
format: 'jwt-vc',
|
|
182
|
+
credential: mockedVC,
|
|
183
|
+
});
|
|
184
|
+
const client = await OpenID4VCIClientV1_0_13.fromURI({
|
|
185
|
+
uri: HTTPS_OFFER_QR_PRE_AUTHORIZED_v13,
|
|
186
|
+
kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
187
|
+
alg: Alg.ES256,
|
|
188
|
+
clientId: 'test-clientId',
|
|
189
|
+
});
|
|
190
|
+
expect(client.credentialOffer).toBeDefined();
|
|
191
|
+
expect(client.endpointMetadata).toBeDefined();
|
|
192
|
+
expect(client.getIssuer()).toEqual('https://issuer.research.identiproof.io');
|
|
193
|
+
expect(client.getCredentialEndpoint()).toEqual('https://issuer.research.identiproof.io/credential');
|
|
194
|
+
expect(client.getAccessTokenEndpoint()).toEqual('https://issuer.research.identiproof.io/token');
|
|
195
|
+
|
|
196
|
+
const accessToken = await client.acquireAccessToken({ pin: '1234', code: 'ABCD' });
|
|
197
|
+
expect(accessToken).toEqual(mockedAccessTokenResponse);
|
|
198
|
+
|
|
199
|
+
const credentialResponse = await client.acquireCredentials({
|
|
200
|
+
credentialIdentifier: 'OpenBadgeCredential',
|
|
201
|
+
format: 'jwt_vc_json-ld',
|
|
202
|
+
proofCallbacks: {
|
|
203
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
expect(credentialResponse.credential).toEqual(mockedVC);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and preauthorized_code flow', async () => {
|
|
210
|
+
succeedWithAFullFlowWithClientSetup();
|
|
211
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
136
212
|
uri: HTTPS_OFFER_QR_PRE_AUTHORIZED,
|
|
137
213
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
138
214
|
alg: Alg.ES256,
|
|
@@ -141,7 +217,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
141
217
|
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
142
218
|
});
|
|
143
219
|
|
|
144
|
-
async function assertionOfsucceedWithAFullFlowWithClient(client:
|
|
220
|
+
async function assertionOfsucceedWithAFullFlowWithClient(client: OpenID4VCIClient) {
|
|
145
221
|
expect(client.credentialOffer).toBeDefined();
|
|
146
222
|
expect(client.endpointMetadata).toBeDefined();
|
|
147
223
|
expect(client.getIssuer()).toEqual('https://issuer.research.identiproof.io');
|
|
@@ -165,7 +241,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
165
241
|
'succeed with a full flow without the client v1_0_11',
|
|
166
242
|
async () => {
|
|
167
243
|
/* Convert the URI into an object */
|
|
168
|
-
const credentialOffer: CredentialOfferRequestWithBaseUrl = await
|
|
244
|
+
const credentialOffer: CredentialOfferRequestWithBaseUrl = await CredentialOfferClient.fromURI(INITIATE_QR_V1_0_08);
|
|
169
245
|
|
|
170
246
|
expect(credentialOffer.baseUrl).toEqual('openid-initiate-issuance://');
|
|
171
247
|
expect(credentialOffer.original_credential_offer).toEqual({
|
|
@@ -191,18 +267,14 @@ describe('OID4VCI-Client should', () => {
|
|
|
191
267
|
format: 'jwt-vc',
|
|
192
268
|
credential: mockedVC,
|
|
193
269
|
});
|
|
194
|
-
const credReqClient =
|
|
270
|
+
const credReqClient = CredentialRequestClientBuilder.fromCredentialOffer({ credentialOffer: credentialOffer })
|
|
195
271
|
.withFormat('jwt_vc')
|
|
196
272
|
|
|
197
273
|
.withTokenFromResponse(accessTokenResponse.successBody!)
|
|
198
274
|
.build();
|
|
199
275
|
|
|
200
|
-
//TS2322: Type '(args: ProofOfPossessionCallbackArgs) => Promise<string>'
|
|
201
|
-
// is not assignable to type 'ProofOfPossessionCallback'.
|
|
202
|
-
// Types of parameters 'args' and 'args' are incompatible.
|
|
203
|
-
// Property 'kid' is missing in type '{ header: unknown; payload: unknown; }' but required in type 'ProofOfPossessionCallbackArgs'.
|
|
204
276
|
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
205
|
-
jwt,
|
|
277
|
+
jwt: jwtDid,
|
|
206
278
|
callbacks: {
|
|
207
279
|
signCallback: proofOfPossessionCallbackFunction,
|
|
208
280
|
},
|
|
@@ -261,12 +333,8 @@ describe('OID4VCI-Client should', () => {
|
|
|
261
333
|
.withTokenFromResponse(accessTokenResponse.successBody!)
|
|
262
334
|
.build();
|
|
263
335
|
|
|
264
|
-
//TS2322: Type '(args: ProofOfPossessionCallbackArgs) => Promise<string>'
|
|
265
|
-
// is not assignable to type 'ProofOfPossessionCallback'.
|
|
266
|
-
// Types of parameters 'args' and 'args' are incompatible.
|
|
267
|
-
// Property 'kid' is missing in type '{ header: unknown; payload: unknown; }' but required in type 'ProofOfPossessionCallbackArgs'.
|
|
268
336
|
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
269
|
-
jwt,
|
|
337
|
+
jwt: jwtDid,
|
|
270
338
|
callbacks: {
|
|
271
339
|
signCallback: proofOfPossessionCallbackFunction,
|
|
272
340
|
},
|
|
@@ -290,9 +358,6 @@ describe('OID4VCI-Client should', () => {
|
|
|
290
358
|
});
|
|
291
359
|
|
|
292
360
|
describe('OIDVCI-Client for v1_0_13 should', () => {
|
|
293
|
-
const INITIATE_QR_V1_0_13_CREDENCO =
|
|
294
|
-
'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';
|
|
295
|
-
|
|
296
361
|
const mockedCredentialOffer = {
|
|
297
362
|
credential_issuer: 'https://mijnkvk.acc.credenco.com',
|
|
298
363
|
credential_configuration_ids: ['BevoegdheidUittreksel_jwt_vc_json'],
|
|
@@ -320,21 +385,6 @@ describe('OIDVCI-Client for v1_0_13 should', () => {
|
|
|
320
385
|
nock.cleanAll();
|
|
321
386
|
});
|
|
322
387
|
|
|
323
|
-
/*function succeedWithAFullFlowWithClientSetup() {
|
|
324
|
-
nock(IDENTIPROOF_ISSUER_URL).get('/.well-known/openid-credential-issuer').reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
|
|
325
|
-
nock(IDENTIPROOF_AS_URL).get('/.well-known/oauth-authorization-server').reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA));
|
|
326
|
-
nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {});
|
|
327
|
-
nock(IDENTIPROOF_AS_URL)
|
|
328
|
-
.post(/oauth2\/token.*!/)
|
|
329
|
-
.reply(200, JSON.stringify(mockedAccessTokenResponse));
|
|
330
|
-
nock(ISSUER_URL)
|
|
331
|
-
.post(/credential/)
|
|
332
|
-
.reply(200, {
|
|
333
|
-
format: 'jwt-vc',
|
|
334
|
-
credential: mockedVC,
|
|
335
|
-
});
|
|
336
|
-
}*/
|
|
337
|
-
|
|
338
388
|
it('should successfully resolve the credential offer URI', async () => {
|
|
339
389
|
const uri = 'https://mijnkvk.acc.credenco.com/openid4vc/credentialOffer?id=32fc4ebf-9e31-4149-9877-e3c0b602d559';
|
|
340
390
|
|
|
@@ -343,78 +393,65 @@ describe('OIDVCI-Client for v1_0_13 should', () => {
|
|
|
343
393
|
expect(credentialOffer).toEqual(mockedCredentialOffer);
|
|
344
394
|
});
|
|
345
395
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
'succeed credenco with a full flow without the client v1_0_13',
|
|
396
|
+
it(
|
|
397
|
+
'succeed with a full flow without the client and without did',
|
|
349
398
|
async () => {
|
|
350
399
|
/* Convert the URI into an object */
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
367
|
-
'pre-authorized_code': preAuthorizedCode,
|
|
400
|
+
const credentialOffer: CredentialOfferRequestWithBaseUrl = await CredentialOfferClient.fromURI(INITIATE_QR_V1_0_13);
|
|
401
|
+
|
|
402
|
+
expect(credentialOffer.baseUrl).toEqual('openid-credential-offer://');
|
|
403
|
+
expect(credentialOffer.original_credential_offer).toEqual({
|
|
404
|
+
credential_configuration_ids: ['OpenBadgeCredentialUrl'],
|
|
405
|
+
credential_issuer: ISSUER_URL,
|
|
406
|
+
grants: {
|
|
407
|
+
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
408
|
+
'pre-authorized_code': 'oaKazRN8I0IbtZ0C7JuMn5',
|
|
409
|
+
tx_code: {
|
|
410
|
+
description: 'Please enter the serial number of your physical drivers license',
|
|
411
|
+
input_mode: 'text',
|
|
412
|
+
length: 22,
|
|
413
|
+
},
|
|
414
|
+
},
|
|
368
415
|
},
|
|
369
416
|
});
|
|
370
417
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
418
|
+
nock(ISSUER_URL)
|
|
419
|
+
.post(/token.*/)
|
|
420
|
+
.reply(200, JSON.stringify(mockedAccessTokenResponse));
|
|
374
421
|
|
|
375
422
|
/* The actual access token calls */
|
|
376
423
|
const accessTokenClient: AccessTokenClient = new AccessTokenClient();
|
|
377
|
-
const accessTokenResponse = await accessTokenClient.acquireAccessToken({
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
});
|
|
381
|
-
expect(accessTokenResponse.successBody).toEqual({});
|
|
382
|
-
/*// Get the credential
|
|
424
|
+
const accessTokenResponse = await accessTokenClient.acquireAccessToken({ credentialOffer: credentialOffer, pin: '1234' });
|
|
425
|
+
expect(accessTokenResponse.successBody).toEqual(mockedAccessTokenResponse);
|
|
426
|
+
// Get the credential
|
|
383
427
|
nock(ISSUER_URL)
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
428
|
+
.post(/credential/)
|
|
429
|
+
.reply(200, {
|
|
430
|
+
format: 'jwt-vc',
|
|
431
|
+
credential: mockedVC,
|
|
432
|
+
});
|
|
389
433
|
const credReqClient = CredentialRequestClientBuilder.fromCredentialOffer({ credentialOffer: credentialOffer })
|
|
390
|
-
|
|
434
|
+
.withFormat('jwt_vc')
|
|
391
435
|
|
|
392
|
-
|
|
393
|
-
|
|
436
|
+
.withTokenFromResponse(accessTokenResponse.successBody!)
|
|
437
|
+
.build();
|
|
394
438
|
|
|
395
|
-
//TS2322: Type '(args: ProofOfPossessionCallbackArgs) => Promise<string>'
|
|
396
|
-
// is not assignable to type 'ProofOfPossessionCallback'.
|
|
397
|
-
// Types of parameters 'args' and 'args' are incompatible.
|
|
398
|
-
// Property 'kid' is missing in type '{ header: unknown; payload: unknown; }' but required in type 'ProofOfPossessionCallbackArgs'.
|
|
399
439
|
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
400
|
-
jwt,
|
|
440
|
+
jwt: jwtWithoutDid,
|
|
401
441
|
callbacks: {
|
|
402
442
|
signCallback: proofOfPossessionCallbackFunction,
|
|
403
443
|
},
|
|
404
|
-
version: OpenId4VCIVersion.
|
|
405
|
-
})
|
|
406
|
-
.withEndpointMetadata({
|
|
407
|
-
issuer: 'https://issuer.research.identiproof.io',
|
|
408
|
-
credential_endpoint: 'https://issuer.research.identiproof.io/credential',
|
|
409
|
-
token_endpoint: 'https://issuer.research.identiproof.io/token',
|
|
444
|
+
version: OpenId4VCIVersion.VER_1_0_13,
|
|
410
445
|
})
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
446
|
+
.withEndpointMetadata({
|
|
447
|
+
issuer: 'https://issuer.research.identiproof.io',
|
|
448
|
+
credential_endpoint: 'https://issuer.research.identiproof.io/credential',
|
|
449
|
+
token_endpoint: 'https://issuer.research.identiproof.io/token',
|
|
450
|
+
})
|
|
451
|
+
.withKid('ebfeb1f712ebc6f1c276e12ec21/keys/1')
|
|
452
|
+
.build();
|
|
453
|
+
const credResponse = await credReqClient.acquireCredentialsUsingProof({ proofInput: proof, credentialIdentifier: 'OpenBadgeCredentialUrl' });
|
|
454
|
+
expect(credResponse.successBody?.credential).toEqual(mockedVC);
|
|
418
455
|
},
|
|
419
456
|
UNIT_TEST_TIMEOUT,
|
|
420
457
|
);
|
|
@@ -127,6 +127,41 @@ export const IDENTIPROOF_OID4VCI_METADATA = {
|
|
|
127
127
|
},
|
|
128
128
|
},
|
|
129
129
|
};
|
|
130
|
+
export const IDENTIPROOF_OID4VCI_METADATA_v13 = {
|
|
131
|
+
issuer: 'https://issuer.research.identiproof.io',
|
|
132
|
+
authorization_server: 'https://auth.research.identiproof.io',
|
|
133
|
+
credential_endpoint: 'https://issuer.research.identiproof.io/credential',
|
|
134
|
+
jwks_uri: 'https://issuer.research.identiproof.io/.well-known/did.json',
|
|
135
|
+
credential_configurations_supported: {
|
|
136
|
+
'Cyber Security Certificate': {
|
|
137
|
+
formats: {
|
|
138
|
+
jwt_vc: {
|
|
139
|
+
types: ['VerifiableCredential', 'Cyber Security Certificate'],
|
|
140
|
+
cryptographic_binding_methods_supported: ['did'],
|
|
141
|
+
cryptographic_suites_supported: ['ES256'],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
OpenBadgeCredential: {
|
|
146
|
+
formats: {
|
|
147
|
+
jwt_vc: {
|
|
148
|
+
types: ['VerifiableCredential', 'OpenBadgeCredential'],
|
|
149
|
+
cryptographic_binding_methods_supported: ['did'],
|
|
150
|
+
cryptographic_suites_supported: ['ES256'],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
OpenBadgeExtendedCredential: {
|
|
155
|
+
formats: {
|
|
156
|
+
jwt_vc: {
|
|
157
|
+
types: ['VerifiableCredential', 'OpenBadgeExtendedCredential'],
|
|
158
|
+
cryptographic_binding_methods_supported: ['did'],
|
|
159
|
+
cryptographic_suites_supported: ['ES256'],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
};
|
|
130
165
|
|
|
131
166
|
export const SPRUCE_OID4VCI_METADATA = {
|
|
132
167
|
issuer: 'https://ngi-oidc4vci-test.spruceid.xyz',
|