@sphereon/oid4vci-client 0.6.1-next.8 → 0.7.1-next.10

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.
@@ -30,16 +30,18 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
30
30
  nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
31
31
 
32
32
  nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OAUTH_AS).reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA));
33
+ nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404);
33
34
 
34
35
  const metadata = await MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL);
35
36
  expect(metadata.credential_endpoint).toEqual('https://issuer.research.identiproof.io/credential');
36
37
  expect(metadata.token_endpoint).toEqual('https://auth.research.identiproof.io/oauth2/token');
37
- expect(metadata.issuerMetadata).toEqual(IDENTIPROOF_OID4VCI_METADATA);
38
+ expect(metadata.credentialIssuerMetadata).toMatchObject(IDENTIPROOF_OID4VCI_METADATA);
38
39
  });
39
40
 
40
41
  it('succeed with OID4VCI and separate AS metadata from Initiation', async () => {
41
42
  nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
42
43
  nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OAUTH_AS).reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA));
44
+ nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404);
43
45
 
44
46
  const INITIATE_URI =
45
47
  'openid-initiate-issuance://?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredential&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhOTUyZjUxNi1jYWVmLTQ4YjMtODIxYy00OTRkYzgyNjljZjAiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.YE5DlalcLC2ChGEg47CQDaN1gTxbaQqSclIVqsSAUHE&user_pin_required=false';
@@ -47,7 +49,7 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
47
49
  const metadata = await MetadataClient.retrieveAllMetadata(getIssuerFromCredentialOfferPayload(initiation.credential_offer) as string);
48
50
  expect(metadata.credential_endpoint).toEqual('https://issuer.research.identiproof.io/credential');
49
51
  expect(metadata.token_endpoint).toEqual('https://auth.research.identiproof.io/oauth2/token');
50
- expect(metadata.issuerMetadata).toEqual(IDENTIPROOF_OID4VCI_METADATA);
52
+ expect(metadata.credentialIssuerMetadata).toEqual(IDENTIPROOF_OID4VCI_METADATA);
51
53
  });
52
54
 
53
55
  it('Fail without OID4VCI and only AS metadata (no credential endpoint)', async () => {
@@ -64,18 +66,20 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
64
66
  .reply(404, JSON.stringify({ error: 'does not exist' }));
65
67
 
66
68
  await expect(() => MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL, { errorOnNotFound: true })).rejects.toThrowError(
67
- 'Could not deduce the token endpoint for https://issuer.research.identiproof.io',
69
+ 'Could not deduce the token_endpoint for https://issuer.research.identiproof.io',
68
70
  );
69
71
  });
70
72
 
71
73
  it('Fail with OID4VCI and no AS metadata', async () => {
72
74
  nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
73
- nock(IDENTIPROOF_ISSUER_URL)
75
+ nock(IDENTIPROOF_AS_URL)
74
76
  .get(WellKnownEndpoints.OPENID_CONFIGURATION)
75
77
  .reply(404, JSON.stringify({ error: 'does not exist' }));
76
78
 
77
79
  nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OAUTH_AS).reply(404, JSON.stringify({}));
78
- await expect(() => MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL)).rejects.toThrowError('{"error": "not found"}');
80
+ await expect(() => MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL)).rejects.toThrowError(
81
+ 'Issuer https://issuer.research.identiproof.io provided a separate authorization server https://auth.research.identiproof.io, but that server did not provide metadata',
82
+ );
79
83
  });
80
84
 
81
85
  it('Fail if there is no token endpoint with errors enabled', async () => {
@@ -83,9 +87,10 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
83
87
  const meta = JSON.parse(JSON.stringify(IDENTIPROOF_AS_METADATA));
84
88
  delete meta.token_endpoint;
85
89
  nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OAUTH_AS).reply(200, JSON.stringify(meta));
90
+ nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404);
86
91
 
87
92
  await expect(() => MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL, { errorOnNotFound: true })).rejects.toThrowError(
88
- 'Could not deduce the token endpoint for https://issuer.research.identiproof.io',
93
+ 'Authorization Sever https://auth.research.identiproof.io did not provide a token_endpoint',
89
94
  );
90
95
  });
91
96
 
@@ -94,6 +99,7 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
94
99
  delete meta.credential_endpoint;
95
100
  nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(meta));
96
101
  nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OAUTH_AS).reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA));
102
+ nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404);
97
103
 
98
104
  await expect(() => MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL, { errorOnNotFound: true })).rejects.toThrowError(
99
105
  'Could not deduce the credential endpoint for https://issuer.research.identiproof.io',
@@ -103,6 +109,7 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
103
109
  it('Succeed with default value if there is no credential endpoint with errors disabled', async () => {
104
110
  nock(IDENTIPROOF_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
105
111
  nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OAUTH_AS).reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA));
112
+ nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404);
106
113
 
107
114
  const metadata = await MetadataClient.retrieveAllMetadata(IDENTIPROOF_ISSUER_URL);
108
115
  expect(metadata.credential_endpoint).toEqual('https://issuer.research.identiproof.io/credential');
@@ -130,11 +137,13 @@ describe('MetadataClient with IdentiProof Issuer should', () => {
130
137
  describe('Metadataclient with Spruce Issuer should', () => {
131
138
  it('succeed with OID4VCI and separate AS metadata', async () => {
132
139
  nock(SPRUCE_ISSUER_URL).get(WellKnownEndpoints.OPENID4VCI_ISSUER).reply(200, JSON.stringify(SPRUCE_OID4VCI_METADATA));
140
+ nock(SPRUCE_ISSUER_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404);
141
+ nock(SPRUCE_ISSUER_URL).get(WellKnownEndpoints.OAUTH_AS).reply(404);
133
142
 
134
143
  const metadata = await MetadataClient.retrieveAllMetadata(SPRUCE_ISSUER_URL);
135
144
  expect(metadata.credential_endpoint).toEqual('https://ngi-oidc4vci-test.spruceid.xyz/credential');
136
145
  expect(metadata.token_endpoint).toEqual('https://ngi-oidc4vci-test.spruceid.xyz/token');
137
- expect(metadata.issuerMetadata).toEqual(SPRUCE_OID4VCI_METADATA);
146
+ expect(metadata.credentialIssuerMetadata).toEqual(SPRUCE_OID4VCI_METADATA);
138
147
  });
139
148
 
140
149
  it('Fail without OID4VCI', async () => {
@@ -144,7 +153,7 @@ describe('Metadataclient with Spruce Issuer should', () => {
144
153
  .reply(404, JSON.stringify({ error: 'does not exist' }));
145
154
 
146
155
  await expect(() => MetadataClient.retrieveAllMetadata(SPRUCE_ISSUER_URL, { errorOnNotFound: true })).rejects.toThrowError(
147
- 'Could not deduce the token endpoint for https://ngi-oidc4vci-test.spruceid.xyz',
156
+ 'Could not deduce the token_endpoint for https://ngi-oidc4vci-test.spruceid.xyz',
148
157
  );
149
158
  });
150
159
  });
@@ -160,7 +169,7 @@ describe('Metadataclient with Danubetech should', () => {
160
169
  const metadata = await MetadataClient.retrieveAllMetadata(DANUBE_ISSUER_URL);
161
170
  expect(metadata.credential_endpoint).toEqual('https://oidc4vc.uniissuer.io/credential');
162
171
  expect(metadata.token_endpoint).toEqual('https://oidc4vc.uniissuer.io/token');
163
- expect(metadata.issuerMetadata).toEqual(DANUBE_OIDC_METADATA);
172
+ expect(metadata.credentialIssuerMetadata).toEqual(DANUBE_OIDC_METADATA);
164
173
  });
165
174
 
166
175
  it('Fail without OID4VCI', async () => {
@@ -170,7 +179,7 @@ describe('Metadataclient with Danubetech should', () => {
170
179
  .reply(404, JSON.stringify({ error: 'does not exist' }));
171
180
 
172
181
  await expect(() => MetadataClient.retrieveAllMetadata(SPRUCE_ISSUER_URL, { errorOnNotFound: true })).rejects.toThrowError(
173
- 'Could not deduce the token endpoint for https://ngi-oidc4vci-test.spruceid.xyz',
182
+ 'Could not deduce the token_endpoint for https://ngi-oidc4vci-test.spruceid.xyz',
174
183
  );
175
184
  });
176
185
  });
@@ -187,7 +196,7 @@ describe('Metadataclient with Walt-id should', () => {
187
196
  const metadata = await MetadataClient.retrieveAllMetadata(WALT_ISSUER_URL);
188
197
  expect(metadata.credential_endpoint).toEqual('https://jff.walt.id/issuer-api/oidc/credential');
189
198
  expect(metadata.token_endpoint).toEqual('https://jff.walt.id/issuer-api/oidc/token');
190
- expect(metadata.issuerMetadata).toEqual(WALT_OID4VCI_METADATA);
199
+ expect(metadata.credentialIssuerMetadata).toEqual(WALT_OID4VCI_METADATA);
191
200
  });
192
201
 
193
202
  it('Fail without OID4VCI', async () => {
@@ -197,7 +206,7 @@ describe('Metadataclient with Walt-id should', () => {
197
206
  .reply(404, JSON.stringify({ error: 'does not exist' }));
198
207
 
199
208
  await expect(() => MetadataClient.retrieveAllMetadata(WALT_ISSUER_URL, { errorOnNotFound: true })).rejects.toThrowError(
200
- 'Could not deduce the token endpoint for https://jff.walt.id/issuer-api/oidc',
209
+ 'Could not deduce the token_endpoint for https://jff.walt.id/issuer-api/oidc',
201
210
  );
202
211
  });
203
212
  });
@@ -1,4 +1,4 @@
1
- import { AuthzFlowType, CodeChallengeMethod } from '@sphereon/oid4vci-common';
1
+ import { AuthzFlowType, CodeChallengeMethod, WellKnownEndpoints } from '@sphereon/oid4vci-common';
2
2
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3
3
  // @ts-ignore
4
4
  import nock from 'nock';
@@ -12,6 +12,8 @@ describe('OpenID4VCIClient should', () => {
12
12
 
13
13
  beforeEach(async () => {
14
14
  nock(MOCK_URL).get(/.*/).reply(200, {});
15
+ nock(MOCK_URL).get(WellKnownEndpoints.OAUTH_AS).reply(404, {});
16
+ nock(MOCK_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {});
15
17
  client = await OpenID4VCIClient.fromURI({
16
18
  uri: 'openid-initiate-issuance://?issuer=https://server.example.com&credential_type=TestCredential',
17
19
  flowType: AuthzFlowType.AUTHORIZATION_CODE_FLOW,
@@ -25,7 +27,7 @@ describe('OpenID4VCIClient should', () => {
25
27
  it('should create successfully construct an authorization request url', async () => {
26
28
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
27
29
  // @ts-ignore
28
- client._endpointMetadata?.issuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
30
+ client._endpointMetadata?.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
29
31
  const url = client.createAuthorizationRequestUrl({
30
32
  clientId: 'test-client',
31
33
  codeChallengeMethod: CodeChallengeMethod.SHA256,
@@ -53,7 +55,7 @@ describe('OpenID4VCIClient should', () => {
53
55
  it("injects 'openid' as the first scope if not provided", async () => {
54
56
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
55
57
  // @ts-ignore
56
- client._endpointMetadata?.issuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
58
+ client._endpointMetadata?.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
57
59
 
58
60
  const url = client.createAuthorizationRequestUrl({
59
61
  clientId: 'test-client',
@@ -71,7 +73,7 @@ describe('OpenID4VCIClient should', () => {
71
73
  it('throw an error if no scope and no authorization_details is provided', async () => {
72
74
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
73
75
  // @ts-ignore
74
- client._endpointMetadata?.issuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
76
+ client._endpointMetadata?.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
75
77
 
76
78
  expect(() => {
77
79
  client.createAuthorizationRequestUrl({
@@ -85,7 +87,7 @@ describe('OpenID4VCIClient should', () => {
85
87
  it('create an authorization request url with authorization_details array property', async () => {
86
88
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
87
89
  // @ts-ignore
88
- client._endpointMetadata.issuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
90
+ client._endpointMetadata?.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
89
91
 
90
92
  expect(
91
93
  client.createAuthorizationRequestUrl({
@@ -116,7 +118,7 @@ describe('OpenID4VCIClient should', () => {
116
118
  it('create an authorization request url with authorization_details object property', async () => {
117
119
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
118
120
  // @ts-ignore
119
- client._endpointMetadata.issuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
121
+ client._endpointMetadata?.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
120
122
 
121
123
  expect(
122
124
  client.createAuthorizationRequestUrl({
@@ -140,7 +142,7 @@ describe('OpenID4VCIClient should', () => {
140
142
  it('create an authorization request url with authorization_details and scope', async () => {
141
143
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
142
144
  // @ts-ignore
143
- client._endpointMetadata.issuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
145
+ client._endpointMetadata.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
144
146
 
145
147
  expect(
146
148
  client.createAuthorizationRequestUrl({
@@ -1,4 +1,4 @@
1
- import { AuthzFlowType, CodeChallengeMethod, Oauth2ASWithOID4VCIMetadata } from '@sphereon/oid4vci-common';
1
+ import { AuthzFlowType, CodeChallengeMethod, WellKnownEndpoints } from '@sphereon/oid4vci-common';
2
2
  import nock from 'nock';
3
3
 
4
4
  import { OpenID4VCIClient } from '../OpenID4VCIClient';
@@ -9,6 +9,8 @@ describe('OpenID4VCIClient', () => {
9
9
 
10
10
  beforeEach(async () => {
11
11
  nock(MOCK_URL).get(/.*/).reply(200, {});
12
+ nock(MOCK_URL).get(WellKnownEndpoints.OAUTH_AS).reply(404, {});
13
+ nock(MOCK_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {});
12
14
  nock(`${MOCK_URL}`).post('/v1/auth/par').reply(201, { request_uri: 'test_uri', expires_in: 90 });
13
15
  client = await OpenID4VCIClient.fromURI({
14
16
  uri: 'openid-initiate-issuance://?issuer=https://server.example.com&credential_type=TestCredential',
@@ -21,7 +23,7 @@ describe('OpenID4VCIClient', () => {
21
23
  });
22
24
 
23
25
  it('should successfully retrieve the authorization code using PAR', async () => {
24
- (client.endpointMetadata.issuerMetadata! as Oauth2ASWithOID4VCIMetadata).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
26
+ client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
25
27
  const actual = await client.acquirePushedAuthorizationRequestURI({
26
28
  clientId: 'test-client',
27
29
  codeChallengeMethod: CodeChallengeMethod.SHA256,
@@ -56,7 +58,7 @@ describe('OpenID4VCIClient', () => {
56
58
  });
57
59
 
58
60
  it('should not fail when only authorization_details is present', async () => {
59
- (client.endpointMetadata.issuerMetadata! as Oauth2ASWithOID4VCIMetadata).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
61
+ client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
60
62
  const actual = await client.acquirePushedAuthorizationRequestURI({
61
63
  clientId: 'test-client',
62
64
  codeChallengeMethod: CodeChallengeMethod.SHA256,
@@ -77,7 +79,7 @@ describe('OpenID4VCIClient', () => {
77
79
  });
78
80
 
79
81
  it('should not fail when only scope is present', async () => {
80
- (client.endpointMetadata.issuerMetadata! as Oauth2ASWithOID4VCIMetadata).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
82
+ client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
81
83
  const actual = await client.acquirePushedAuthorizationRequestURI({
82
84
  clientId: 'test-client',
83
85
  codeChallengeMethod: CodeChallengeMethod.SHA256,
@@ -89,7 +91,7 @@ describe('OpenID4VCIClient', () => {
89
91
  });
90
92
 
91
93
  it('should not fail when both authorization_details and scope are present', async () => {
92
- (client.endpointMetadata.issuerMetadata! as Oauth2ASWithOID4VCIMetadata).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
94
+ client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
93
95
  const actual = await client.acquirePushedAuthorizationRequestURI({
94
96
  clientId: 'test-client',
95
97
  codeChallengeMethod: CodeChallengeMethod.SHA256,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sphereon/oid4vci-client",
3
- "version": "0.6.1-next.8+02c84d3",
3
+ "version": "0.7.1-next.10+ab47468",
4
4
  "description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
5
5
  "source": "lib/index.ts",
6
6
  "main": "dist/index.js",
@@ -15,15 +15,14 @@
15
15
  "build": "tsc"
16
16
  },
17
17
  "dependencies": {
18
- "@sphereon/oid4vci-common": "0.6.1-next.8+02c84d3",
18
+ "@sphereon/oid4vci-common": "0.7.1-next.10+ab47468",
19
19
  "@sphereon/ssi-types": "^0.15.1",
20
20
  "cross-fetch": "^3.1.8",
21
- "debug": "^4.3.4",
22
- "uint8arrays": "^4.0.6"
21
+ "debug": "^4.3.4"
23
22
  },
24
23
  "devDependencies": {
25
24
  "@types/jest": "^29.5.3",
26
- "@types/node": "^18.17.3",
25
+ "@types/node": "^18.17.4",
27
26
  "@typescript-eslint/eslint-plugin": "^5.62.0",
28
27
  "@typescript-eslint/parser": "^5.62.0",
29
28
  "codecov": "^3.8.3",
@@ -40,7 +39,8 @@
40
39
  "open-cli": "^7.2.0",
41
40
  "ts-jest": "^29.1.1",
42
41
  "ts-node": "^10.9.1",
43
- "typescript": "4.9.5"
42
+ "typescript": "4.9.5",
43
+ "uint8arrays": "3.1.1"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=16"
@@ -64,5 +64,5 @@
64
64
  "OIDC4VCI",
65
65
  "OID4VCI"
66
66
  ],
67
- "gitHead": "02c84d30ec5fd81b1ecbec0d676e9a8c9b731823"
67
+ "gitHead": "ab474685112423e8eabee445baae6403e45fd087"
68
68
  }