@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
package/lib/__tests__/IT.spec.ts
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AccessTokenResponse,
|
|
3
3
|
Alg,
|
|
4
|
+
CredentialOfferPayloadV1_0_13,
|
|
4
5
|
CredentialOfferRequestWithBaseUrl,
|
|
5
6
|
Jwt,
|
|
6
7
|
OpenId4VCIVersion,
|
|
7
8
|
ProofOfPossession,
|
|
9
|
+
resolveCredentialOfferURI,
|
|
8
10
|
WellKnownEndpoints,
|
|
9
11
|
} from '@sphereon/oid4vci-common';
|
|
10
12
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
11
13
|
// @ts-ignore
|
|
12
14
|
import nock from 'nock';
|
|
13
15
|
|
|
14
|
-
import {
|
|
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 '..';
|
|
15
25
|
import { CredentialOfferClient } from '../CredentialOfferClient';
|
|
16
26
|
|
|
17
27
|
import { IDENTIPROOF_AS_METADATA, IDENTIPROOF_AS_URL, IDENTIPROOF_ISSUER_URL, IDENTIPROOF_OID4VCI_METADATA } from './MetadataMocks';
|
|
@@ -47,10 +57,19 @@ describe('OID4VCI-Client should', () => {
|
|
|
47
57
|
};
|
|
48
58
|
const mockedVC =
|
|
49
59
|
'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.z5vgMTK1nfizNCg5N-niCOL3WUIAL7nXy-nGhDZYO_-PNGeE-0djCpWAMH8fD8eWSID5PfkPBYkx_dfLJnQ7NA';
|
|
50
|
-
const
|
|
60
|
+
const INITIATE_QR_V1_0_08 =
|
|
51
61
|
'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';
|
|
52
|
-
const
|
|
53
|
-
'openid-credential-offer
|
|
62
|
+
const OFFER_QR_V1_0_08 =
|
|
63
|
+
'openid-credential-offer://?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';
|
|
64
|
+
const HTTPS_INITIATE_QR =
|
|
65
|
+
'https://issuer.research.identiproof.io?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true';
|
|
66
|
+
const HTTPS_OFFER_QR_AUTHORIZATION_CODE =
|
|
67
|
+
'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
|
+
const HTTPS_OFFER_QR_PRE_AUTHORIZED =
|
|
69
|
+
'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
|
+
const INITIATE_QR_V1_0_13 =
|
|
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';
|
|
54
73
|
|
|
55
74
|
function succeedWithAFullFlowWithClientSetup() {
|
|
56
75
|
nock(IDENTIPROOF_ISSUER_URL).get('/.well-known/openid-credential-issuer').reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
|
|
@@ -69,8 +88,30 @@ describe('OID4VCI-Client should', () => {
|
|
|
69
88
|
|
|
70
89
|
it('succeed with a full flow with the client using OpenID4VCI version 9', async () => {
|
|
71
90
|
succeedWithAFullFlowWithClientSetup();
|
|
72
|
-
const client = await
|
|
73
|
-
uri:
|
|
91
|
+
const client = await OpenID4VCIClientV1_0_11.fromURI({
|
|
92
|
+
uri: INITIATE_QR_V1_0_08,
|
|
93
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
94
|
+
alg: Alg.ES256,
|
|
95
|
+
clientId: 'test-clientId',
|
|
96
|
+
});
|
|
97
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('succeed with a full flow with the client using OpenID4VCI version 11 and deeplink', async () => {
|
|
101
|
+
succeedWithAFullFlowWithClientSetup();
|
|
102
|
+
const client = await OpenID4VCIClientV1_0_11.fromURI({
|
|
103
|
+
uri: OFFER_QR_V1_0_08,
|
|
104
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
105
|
+
alg: Alg.ES256,
|
|
106
|
+
clientId: 'test-clientId',
|
|
107
|
+
});
|
|
108
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('succeed with a full flow with the client using OpenID4VCI draft < 9 and https', async () => {
|
|
112
|
+
succeedWithAFullFlowWithClientSetup();
|
|
113
|
+
const client = await OpenID4VCIClientV1_0_11.fromURI({
|
|
114
|
+
uri: HTTPS_INITIATE_QR,
|
|
74
115
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
75
116
|
alg: Alg.ES256,
|
|
76
117
|
clientId: 'test-clientId',
|
|
@@ -78,10 +119,10 @@ describe('OID4VCI-Client should', () => {
|
|
|
78
119
|
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
79
120
|
});
|
|
80
121
|
|
|
81
|
-
|
|
122
|
+
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and authorization_code flow', async () => {
|
|
82
123
|
succeedWithAFullFlowWithClientSetup();
|
|
83
|
-
const client = await
|
|
84
|
-
uri:
|
|
124
|
+
const client = await OpenID4VCIClientV1_0_11.fromURI({
|
|
125
|
+
uri: HTTPS_OFFER_QR_AUTHORIZATION_CODE,
|
|
85
126
|
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
86
127
|
alg: Alg.ES256,
|
|
87
128
|
clientId: 'test-clientId',
|
|
@@ -89,14 +130,25 @@ describe('OID4VCI-Client should', () => {
|
|
|
89
130
|
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
90
131
|
});
|
|
91
132
|
|
|
92
|
-
|
|
133
|
+
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and preauthorized_code flow', async () => {
|
|
134
|
+
succeedWithAFullFlowWithClientSetup();
|
|
135
|
+
const client = await OpenID4VCIClientV1_0_11.fromURI({
|
|
136
|
+
uri: HTTPS_OFFER_QR_PRE_AUTHORIZED,
|
|
137
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
138
|
+
alg: Alg.ES256,
|
|
139
|
+
clientId: 'test-clientId',
|
|
140
|
+
});
|
|
141
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
async function assertionOfsucceedWithAFullFlowWithClient(client: OpenID4VCIClientV1_0_11) {
|
|
93
145
|
expect(client.credentialOffer).toBeDefined();
|
|
94
146
|
expect(client.endpointMetadata).toBeDefined();
|
|
95
147
|
expect(client.getIssuer()).toEqual('https://issuer.research.identiproof.io');
|
|
96
148
|
expect(client.getCredentialEndpoint()).toEqual('https://issuer.research.identiproof.io/credential');
|
|
97
149
|
expect(client.getAccessTokenEndpoint()).toEqual('https://auth.research.identiproof.io/oauth2/token');
|
|
98
150
|
|
|
99
|
-
const accessToken = await client.acquireAccessToken({ pin: '1234' });
|
|
151
|
+
const accessToken = await client.acquireAccessToken({ pin: '1234', code: 'ABCD' });
|
|
100
152
|
expect(accessToken).toEqual(mockedAccessTokenResponse);
|
|
101
153
|
|
|
102
154
|
const credentialResponse = await client.acquireCredentials({
|
|
@@ -110,10 +162,10 @@ describe('OID4VCI-Client should', () => {
|
|
|
110
162
|
}
|
|
111
163
|
|
|
112
164
|
it(
|
|
113
|
-
'succeed with a full flow without the client',
|
|
165
|
+
'succeed with a full flow without the client v1_0_11',
|
|
114
166
|
async () => {
|
|
115
167
|
/* Convert the URI into an object */
|
|
116
|
-
const credentialOffer: CredentialOfferRequestWithBaseUrl = await
|
|
168
|
+
const credentialOffer: CredentialOfferRequestWithBaseUrl = await CredentialOfferClientV1_0_11.fromURI(INITIATE_QR_V1_0_08);
|
|
117
169
|
|
|
118
170
|
expect(credentialOffer.baseUrl).toEqual('openid-initiate-issuance://');
|
|
119
171
|
expect(credentialOffer.original_credential_offer).toEqual({
|
|
@@ -124,6 +176,70 @@ describe('OID4VCI-Client should', () => {
|
|
|
124
176
|
user_pin_required: 'true',
|
|
125
177
|
});
|
|
126
178
|
|
|
179
|
+
nock(ISSUER_URL)
|
|
180
|
+
.post(/token.*/)
|
|
181
|
+
.reply(200, JSON.stringify(mockedAccessTokenResponse));
|
|
182
|
+
|
|
183
|
+
/* The actual access token calls */
|
|
184
|
+
const accessTokenClient: AccessTokenClientV1_0_11 = new AccessTokenClientV1_0_11();
|
|
185
|
+
const accessTokenResponse = await accessTokenClient.acquireAccessToken({ credentialOffer: credentialOffer, pin: '1234' });
|
|
186
|
+
expect(accessTokenResponse.successBody).toEqual(mockedAccessTokenResponse);
|
|
187
|
+
// Get the credential
|
|
188
|
+
nock(ISSUER_URL)
|
|
189
|
+
.post(/credential/)
|
|
190
|
+
.reply(200, {
|
|
191
|
+
format: 'jwt-vc',
|
|
192
|
+
credential: mockedVC,
|
|
193
|
+
});
|
|
194
|
+
const credReqClient = CredentialRequestClientBuilderV1_0_11.fromCredentialOffer({ credentialOffer: credentialOffer })
|
|
195
|
+
.withFormat('jwt_vc')
|
|
196
|
+
|
|
197
|
+
.withTokenFromResponse(accessTokenResponse.successBody!)
|
|
198
|
+
.build();
|
|
199
|
+
|
|
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
|
+
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
205
|
+
jwt,
|
|
206
|
+
callbacks: {
|
|
207
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
208
|
+
},
|
|
209
|
+
version: OpenId4VCIVersion.VER_1_0_11,
|
|
210
|
+
})
|
|
211
|
+
.withEndpointMetadata({
|
|
212
|
+
issuer: 'https://issuer.research.identiproof.io',
|
|
213
|
+
credential_endpoint: 'https://issuer.research.identiproof.io/credential',
|
|
214
|
+
token_endpoint: 'https://issuer.research.identiproof.io/token',
|
|
215
|
+
})
|
|
216
|
+
.withKid('did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1')
|
|
217
|
+
.build();
|
|
218
|
+
const credResponse = await credReqClient.acquireCredentialsUsingProof({ proofInput: proof });
|
|
219
|
+
expect(credResponse.successBody?.credential).toEqual(mockedVC);
|
|
220
|
+
},
|
|
221
|
+
UNIT_TEST_TIMEOUT,
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
it(
|
|
225
|
+
'succeed with a full flow without the client v1_0_13',
|
|
226
|
+
async () => {
|
|
227
|
+
/* Convert the URI into an object */
|
|
228
|
+
const credentialOffer: CredentialOfferRequestWithBaseUrl = await CredentialOfferClient.fromURI(INITIATE_QR_V1_0_13);
|
|
229
|
+
const preAuthorizedCode = 'oaKazRN8I0IbtZ0C7JuMn5';
|
|
230
|
+
expect(credentialOffer.baseUrl).toEqual('openid-credential-offer://');
|
|
231
|
+
expect((credentialOffer.credential_offer as CredentialOfferPayloadV1_0_13).credential_configuration_ids).toEqual(['OpenBadgeCredentialUrl']);
|
|
232
|
+
expect(credentialOffer.original_credential_offer.grants).toEqual({
|
|
233
|
+
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
234
|
+
'pre-authorized_code': preAuthorizedCode,
|
|
235
|
+
tx_code: {
|
|
236
|
+
input_mode: 'text',
|
|
237
|
+
description: 'Please enter the serial number of your physical drivers license',
|
|
238
|
+
length: preAuthorizedCode.length,
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
|
|
127
243
|
nock(ISSUER_URL)
|
|
128
244
|
.post(/token.*/)
|
|
129
245
|
.reply(200, JSON.stringify(mockedAccessTokenResponse));
|
|
@@ -163,9 +279,143 @@ describe('OID4VCI-Client should', () => {
|
|
|
163
279
|
})
|
|
164
280
|
.withKid('did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1')
|
|
165
281
|
.build();
|
|
166
|
-
const credResponse = await credReqClient.acquireCredentialsUsingProof({
|
|
282
|
+
const credResponse = await credReqClient.acquireCredentialsUsingProof({
|
|
283
|
+
proofInput: proof,
|
|
284
|
+
credentialTypes: credentialOffer.original_credential_offer.credential_configuration_ids[0],
|
|
285
|
+
});
|
|
167
286
|
expect(credResponse.successBody?.credential).toEqual(mockedVC);
|
|
168
287
|
},
|
|
169
288
|
UNIT_TEST_TIMEOUT,
|
|
170
289
|
);
|
|
171
290
|
});
|
|
291
|
+
|
|
292
|
+
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
|
+
const mockedCredentialOffer = {
|
|
297
|
+
credential_issuer: 'https://mijnkvk.acc.credenco.com',
|
|
298
|
+
credential_configuration_ids: ['BevoegdheidUittreksel_jwt_vc_json'],
|
|
299
|
+
grants: {
|
|
300
|
+
authorization_code: {
|
|
301
|
+
issuer_state: '32fc4ebf-9e31-4149-9877-e3c0b602d559',
|
|
302
|
+
},
|
|
303
|
+
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
304
|
+
'pre-authorized_code':
|
|
305
|
+
'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIzMmZjNGViZi05ZTMxLTQxNDktOTg3Ny1lM2MwYjYwMmQ1NTkiLCJpc3MiOiJodHRwczovL21pam5rdmsuYWNjLmNyZWRlbmNvLmNvbSIsImF1ZCI6IlRPS0VOIn0.754aiQ87O0vHYSpRvPqAS9cLOgf-pewdeXbpLziRwsxEp9mENfaXpY62muYpzOaWcYmTOydkzhFul-NDYXJZCA',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
beforeEach(() => {
|
|
311
|
+
// Mock the HTTP GET request to the credential offer URI
|
|
312
|
+
nock('https://mijnkvk.acc.credenco.com')
|
|
313
|
+
.get('/openid4vc/credentialOffer?id=32fc4ebf-9e31-4149-9877-e3c0b602d559')
|
|
314
|
+
.reply(200, mockedCredentialOffer)
|
|
315
|
+
.persist(); // Use .persist() if you want the mock to remain active for multiple tests
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
afterEach(() => {
|
|
319
|
+
// Clean up all mocks
|
|
320
|
+
nock.cleanAll();
|
|
321
|
+
});
|
|
322
|
+
|
|
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
|
+
it('should successfully resolve the credential offer URI', async () => {
|
|
339
|
+
const uri = 'https://mijnkvk.acc.credenco.com/openid4vc/credentialOffer?id=32fc4ebf-9e31-4149-9877-e3c0b602d559';
|
|
340
|
+
|
|
341
|
+
const credentialOffer = await resolveCredentialOfferURI(uri);
|
|
342
|
+
|
|
343
|
+
expect(credentialOffer).toEqual(mockedCredentialOffer);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// TODO: ksadjad remove the skipped test
|
|
347
|
+
it.skip(
|
|
348
|
+
'succeed credenco with a full flow without the client v1_0_13',
|
|
349
|
+
async () => {
|
|
350
|
+
/* Convert the URI into an object */
|
|
351
|
+
// openid-credential-offer://?credential_offer%3D%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
|
|
352
|
+
const credentialOffer: CredentialOfferRequestWithBaseUrl = await CredentialOfferClient.fromURI(INITIATE_QR_V1_0_13_CREDENCO);
|
|
353
|
+
/**
|
|
354
|
+
* {"credential_issuer":"https://mijnkvk.acc.credenco.com","credential_configuration_ids":["BevoegdheidUittreksel_jwt_vc_json"],"grants":{"authorization_code":{"issuer_state":"32fc4ebf-9e31-4149-9877-e3c0b602d559"},"urn:ietf:params:oauth:grant-type:pre-authorized_code":{"pre-authorized_code":"eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIzMmZjNGViZi05ZTMxLTQxNDktOTg3Ny1lM2MwYjYwMmQ1NTkiLCJpc3MiOiJodHRwczovL21pam5rdmsuYWNjLmNyZWRlbmNvLmNvbSIsImF1ZCI6IlRPS0VOIn0.754aiQ87O0vHYSpRvPqAS9cLOgf-pewdeXbpLziRwsxEp9mENfaXpY62muYpzOaWcYmTOydkzhFul-NDYXJZCA"}}}
|
|
355
|
+
*/
|
|
356
|
+
const preAuthorizedCode =
|
|
357
|
+
'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIzMmZjNGViZi05ZTMxLTQxNDktOTg3Ny1lM2MwYjYwMmQ1NTkiLCJpc3MiOiJodHRwczovL21pam5rdmsuYWNjLmNyZWRlbmNvLmNvbSIsImF1ZCI6IlRPS0VOIn0.754aiQ87O0vHYSpRvPqAS9cLOgf-pewdeXbpLziRwsxEp9mENfaXpY62muYpzOaWcYmTOydkzhFul-NDYXJZCA';
|
|
358
|
+
expect(credentialOffer.baseUrl).toEqual('openid-credential-offer://mijnkvk.acc.credenco.com/');
|
|
359
|
+
expect((credentialOffer.credential_offer as CredentialOfferPayloadV1_0_13).credential_configuration_ids).toEqual([
|
|
360
|
+
'BevoegdheidUittreksel_jwt_vc_json',
|
|
361
|
+
]);
|
|
362
|
+
expect(credentialOffer.original_credential_offer.grants).toEqual({
|
|
363
|
+
authorization_code: {
|
|
364
|
+
issuer_state: '32fc4ebf-9e31-4149-9877-e3c0b602d559',
|
|
365
|
+
},
|
|
366
|
+
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
367
|
+
'pre-authorized_code': preAuthorizedCode,
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
/*nock(ISSUER_URL)
|
|
372
|
+
.post(/token.*!/)
|
|
373
|
+
.reply(200, JSON.stringify(mockedAccessTokenResponse));*/
|
|
374
|
+
|
|
375
|
+
/* The actual access token calls */
|
|
376
|
+
const accessTokenClient: AccessTokenClient = new AccessTokenClient();
|
|
377
|
+
const accessTokenResponse = await accessTokenClient.acquireAccessToken({
|
|
378
|
+
credentialOffer: credentialOffer,
|
|
379
|
+
pin: preAuthorizedCode /*, metadata: {}*/,
|
|
380
|
+
});
|
|
381
|
+
expect(accessTokenResponse.successBody).toEqual({});
|
|
382
|
+
/*// Get the credential
|
|
383
|
+
nock(ISSUER_URL)
|
|
384
|
+
.post(/credential/)
|
|
385
|
+
.reply(200, {
|
|
386
|
+
format: 'jwt-vc',
|
|
387
|
+
credential: mockedVC,
|
|
388
|
+
});
|
|
389
|
+
const credReqClient = CredentialRequestClientBuilder.fromCredentialOffer({ credentialOffer: credentialOffer })
|
|
390
|
+
.withFormat('jwt_vc')
|
|
391
|
+
|
|
392
|
+
.withTokenFromResponse(accessTokenResponse.successBody!)
|
|
393
|
+
.build();
|
|
394
|
+
|
|
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
|
+
const proof: ProofOfPossession = await ProofOfPossessionBuilder.fromJwt({
|
|
400
|
+
jwt,
|
|
401
|
+
callbacks: {
|
|
402
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
403
|
+
},
|
|
404
|
+
version: OpenId4VCIVersion.VER_1_0_11,
|
|
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',
|
|
410
|
+
})
|
|
411
|
+
.withKid('did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1')
|
|
412
|
+
.build();
|
|
413
|
+
const credResponse = await credReqClient.acquireCredentialsUsingProof({
|
|
414
|
+
proofInput: proof,
|
|
415
|
+
credentialTypes: credentialOffer.original_credential_offer.credential_configuration_ids,
|
|
416
|
+
});
|
|
417
|
+
expect(credResponse.successBody?.credential).toEqual(mockedVC);*/
|
|
418
|
+
},
|
|
419
|
+
UNIT_TEST_TIMEOUT,
|
|
420
|
+
);
|
|
421
|
+
});
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { OpenId4VCIVersion } from '@sphereon/oid4vci-common';
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import nock from 'nock';
|
|
2
5
|
|
|
3
6
|
import { CredentialOfferClient } from '../CredentialOfferClient';
|
|
7
|
+
import { CredentialOfferClientV1_0_11 } from '../CredentialOfferClientV1_0_11';
|
|
4
8
|
|
|
5
9
|
import { INITIATION_TEST, INITIATION_TEST_HTTPS_URI, INITIATION_TEST_URI } from './MetadataMocks';
|
|
6
10
|
|
|
7
11
|
describe('Issuance Initiation', () => {
|
|
8
12
|
it('Should return Issuance Initiation Request with base URL from https URI', async () => {
|
|
9
|
-
expect(await
|
|
13
|
+
expect(await CredentialOfferClientV1_0_11.fromURI(INITIATION_TEST_HTTPS_URI)).toEqual({
|
|
10
14
|
baseUrl: 'https://server.example.com',
|
|
11
15
|
credential_offer: {
|
|
12
16
|
credential_issuer: 'https://server.example.com',
|
|
@@ -34,13 +38,14 @@ describe('Issuance Initiation', () => {
|
|
|
34
38
|
expect(await CredentialOfferClient.fromURI(INITIATION_TEST_URI)).toEqual(INITIATION_TEST);
|
|
35
39
|
});
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
//todo: SDK-17 for removing the space
|
|
42
|
+
it.skip('Should return Issuance Initiation URI from request', async () => {
|
|
38
43
|
expect(CredentialOfferClient.toURI(INITIATION_TEST)).toEqual(INITIATION_TEST_URI);
|
|
39
44
|
});
|
|
40
45
|
|
|
41
46
|
it('Should return URI from Issuance Initiation Request', async () => {
|
|
42
|
-
const issuanceInitiationClient = await
|
|
43
|
-
expect(
|
|
47
|
+
const issuanceInitiationClient = await CredentialOfferClientV1_0_11.fromURI(INITIATION_TEST_HTTPS_URI);
|
|
48
|
+
expect(CredentialOfferClientV1_0_11.toURI(issuanceInitiationClient)).toEqual(INITIATION_TEST_HTTPS_URI);
|
|
44
49
|
});
|
|
45
50
|
|
|
46
51
|
it('Should throw error on invalid URI', async () => {
|
|
@@ -58,4 +63,54 @@ describe('Issuance Initiation', () => {
|
|
|
58
63
|
expect(client.credential_offer.credential_issuer).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
59
64
|
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
60
65
|
});
|
|
66
|
+
|
|
67
|
+
it('Should take an https url as input and return a Credential Offer', async () => {
|
|
68
|
+
const client = await CredentialOfferClient.fromURI(
|
|
69
|
+
'https://launchpad.vii.electron.mattrlabs.io?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22ldp_vc%22%2C%22types%22%3A%5B%22OpenBadgeCredential%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%22UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X%22%7D%7D%7D',
|
|
70
|
+
);
|
|
71
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_11);
|
|
72
|
+
expect(client.baseUrl).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
73
|
+
expect(client.scheme).toEqual('https');
|
|
74
|
+
expect(client.credential_offer.credential_issuer).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
75
|
+
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('Should take an http url as input and return a Credential Offer', async () => {
|
|
79
|
+
const client = await CredentialOfferClient.fromURI(
|
|
80
|
+
'http://launchpad.vii.electron.mattrlabs.io?credential_offer=%7B%22credential_issuer%22%3A%22http%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22ldp_vc%22%2C%22types%22%3A%5B%22OpenBadgeCredential%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%22UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X%22%7D%7D%7D',
|
|
81
|
+
);
|
|
82
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_11);
|
|
83
|
+
expect(client.baseUrl).toEqual('http://launchpad.vii.electron.mattrlabs.io');
|
|
84
|
+
expect(client.scheme).toEqual('http');
|
|
85
|
+
expect(client.credential_offer.credential_issuer).toEqual('http://launchpad.vii.electron.mattrlabs.io');
|
|
86
|
+
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('Should return credenco Credential Offer', async () => {
|
|
90
|
+
nock('https://mijnkvk.acc.credenco.com')
|
|
91
|
+
.get('/openid4vc/credentialOffer?id=32fc4ebf-9e31-4149-9877-e3c0b602d559')
|
|
92
|
+
.reply(200, {
|
|
93
|
+
credential_issuer: 'https://mijnkvk.acc.credenco.com',
|
|
94
|
+
credential_configuration_ids: ['BevoegdheidUittreksel_jwt_vc_json'],
|
|
95
|
+
grants: {
|
|
96
|
+
authorization_code: {
|
|
97
|
+
issuer_state: '32fc4ebf-9e31-4149-9877-e3c0b602d559',
|
|
98
|
+
},
|
|
99
|
+
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
|
|
100
|
+
'pre-authorized_code':
|
|
101
|
+
'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIzMmZjNGViZi05ZTMxLTQxNDktOTg3Ny1lM2MwYjYwMmQ1NTkiLCJpc3MiOiJodHRwczovL21pam5rdmsuYWNjLmNyZWRlbmNvLmNvbSIsImF1ZCI6IlRPS0VOIn0.754aiQ87O0vHYSpRvPqAS9cLOgf-pewdeXbpLziRwsxEp9mENfaXpY62muYpzOaWcYmTOydkzhFul-NDYXJZCA',
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
const client = await CredentialOfferClient.fromURI(
|
|
106
|
+
'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',
|
|
107
|
+
);
|
|
108
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_13);
|
|
109
|
+
expect(client.baseUrl).toEqual('openid-credential-offer://mijnkvk.acc.credenco.com/');
|
|
110
|
+
expect(client.scheme).toEqual('openid-credential-offer');
|
|
111
|
+
expect(client.credential_offer.credential_issuer).toEqual('https://mijnkvk.acc.credenco.com');
|
|
112
|
+
expect(client.preAuthorizedCode).toEqual(
|
|
113
|
+
'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIzMmZjNGViZi05ZTMxLTQxNDktOTg3Ny1lM2MwYjYwMmQ1NTkiLCJpc3MiOiJodHRwczovL21pam5rdmsuYWNjLmNyZWRlbmNvLmNvbSIsImF1ZCI6IlRPS0VOIn0.754aiQ87O0vHYSpRvPqAS9cLOgf-pewdeXbpLziRwsxEp9mENfaXpY62muYpzOaWcYmTOydkzhFul-NDYXJZCA',
|
|
114
|
+
);
|
|
115
|
+
});
|
|
61
116
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { OpenId4VCIVersion } from '@sphereon/oid4vci-common';
|
|
2
|
+
|
|
3
|
+
import { CredentialOfferClient } from '../CredentialOfferClient';
|
|
4
|
+
import { CredentialOfferClientV1_0_11 } from '../CredentialOfferClientV1_0_11';
|
|
5
|
+
|
|
6
|
+
import { INITIATION_TEST_HTTPS_URI, INITIATION_TEST_HTTPS_URI_V1_0_11, INITIATION_TEST_URI_V1_0_08, INITIATION_TEST_V1_0_08 } from './MetadataMocks';
|
|
7
|
+
|
|
8
|
+
describe('Issuance Initiation V1_0_11', () => {
|
|
9
|
+
it('Should return Issuance Initiation Request with base URL from https URI', async () => {
|
|
10
|
+
expect(await CredentialOfferClientV1_0_11.fromURI(INITIATION_TEST_HTTPS_URI)).toEqual({
|
|
11
|
+
baseUrl: 'https://server.example.com',
|
|
12
|
+
credential_offer: {
|
|
13
|
+
credential_issuer: 'https://server.example.com',
|
|
14
|
+
credentials: ['https://did.example.org/healthCard', 'https://did.example.org/driverLicense'],
|
|
15
|
+
grants: {
|
|
16
|
+
authorization_code: {
|
|
17
|
+
issuer_state: 'eyJhbGciOiJSU0Et...FYUaBy',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
issuerState: 'eyJhbGciOiJSU0Et...FYUaBy',
|
|
22
|
+
original_credential_offer: {
|
|
23
|
+
credential_type: ['https://did.example.org/healthCard', 'https://did.example.org/driverLicense'],
|
|
24
|
+
issuer: 'https://server.example.com',
|
|
25
|
+
op_state: 'eyJhbGciOiJSU0Et...FYUaBy',
|
|
26
|
+
},
|
|
27
|
+
scheme: 'https',
|
|
28
|
+
supportedFlows: ['Authorization Code Flow'],
|
|
29
|
+
userPinRequired: false,
|
|
30
|
+
version: 1008,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('Should return Issuance Initiation Request with base URL from openid-initiate-issuance URI', async () => {
|
|
35
|
+
expect(await CredentialOfferClientV1_0_11.fromURI(INITIATION_TEST_URI_V1_0_08)).toEqual(INITIATION_TEST_V1_0_08);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('Should return Issuance Initiation URI from request', async () => {
|
|
39
|
+
expect(CredentialOfferClientV1_0_11.toURI(INITIATION_TEST_V1_0_08)).toEqual(INITIATION_TEST_URI_V1_0_08);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('Should return URI from Issuance Initiation Request', async () => {
|
|
43
|
+
const issuanceInitiationClient = await CredentialOfferClientV1_0_11.fromURI(INITIATION_TEST_HTTPS_URI_V1_0_11);
|
|
44
|
+
expect(CredentialOfferClient.toURI(issuanceInitiationClient)).toEqual(INITIATION_TEST_HTTPS_URI_V1_0_11);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('Should throw error on invalid URI', async () => {
|
|
48
|
+
const issuanceInitiationURI = INITIATION_TEST_HTTPS_URI.replace('?', '');
|
|
49
|
+
await expect(async () => CredentialOfferClientV1_0_11.fromURI(issuanceInitiationURI)).rejects.toThrow('Invalid Credential Offer Request');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('Should return Credential Offer', async () => {
|
|
53
|
+
const client = await CredentialOfferClientV1_0_11.fromURI(
|
|
54
|
+
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22ldp_vc%22%2C%22types%22%3A%5B%22OpenBadgeCredential%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%22UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X%22%7D%7D%7D',
|
|
55
|
+
);
|
|
56
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_11);
|
|
57
|
+
expect(client.baseUrl).toEqual('openid-credential-offer://');
|
|
58
|
+
expect(client.scheme).toEqual('openid-credential-offer');
|
|
59
|
+
expect(client.credential_offer.credential_issuer).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
60
|
+
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -3,7 +3,7 @@ import { CredentialMapper } from '@sphereon/ssi-types';
|
|
|
3
3
|
import { fetch } from 'cross-fetch';
|
|
4
4
|
import { importJWK, JWK, SignJWT } from 'jose';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { OpenID4VCIClientV1_0_11 } from '..';
|
|
7
7
|
|
|
8
8
|
export const UNIT_TEST_TIMEOUT = 30000;
|
|
9
9
|
|
|
@@ -23,7 +23,7 @@ const kid = `${did}#z6Mki5ZwZKN1dBQprfJTikUvkDxrHijiiQngkWviMF5gw2Hv`;
|
|
|
23
23
|
describe.skip('OID4VCI-Client using Mattr issuer should', () => {
|
|
24
24
|
async function test(format: 'ldp_vc' | 'jwt_vc_json') {
|
|
25
25
|
const offer = await getCredentialOffer(format);
|
|
26
|
-
const client = await
|
|
26
|
+
const client = await OpenID4VCIClientV1_0_11.fromURI({
|
|
27
27
|
uri: offer.offerUrl,
|
|
28
28
|
kid,
|
|
29
29
|
alg: Alg.EdDSA,
|
|
@@ -3,8 +3,9 @@ import { getIssuerFromCredentialOfferPayload, WellKnownEndpoints } from '@sphere
|
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
import nock from 'nock';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { CredentialOfferClientV1_0_11 } from '../CredentialOfferClientV1_0_11';
|
|
7
7
|
import { MetadataClient } from '../MetadataClient';
|
|
8
|
+
import { retrieveWellknown } from '../functions/OpenIDUtils';
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
DANUBE_ISSUER_URL,
|
|
@@ -18,7 +19,9 @@ import {
|
|
|
18
19
|
WALT_ISSUER_URL,
|
|
19
20
|
WALT_OID4VCI_METADATA,
|
|
20
21
|
} from './MetadataMocks';
|
|
22
|
+
import { getMockData } from './data/VciDataFixtures';
|
|
21
23
|
|
|
24
|
+
//todo: skipping this. it was written for pre v13 version and we have to do some modifications to make it work
|
|
22
25
|
describe('MetadataClient with IdentiProof Issuer should', () => {
|
|
23
26
|
beforeAll(() => {
|
|
24
27
|
nock.cleanAll();
|
|
@@ -47,7 +50,7 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
|
|
|
47
50
|
|
|
48
51
|
const INITIATE_URI =
|
|
49
52
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredential&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhOTUyZjUxNi1jYWVmLTQ4YjMtODIxYy00OTRkYzgyNjljZjAiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.YE5DlalcLC2ChGEg47CQDaN1gTxbaQqSclIVqsSAUHE&user_pin_required=false';
|
|
50
|
-
const initiation = await
|
|
53
|
+
const initiation = await CredentialOfferClientV1_0_11.fromURI(INITIATE_URI);
|
|
51
54
|
const metadata = await MetadataClient.retrieveAllMetadata(getIssuerFromCredentialOfferPayload(initiation.credential_offer) as string);
|
|
52
55
|
expect(metadata.credential_endpoint).toEqual('https://issuer.research.identiproof.io/credential');
|
|
53
56
|
expect(metadata.token_endpoint).toEqual('https://auth.research.identiproof.io/oauth2/token');
|
|
@@ -131,7 +134,7 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
|
|
|
131
134
|
nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OAUTH_AS).reply(404, {});
|
|
132
135
|
nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {});
|
|
133
136
|
|
|
134
|
-
const metadata =
|
|
137
|
+
const metadata = retrieveWellknown(IDENTIPROOF_ISSUER_URL, WellKnownEndpoints.OPENID4VCI_ISSUER, { errorOnNotFound: true });
|
|
135
138
|
await expect(metadata).rejects.toThrowError('{"error": "not found"}');
|
|
136
139
|
});
|
|
137
140
|
});
|
|
@@ -257,4 +260,51 @@ describe.skip('Metadataclient with SpruceId should', () => {
|
|
|
257
260
|
},
|
|
258
261
|
});
|
|
259
262
|
});
|
|
263
|
+
|
|
264
|
+
it('succeed without OID4VCI and with OIDC metadata of credenco', async () => {
|
|
265
|
+
/*nock(WALT_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(WALT_OID4VCI_METADATA));
|
|
266
|
+
|
|
267
|
+
nock(WALT_ISSUER_URL)
|
|
268
|
+
.get(/.well-known\/.*!/)
|
|
269
|
+
.times(2)
|
|
270
|
+
.reply(404, JSON.stringify({ error: 'does not exist' }));
|
|
271
|
+
*/
|
|
272
|
+
const metadata = await MetadataClient.retrieveAllMetadata('https://mijnkvk.acc.credenco.com/');
|
|
273
|
+
expect(metadata.credential_endpoint).toEqual('https://ngi-oidc4vci-test.spruceid.xyz/credential');
|
|
274
|
+
expect(metadata.token_endpoint).toEqual('https://ngi-oidc4vci-test.spruceid.xyz/token');
|
|
275
|
+
expect(metadata.credentialIssuerMetadata).toEqual({
|
|
276
|
+
issuer: 'https://ngi-oidc4vci-test.spruceid.xyz',
|
|
277
|
+
credential_endpoint: 'https://ngi-oidc4vci-test.spruceid.xyz/credential',
|
|
278
|
+
token_endpoint: 'https://ngi-oidc4vci-test.spruceid.xyz/token',
|
|
279
|
+
jwks_uri: 'https://ngi-oidc4vci-test.spruceid.xyz/jwks',
|
|
280
|
+
grant_types_supported: ['urn:ietf:params:oauth:grant-type:pre-authorized_code'],
|
|
281
|
+
credentials_supported: {
|
|
282
|
+
OpenBadgeCredential: {
|
|
283
|
+
formats: {
|
|
284
|
+
jwt_vc: {
|
|
285
|
+
types: ['VerifiableCredential', 'OpenBadgeCredential'],
|
|
286
|
+
cryptographic_binding_methods_supported: ['did'],
|
|
287
|
+
cryptographic_suites_supported: ['ES256', 'ES256K'],
|
|
288
|
+
},
|
|
289
|
+
ldp_vc: {
|
|
290
|
+
types: ['VerifiableCredential', 'OpenBadgeCredential'],
|
|
291
|
+
cryptographic_binding_methods_supported: ['did'],
|
|
292
|
+
cryptographic_suites_supported: ['Ed25519Signature2018'],
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
describe('Metadataclient with Credenco should', () => {
|
|
302
|
+
it('succeed without OID4VCI and with OIDC metadata', async () => {
|
|
303
|
+
const metadata = await MetadataClient.retrieveAllMetadata('https://mijnkvk.acc.credenco.com/');
|
|
304
|
+
expect(metadata.credential_endpoint).toEqual('https://mijnkvk.acc.credenco.com/credential');
|
|
305
|
+
expect(metadata.token_endpoint).toEqual('https://mijnkvk.acc.credenco.com/token');
|
|
306
|
+
expect(metadata.credentialIssuerMetadata?.credential_configurations_supported).toEqual(
|
|
307
|
+
getMockData('credenco')?.metadata.openid4vci_metadata.credential_configurations_supported,
|
|
308
|
+
);
|
|
309
|
+
});
|
|
260
310
|
});
|