@connectid-tools/rp-nodejs-sdk 4.2.1 → 5.0.0
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 +60 -71
- package/package.json +4 -5
- package/{config.js → src/config.js} +2 -31
- package/src/conformance/api/conformance-api.d.ts +38 -0
- package/src/conformance/api/conformance-api.js +53 -0
- package/src/conformance/config.json +60 -0
- package/src/conformance/conformance-config.d.ts +2 -0
- package/src/conformance/conformance-config.js +34 -0
- package/src/conformance/conformance.test.js +101 -0
- package/src/conformance/variant.json +1 -0
- package/src/crypto/crypto-loader.d.ts +32 -0
- package/src/crypto/crypto-loader.js +49 -0
- package/src/crypto/jwt-helper.d.ts +61 -0
- package/src/crypto/jwt-helper.js +92 -0
- package/src/crypto/pkce-helper.d.ts +43 -0
- package/src/crypto/pkce-helper.js +75 -0
- package/src/endpoints/participants-endpoint.d.ts +55 -0
- package/src/endpoints/participants-endpoint.js +137 -0
- package/src/endpoints/pushed-authorisation-request-endpoint.d.ts +87 -0
- package/src/endpoints/pushed-authorisation-request-endpoint.js +192 -0
- package/src/endpoints/retrieve-token-endpoint.d.ts +66 -0
- package/src/endpoints/retrieve-token-endpoint.js +159 -0
- package/src/endpoints/userinfo-endpoint.d.ts +24 -0
- package/src/endpoints/userinfo-endpoint.js +50 -0
- package/src/fapi/fapi-utils.d.ts +6 -0
- package/src/fapi/fapi-utils.js +9 -0
- package/src/http/http-client-extensions.d.ts +60 -0
- package/src/http/http-client-extensions.js +106 -0
- package/src/http/http-client-factory.d.ts +27 -0
- package/src/http/http-client-factory.js +45 -0
- package/src/integration/integration.test.d.ts +1 -0
- package/src/integration/integration.test.js +30 -0
- package/src/model/callback-params.d.ts +31 -0
- package/src/model/callback-params.js +1 -0
- package/src/model/claims.d.ts +100 -0
- package/src/model/claims.js +1 -0
- package/src/model/consolidated-token-set.d.ts +74 -0
- package/src/model/consolidated-token-set.js +100 -0
- package/src/model/discovery-service.d.ts +46 -0
- package/src/model/discovery-service.js +112 -0
- package/src/model/issuer-metadata.d.ts +165 -0
- package/src/model/issuer-metadata.js +1 -0
- package/src/model/jwks.d.ts +12 -0
- package/src/model/jwks.js +1 -0
- package/src/model/token-response.d.ts +31 -0
- package/src/model/token-response.js +1 -0
- package/src/model/token-set.d.ts +73 -0
- package/src/model/token-set.js +179 -0
- package/src/relying-party-client-sdk.d.ts +68 -0
- package/src/relying-party-client-sdk.js +150 -0
- package/src/test-data/large-participants-test-data.d.ts +865 -0
- package/src/test-data/large-participants-test-data.js +18907 -0
- package/src/test-data/participants-test-data.d.ts +149 -0
- package/src/test-data/participants-test-data.js +458 -0
- package/src/test-data/sandbox-participants-test-data.d.ts +865 -0
- package/src/test-data/sandbox-participants-test-data.js +3794 -0
- package/src/tests/cert-utils.test.d.ts +1 -0
- package/src/tests/cert-utils.test.js +13 -0
- package/src/tests/functional-utils.test.d.ts +1 -0
- package/src/tests/functional-utils.test.js +13 -0
- package/src/tests/participant-filters.test.d.ts +1 -0
- package/src/tests/participant-filters.test.js +151 -0
- package/src/tests/pushed-authorisation-request-endpoint.test.d.ts +1 -0
- package/src/tests/pushed-authorisation-request-endpoint.test.js +159 -0
- package/src/tests/relying-party-client-sdk.test.d.ts +1 -0
- package/src/tests/relying-party-client-sdk.test.js +313 -0
- package/src/tests/request-utils.test.d.ts +1 -0
- package/src/tests/request-utils.test.js +16 -0
- package/src/tests/system-information.test.d.ts +1 -0
- package/src/tests/system-information.test.js +16 -0
- package/src/tests/user-agent.test.d.ts +1 -0
- package/src/tests/user-agent.test.js +23 -0
- package/src/tests/validator.test.d.ts +1 -0
- package/src/tests/validator.test.js +38 -0
- package/{types.d.ts → src/types.d.ts} +61 -32
- package/src/types.js +1 -0
- package/{utils → src/utils}/request-utils.d.ts +1 -1
- package/src/utils/request-utils.js +8 -0
- package/{utils → src/utils}/user-agent.d.ts +1 -1
- package/{utils → src/utils}/user-agent.js +1 -1
- package/relying-party-client-sdk.d.ts +0 -37
- package/relying-party-client-sdk.js +0 -364
- package/utils/request-utils.js +0 -8
- /package/{config.d.ts → src/config.d.ts} +0 -0
- /package/{types.js → src/conformance/conformance.test.d.ts} +0 -0
- /package/{filter → src/filter}/participant-filters.d.ts +0 -0
- /package/{filter → src/filter}/participant-filters.js +0 -0
- /package/{logger.d.ts → src/logger.d.ts} +0 -0
- /package/{logger.js → src/logger.js} +0 -0
- /package/{utils → src/utils}/cert-utils.d.ts +0 -0
- /package/{utils → src/utils}/cert-utils.js +0 -0
- /package/{utils → src/utils}/functional-utils.d.ts +0 -0
- /package/{utils → src/utils}/functional-utils.js +0 -0
- /package/{utils → src/utils}/system-information.d.ts +0 -0
- /package/{utils → src/utils}/system-information.js +0 -0
- /package/{validator.d.ts → src/validator.d.ts} +0 -0
- /package/{validator.js → src/validator.js} +0 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import RelyingPartyClientSdk from '../relying-party-client-sdk.js';
|
|
2
|
+
import { config } from '../config.js';
|
|
3
|
+
import { parse } from 'url';
|
|
4
|
+
import { participantsTestData } from '../test-data/participants-test-data.js';
|
|
5
|
+
import { sandboxParticipantsTestData } from '../test-data/sandbox-participants-test-data.js';
|
|
6
|
+
import { largeParticipantsTestData } from '../test-data/large-participants-test-data.js';
|
|
7
|
+
import { describe, it, mock } from 'node:test';
|
|
8
|
+
import assert from 'node:assert';
|
|
9
|
+
describe('getParticipants', () => {
|
|
10
|
+
it('should return participants', async () => {
|
|
11
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
12
|
+
// Mock the endpoint's fetchParticipants method instead
|
|
13
|
+
const participantsEndpoint = rpClient.participantsEndpoint;
|
|
14
|
+
const mockedFetch = mock.method(participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
15
|
+
const idps = await rpClient.getParticipants();
|
|
16
|
+
idps.forEach((idp) => assert.ok(idp.OrganisationId));
|
|
17
|
+
assert.equal(mockedFetch.mock.calls.length, 1);
|
|
18
|
+
});
|
|
19
|
+
it('should throw error when url points to wrong place', async () => {
|
|
20
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
21
|
+
newConfig.data.registry_participants_uri = 'http://www.thisurldoesnotexist123456790.test';
|
|
22
|
+
const wrongRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
23
|
+
await assert.rejects(async () => wrongRpClient.getParticipants());
|
|
24
|
+
});
|
|
25
|
+
it('should return only active participants except Fallback providers when include_uncertified_participants is set', async () => {
|
|
26
|
+
const participantsTestData = getParticipantsTestData();
|
|
27
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
28
|
+
newConfig.data.include_uncertified_participants = true;
|
|
29
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
30
|
+
mock.method(filteringRpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
31
|
+
const participants = await filteringRpClient.getParticipants();
|
|
32
|
+
assert.deepEqual(participants[0], participantsTestData[0]);
|
|
33
|
+
assert.deepEqual(participants[1], participantsTestData[1]);
|
|
34
|
+
assert.equal(participants.length, 2);
|
|
35
|
+
});
|
|
36
|
+
it('should return only active participants who support the requested claims', async () => {
|
|
37
|
+
const participantsData = getParticipantsTestData();
|
|
38
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
39
|
+
newConfig.data.required_claims = ['given_name'];
|
|
40
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
41
|
+
mock.method(filteringRpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
42
|
+
const participants = await filteringRpClient.getParticipants();
|
|
43
|
+
assert.equal(participants.length, 1);
|
|
44
|
+
assert.deepEqual(participants[0].AuthorisationServers[0].AuthorisationServerId, participantsData[0].AuthorisationServers[0].AuthorisationServerId);
|
|
45
|
+
});
|
|
46
|
+
it('should return no participants if none support the required claims', async () => {
|
|
47
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
48
|
+
newConfig.data.required_claims = ['nonexistentclaim'];
|
|
49
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
50
|
+
mock.method(filteringRpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
51
|
+
const participants = await filteringRpClient.getParticipants();
|
|
52
|
+
assert.ok(participants.length === 0);
|
|
53
|
+
});
|
|
54
|
+
it('should return only active participants who have the TDIF certification', async () => {
|
|
55
|
+
const participantsData = getSandboxParticipantsTestData();
|
|
56
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
57
|
+
newConfig.data.required_participant_certifications = [{ profileType: 'TDIF Accreditation', profileVariant: 'Identity Provider' }];
|
|
58
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
59
|
+
mock.method(filteringRpClient.participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
60
|
+
const participants = await filteringRpClient.getParticipants();
|
|
61
|
+
assert.equal(participants[0].AuthorisationServers[0].AuthorisationServerId, participantsData[7].AuthorisationServers[1].AuthorisationServerId);
|
|
62
|
+
assert.equal(participants[0].AuthorisationServers[1].AuthorisationServerId, participantsData[7].AuthorisationServers[2].AuthorisationServerId);
|
|
63
|
+
assert.ok(participants.length === 1);
|
|
64
|
+
assert.ok(participants[0].AuthorisationServers.length === 2);
|
|
65
|
+
});
|
|
66
|
+
it('should return no participants if no-one has the required certification', async () => {
|
|
67
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
68
|
+
newConfig.data.required_participant_certifications = [{ profileType: 'Nonexistent Accreditation', profileVariant: 'Identity Provider' }];
|
|
69
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
70
|
+
mock.method(filteringRpClient.participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
71
|
+
const participants = await filteringRpClient.getParticipants();
|
|
72
|
+
assert.ok(participants.length === 0);
|
|
73
|
+
});
|
|
74
|
+
it('should run really fast', async () => {
|
|
75
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
76
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getLargeParticipantsTestData());
|
|
77
|
+
const startTime = new Date().getTime();
|
|
78
|
+
const numCalls = 1000;
|
|
79
|
+
let numParticipants = 0;
|
|
80
|
+
for (let i = 0; i < numCalls; i++) {
|
|
81
|
+
const participants = await rpClient.getParticipants();
|
|
82
|
+
numParticipants += participants.length;
|
|
83
|
+
}
|
|
84
|
+
const endTime = new Date().getTime();
|
|
85
|
+
const timeDiff = endTime - startTime;
|
|
86
|
+
const timePerCall = timeDiff / numCalls;
|
|
87
|
+
const timePerCallThreshold = 20; // ms, Arbitrary threshold based on performance when filters mutate (if non mutating filters are used, this increases by order of magnitude)
|
|
88
|
+
console.log(`Time taken for ${numCalls} calls: ${timeDiff} ms, per call: ${timePerCall} ms, numParticipants: ${numParticipants}`);
|
|
89
|
+
assert.ok(timePerCall < timePerCallThreshold);
|
|
90
|
+
});
|
|
91
|
+
it('should return only active participants and certifications (except Fallback providers) when using default settings', async () => {
|
|
92
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
93
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
94
|
+
const participants = await rpClient.getParticipants();
|
|
95
|
+
const firstParticipant = participants[0];
|
|
96
|
+
assert.equal(firstParticipant.OrganisationId, participantsTestData[0].OrganisationId);
|
|
97
|
+
assert.ok(participants[0].AuthorisationServers.length === 2);
|
|
98
|
+
assert.ok(participants[0].AuthorisationServers[0].AuthorisationServerCertifications.length === 2);
|
|
99
|
+
assert.ok(participants[0].AuthorisationServers[1].AuthorisationServerCertifications.length === 2);
|
|
100
|
+
assert.ok(participants.length === 1);
|
|
101
|
+
});
|
|
102
|
+
it('should return an empty participants array when no auth servers have the required claims', async () => {
|
|
103
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
104
|
+
newConfig.data.required_claims = ['bogus_claim'];
|
|
105
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
106
|
+
mock.method(filteringRpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
107
|
+
const participants = await filteringRpClient.getParticipants();
|
|
108
|
+
assert.ok(participants.length === 0);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe('getFallbackProviderParticipants', () => {
|
|
112
|
+
it('should return just the participants with a certified Fallback Providers auth server', async () => {
|
|
113
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
114
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
115
|
+
const participants = await rpClient.getFallbackProviderParticipants();
|
|
116
|
+
assert.ok(participants.length === 1);
|
|
117
|
+
assert.deepEqual(participants[0], getParticipantsTestData()[2]);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe('getAuthServerDetails', () => {
|
|
121
|
+
it('should find Mock Bank 3 authorisation server details', async () => {
|
|
122
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
123
|
+
const participantsEndpoint = rpClient.participantsEndpoint;
|
|
124
|
+
mock.method(participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
125
|
+
const bank3AuthServerId = 'ce868ca5-0b99-47e6-b8cd-e26aac082448';
|
|
126
|
+
const { AuthorisationServerId, CustomerFriendlyDescription, } = await participantsEndpoint.getAuthServerDetails(bank3AuthServerId);
|
|
127
|
+
assert.equal(AuthorisationServerId, bank3AuthServerId);
|
|
128
|
+
assert.equal(CustomerFriendlyDescription, 'Bank N');
|
|
129
|
+
});
|
|
130
|
+
it('should throw error when cannot find authorisation server details because it does not exist', async () => {
|
|
131
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
132
|
+
const participantsEndpoint = rpClient.participantsEndpoint;
|
|
133
|
+
await assert.rejects(async () => participantsEndpoint.getAuthServerDetails('foo'), { message: 'Unable to find specified Authorisation Server: foo' });
|
|
134
|
+
});
|
|
135
|
+
it('should not find uncertified auth servers when include_uncertified_participants is not set', async () => {
|
|
136
|
+
const uncertifiedAuthServerId = '6a3b1012-d5c8-4e08-b280-313051d24004';
|
|
137
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
138
|
+
delete newConfig.data.include_uncertified_participants;
|
|
139
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
140
|
+
const participantsEndpoint = filteringRpClient.participantsEndpoint;
|
|
141
|
+
mock.method(participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
142
|
+
await assert.rejects(async () => participantsEndpoint.getAuthServerDetails(uncertifiedAuthServerId));
|
|
143
|
+
});
|
|
144
|
+
it('should not find uncertified auth servers when include_uncertified_participants is false', async () => {
|
|
145
|
+
const uncertifiedAuthServerId = '6a3b1012-d5c8-4e08-b280-313051d24004';
|
|
146
|
+
const newConfig = JSON.parse(JSON.stringify(config));
|
|
147
|
+
newConfig.data.include_uncertified_participants = false;
|
|
148
|
+
const filteringRpClient = withMockedDate(new RelyingPartyClientSdk(newConfig));
|
|
149
|
+
const participantsEndpoint = filteringRpClient.participantsEndpoint;
|
|
150
|
+
mock.method(participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
151
|
+
await assert.rejects(async () => participantsEndpoint.getAuthServerDetails(uncertifiedAuthServerId));
|
|
152
|
+
});
|
|
153
|
+
it('should tell the caller when the requested server was not returned because it has been filtered out based on server certification status', async () => {
|
|
154
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
155
|
+
const participantsEndpoint = rpClient.participantsEndpoint;
|
|
156
|
+
mock.method(participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
157
|
+
const uncertifiedAuthServerId = '6a3b1012-d5c8-4e08-b280-313051d24004';
|
|
158
|
+
await assert.rejects(async () => participantsEndpoint.getAuthServerDetails(uncertifiedAuthServerId));
|
|
159
|
+
});
|
|
160
|
+
it('should find uncertified auth servers if include_uncertified_participants is true', async () => {
|
|
161
|
+
const responseConfig = JSON.parse(JSON.stringify(config));
|
|
162
|
+
responseConfig.data.include_uncertified_participants = true;
|
|
163
|
+
const rpClient = new RelyingPartyClientSdk(responseConfig);
|
|
164
|
+
const participantsEndpoint = rpClient.participantsEndpoint;
|
|
165
|
+
mock.method(participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
166
|
+
const uncertifiedAuthServerId = '6a3b1012-d5c8-4e08-b280-313051d24004';
|
|
167
|
+
const { AuthorisationServerId, CustomerFriendlyDescription, } = await participantsEndpoint.getAuthServerDetails(uncertifiedAuthServerId);
|
|
168
|
+
assert.equal(AuthorisationServerId, uncertifiedAuthServerId);
|
|
169
|
+
assert.equal(CustomerFriendlyDescription, 'Do not use - Paul\'s Test Bank');
|
|
170
|
+
});
|
|
171
|
+
it('should find the fallback auth server', async () => {
|
|
172
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
173
|
+
const participantsEndpoint = rpClient.participantsEndpoint;
|
|
174
|
+
mock.method(participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
175
|
+
const fallbackAuthServerId = '69653ee1-ad97-496e-8885-a9e5a5ecc2b9';
|
|
176
|
+
const { AuthorisationServerId, CustomerFriendlyDescription, } = await participantsEndpoint.getAuthServerDetails(fallbackAuthServerId);
|
|
177
|
+
assert.equal(AuthorisationServerId, fallbackAuthServerId);
|
|
178
|
+
assert.equal(CustomerFriendlyDescription, 'KC Test 3');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('sendPushedAuthorisationRequest', () => {
|
|
182
|
+
const essentialClaims = ['given_name', 'middle_name', 'family_name', 'phone_number', 'email', 'address', 'birthdate'];
|
|
183
|
+
it('should send a pushed authorisation request to Bank 3', async () => {
|
|
184
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
185
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
186
|
+
const bank3AuthServerId = 'ce868ca5-0b99-47e6-b8cd-e26aac082448';
|
|
187
|
+
const essentialClaimsWithCbaLoyalty = [...essentialClaims, 'cba_loyalty'];
|
|
188
|
+
const { authUrl, codeVerifier, state, nonce, xFapiInteractionId, } = await rpClient.sendPushedAuthorisationRequest(bank3AuthServerId, essentialClaimsWithCbaLoyalty);
|
|
189
|
+
// Only the 'client_id' and 'request_uri' can be sent to the authorization endpoint.
|
|
190
|
+
// This verifies https://openid.net/specs/fapi-2_0-security-profile.html#name-authorization-code-flow-2
|
|
191
|
+
// which [will be|is] triggered through this change: https://bitbucket.org/openid/fapi/pull-requests/407
|
|
192
|
+
const url = new URL(authUrl);
|
|
193
|
+
const searchParams = new URLSearchParams(url.search);
|
|
194
|
+
const rfc9126Params = ['client_id', 'request_uri'];
|
|
195
|
+
assert.deepEqual(Array.from(searchParams.keys()), rfc9126Params);
|
|
196
|
+
assert.ok(codeVerifier.length > 0);
|
|
197
|
+
assert.ok(state.length > 0);
|
|
198
|
+
assert.ok(nonce.length > 0);
|
|
199
|
+
assert.ok(xFapiInteractionId.length > 0);
|
|
200
|
+
});
|
|
201
|
+
it('should fail to send a pushed authorisation to a server that is not certified', async () => {
|
|
202
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
203
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getParticipantsTestData());
|
|
204
|
+
const uncertifiedAuthServerId = '6a3b1012-d5c8-4e08-b280-313051d24004';
|
|
205
|
+
// await expect(rpClient.sendPushedAuthorisationRequest(uncertifiedAuthServerId, ['name'], [])).rejects.toThrow('Unable to find specified Authorisation Server: 6a3b1012-d5c8-4e08-b280-313051d24004')
|
|
206
|
+
await assert.rejects(async () => rpClient.sendPushedAuthorisationRequest(uncertifiedAuthServerId, ['name'], []));
|
|
207
|
+
});
|
|
208
|
+
it('should fail to send a pushed authorisation request with an invalid purpose', async () => {
|
|
209
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
210
|
+
const bank3AuthServerId = 'ce868ca5-0b99-47e6-b8cd-e26aac082448';
|
|
211
|
+
// await expect(rpClient.sendPushedAuthorisationRequest(bank3AuthServerId, ['name'], [], 'aa')).rejects.toThrow('Invalid purpose for supplied for PAR: aa')
|
|
212
|
+
await assert.rejects(async () => rpClient.sendPushedAuthorisationRequest(bank3AuthServerId, ['name'], [], 'aa'));
|
|
213
|
+
});
|
|
214
|
+
it('should not return a redirect_uri in the authUrl if only one is present', async () => {
|
|
215
|
+
const redirectConfig = JSON.parse(JSON.stringify(config));
|
|
216
|
+
redirectConfig.data.redirect_uris = ['https://tpp.localhost/cb'];
|
|
217
|
+
const rpClient = new RelyingPartyClientSdk(redirectConfig);
|
|
218
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
219
|
+
const bank3AuthServerId = 'ce868ca5-0b99-47e6-b8cd-e26aac082448';
|
|
220
|
+
const { authUrl } = await rpClient.sendPushedAuthorisationRequest(bank3AuthServerId, essentialClaims);
|
|
221
|
+
// Only the 'client_id' and 'request_uri' can be sent to the authorization endpoint.
|
|
222
|
+
// This verifies https://openid.net/specs/fapi-2_0-security-profile.html#name-authorization-code-flow-2
|
|
223
|
+
// which [will be|is] triggered through this change: https://bitbucket.org/openid/fapi/pull-requests/407
|
|
224
|
+
const url = new URL(authUrl);
|
|
225
|
+
const searchParams = new URLSearchParams(url.search);
|
|
226
|
+
const rfc9126Params = ['client_id', 'request_uri'];
|
|
227
|
+
assert.deepEqual(Array.from(searchParams.keys()), rfc9126Params);
|
|
228
|
+
});
|
|
229
|
+
it('should not return a response_type in the authUrl if only one is present', async () => {
|
|
230
|
+
const responseConfig = JSON.parse(JSON.stringify(config));
|
|
231
|
+
responseConfig.data.response_types = ['code id_token'];
|
|
232
|
+
const rpClient = new RelyingPartyClientSdk(responseConfig);
|
|
233
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
234
|
+
const bank3AuthServerId = 'ce868ca5-0b99-47e6-b8cd-e26aac082448';
|
|
235
|
+
const { authUrl } = await rpClient.sendPushedAuthorisationRequest(bank3AuthServerId, essentialClaims);
|
|
236
|
+
// Only the 'client_id' and 'request_uri' can be sent to the authorization endpoint.
|
|
237
|
+
// This verifies https://openid.net/specs/fapi-2_0-security-profile.html#name-authorization-code-flow-2
|
|
238
|
+
// which [will be|is] triggered through this change: https://bitbucket.org/openid/fapi/pull-requests/407
|
|
239
|
+
const url = new URL(authUrl);
|
|
240
|
+
const searchParams = new URLSearchParams(url.search);
|
|
241
|
+
const rfc9126Params = ['client_id', 'request_uri'];
|
|
242
|
+
assert.deepEqual(Array.from(searchParams.keys()), rfc9126Params);
|
|
243
|
+
});
|
|
244
|
+
it('should throw an error when sending a pushed authorisation request to nonexistent auth server', async () => {
|
|
245
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
246
|
+
await assert.rejects(async () => rpClient.sendPushedAuthorisationRequest('foo', essentialClaims));
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
describe('retrieveTokens', () => {
|
|
250
|
+
it('should throw an error when sending an invalid auth code to Bank 4', async () => {
|
|
251
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config));
|
|
252
|
+
mock.method(rpClient.participantsEndpoint, 'fetchParticipants', async () => getSandboxParticipantsTestData());
|
|
253
|
+
const authorisationServerId = 'efc44d17-d137-4d41-8601-80f632c1b109';
|
|
254
|
+
const callbackQuery = parse('?code=DdW810nrra6opXT2RNScp8IWqs-5J-Xhp0ASjxqi22O&state=e4362a1e5f8e131904e9f1fa68efa29b0347e9fb24d239fc4206aa9d0f72afa0&iss=https%3A%2F%2Fauth.bank4.directory.sandbox.connectid.com.au', true).query;
|
|
255
|
+
const codeVerifier = 'f32AYjAtjVvNmzCrr0mqJq2oSM4q3eq9W2STNhgkmu0';
|
|
256
|
+
const state = 'e4362a1e5f8e131904e9f1fa68efa29b0347e9fb24d239fc4206aa9d0f72afa0';
|
|
257
|
+
const nonce = 'aca08ef3106a1a027e723dedc6ccc22a3a58332af93485a3fcf2969c84a3e931';
|
|
258
|
+
await assert.rejects(async () => rpClient.retrieveTokens(authorisationServerId, callbackQuery, codeVerifier, state, nonce));
|
|
259
|
+
});
|
|
260
|
+
it.skip('should build a consolidated tokenset - NEEDS UPDATE for new TokenSet implementation', () => {
|
|
261
|
+
// TODO: Update this test to use the new TokenSet and ConsolidatedTokenSet classes
|
|
262
|
+
/*
|
|
263
|
+
const tokenSet = new TokenSet({
|
|
264
|
+
scope: 'openid',
|
|
265
|
+
expires_in: 3600,
|
|
266
|
+
token_type: 'bearer',
|
|
267
|
+
id_token:
|
|
268
|
+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjE2NTk2MzM4NTEyNzEtZmYyMDFhZWNkZSJ9.eyJzdWIiOiIwYWI5NTBkNjhjNDcwNTliMTZiMTkwNjY5OTFiZTI4ZGQ2NGU3YmY2Y2Q4N2NiOGJkMjYwMGUzZWQwMTNjMjc0IiwidmVyaWZpZWRfY2xhaW1zIjp7InZlcmlmaWNhdGlvbiI6eyJ0cnVzdF9mcmFtZXdvcmsiOiJhdV9jb25uZWN0aWQifSwiY2xhaW1zIjp7Im92ZXIxOCI6dHJ1ZSwiYmVuZWZpY2lhcnlfYWNjb3VudF9hdSI6eyJiZW5lZmljaWFyeV9uYW1lIjoiSm9obiBTbWl0aCIsImFjY291bnRfYnNiIjoiMTAwLTIwMCIsImFjY291bnRfbnVtYmVyIjoiMTIzNDU2NzgifX19LCJuYW1lIjoiVGl0bGUgR2l2ZW4gRmFtaWx5IiwiZ2l2ZW5fbmFtZSI6IkdpdmVuIiwibWlkZGxlX25hbWUiOiJNaWRkbGUiLCJmYW1pbHlfbmFtZSI6IkZhbWlseSIsInBob25lX251bWJlciI6Iis2MTQ4MDA4OTE2MSIsImVtYWlsIjoiZG9iYXBvMjA2NkB0ZXJrb2VyLmNvbSIsImFkZHJlc3MiOnsiY291bnRyeSI6IkF1c3RyYWxpYSIsImxvY2FsaXR5IjoiQ2l0eSIsInBvc3RhbF9jb2RlIjoiMTAwMCIsInJlZ2lvbiI6IlJlZ2lvbiIsInN0cmVldF9hZGRyZXNzIjoiU3RyZWV0IEFkZHJlc3MifSwiYmlydGhkYXRlIjoiMjAwMC0wMS0wMSIsInR4biI6Im8yVm5XMTkxUVFIdGVtWkZ4ajBqUHJnMmtlNGRtZVFnMXJsNm1kR3dVMnIiLCJhdXRoX3RpbWUiOjE2NzgzMzcyMjQsIm5vbmNlIjoiMTNmZjRkODU4ZGZjNjY0ODFhMzI4OTJlYzAxYTk2ZWUyZTAxYWVjYTllZDMwM2NkZWY1YzliNzRlZWE3ZGE5NiIsImF0X2hhc2giOiJ6MUhyMGUtbi1sV1U2TVJVU0lVaWxBIiwiYXVkIjoiMDkwZDQxYzYtZmMyNy00YjFlLTkxZTktMGZlY2ZjMjQwNjAxIiwiZXhwIjoxNjc4MzM3ODkxLCJpYXQiOjE2NzgzMzcyOTEsImlzcyI6Imh0dHBzOi8vYXV0aC5iYW5rMi5kaXJlY3Rvcnkuc2FuZGJveC5jb25uZWN0aWQuY29tLmF1In0.ECQ-DF-caZJymZJSiJQ19VY7PqSYYXm-FN20qV2_0w0',
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
const rpClient = withMockedDate(new RelyingPartyClientSdk(config))
|
|
272
|
+
|
|
273
|
+
// Example Referencing
|
|
274
|
+
const {
|
|
275
|
+
over18,
|
|
276
|
+
beneficiary_account_au,
|
|
277
|
+
birthdate,
|
|
278
|
+
txn,
|
|
279
|
+
} = rpClient["buildConsolidatedTokenSet"](tokenSet, '0ad8cca6-3363-4cd4-b452-527dc490b041').consolidatedClaims()
|
|
280
|
+
|
|
281
|
+
assert.equal(over18, true)
|
|
282
|
+
assert.deepEqual(beneficiary_account_au, {
|
|
283
|
+
beneficiary_name: 'John Smith',
|
|
284
|
+
account_bsb: '100-200',
|
|
285
|
+
account_number: '12345678',
|
|
286
|
+
})
|
|
287
|
+
assert.equal(birthdate, '2000-01-01')
|
|
288
|
+
assert.equal(txn, 'o2VnW191QQHtemZFxj0jPrg2ke4dmeQg1rl6mdGwU2r')
|
|
289
|
+
*/
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
describe('configureDefaultPurpose', () => {
|
|
293
|
+
it('should fail to initialise SDK with an invalid purpose in config', () => {
|
|
294
|
+
const invalidConfig = JSON.parse(JSON.stringify(config));
|
|
295
|
+
invalidConfig.data.purpose = 'aa';
|
|
296
|
+
assert.throws(() => {
|
|
297
|
+
new RelyingPartyClientSdk(invalidConfig);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
function getParticipantsTestData() {
|
|
302
|
+
return JSON.parse(JSON.stringify(participantsTestData));
|
|
303
|
+
}
|
|
304
|
+
function getSandboxParticipantsTestData() {
|
|
305
|
+
return JSON.parse(JSON.stringify(sandboxParticipantsTestData));
|
|
306
|
+
}
|
|
307
|
+
function getLargeParticipantsTestData() {
|
|
308
|
+
return JSON.parse(JSON.stringify(largeParticipantsTestData));
|
|
309
|
+
}
|
|
310
|
+
function withMockedDate(client) {
|
|
311
|
+
mock.method(client, 'getCurrentDate', () => new Date('2023-06-25'));
|
|
312
|
+
return client;
|
|
313
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import test, { describe } from 'node:test';
|
|
2
|
+
import { generatePushAuthorisationRequestParams } from '../utils/request-utils.js';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
describe('generatePushAuthorisationRequestParams', () => {
|
|
5
|
+
test('should generate request params', () => {
|
|
6
|
+
const { codeChallenge, codeVerifier, nonce, state } = generatePushAuthorisationRequestParams();
|
|
7
|
+
assert.ok(codeChallenge);
|
|
8
|
+
assert.ok(codeVerifier);
|
|
9
|
+
assert.ok(nonce);
|
|
10
|
+
assert.ok(state);
|
|
11
|
+
});
|
|
12
|
+
test('should generate nonce with 43 chars', () => {
|
|
13
|
+
const { nonce } = generatePushAuthorisationRequestParams();
|
|
14
|
+
assert.ok(nonce.length === 43);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getSystemInformation } from '../utils/system-information.js';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
describe('getSystemInformation', () => {
|
|
5
|
+
const USERAGENT_REGEX = /^\((darwin|Macintosh|Windows|Linux|linux|Other); .+; node \d+(\.\d+)*\)$/;
|
|
6
|
+
it('should return a user agent string', () => {
|
|
7
|
+
const systemInfo = getSystemInformation();
|
|
8
|
+
assert.match(systemInfo, USERAGENT_REGEX);
|
|
9
|
+
});
|
|
10
|
+
it('should match real world regex', () => {
|
|
11
|
+
assert.match('(darwin; Apple Silicon Mac OS X 10.15.7; node 16.13.0)', USERAGENT_REGEX);
|
|
12
|
+
});
|
|
13
|
+
it('should match gh action regex', () => {
|
|
14
|
+
assert.match('(linux; x64 6.5.0-1025-azure; node 18.20.6)', USERAGENT_REGEX);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { config } from '../config.js';
|
|
4
|
+
import { buildUserAgent, packageJsonVersion } from '../utils/user-agent.js';
|
|
5
|
+
import { version } from '../../package.json';
|
|
6
|
+
describe('buildUserAgent', () => {
|
|
7
|
+
it('should build user agent', () => {
|
|
8
|
+
const userAgent = buildUserAgent(config.data.client_id);
|
|
9
|
+
const regex = /(.*?)\/(.*?)\s(\(.*?\))\s(\+.*)/;
|
|
10
|
+
const match = userAgent.match(regex);
|
|
11
|
+
assert.ok(match, 'UserAgent does not match the expected format');
|
|
12
|
+
const version = match[2];
|
|
13
|
+
const platform = match[3];
|
|
14
|
+
assert.strictEqual(userAgent.startsWith('cid-rp-nodejs-sdk'), true);
|
|
15
|
+
assert.match(version, /^(\d+)\.(\d+)\.(\d+)$/);
|
|
16
|
+
assert.match(platform, /\(.+; .+; .+\)/);
|
|
17
|
+
assert.strictEqual(userAgent.endsWith(config.data.client_id), true);
|
|
18
|
+
});
|
|
19
|
+
it('should match package json version and user agent version', () => {
|
|
20
|
+
const packageJsonVersionFromUserAgent = packageJsonVersion;
|
|
21
|
+
assert.equal(packageJsonVersionFromUserAgent, version);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { validatePurpose, isValidCertificate } from '../validator.js';
|
|
4
|
+
describe('validateCertificate', () => {
|
|
5
|
+
it('should return false if certificateFilePath and certificateContent are not provided', () => {
|
|
6
|
+
assert.strictEqual(isValidCertificate(undefined, undefined), false);
|
|
7
|
+
});
|
|
8
|
+
it('should return true if certificateFilePath is provided', () => {
|
|
9
|
+
assert.strictEqual(isValidCertificate('./certs/transport.key', undefined), true);
|
|
10
|
+
});
|
|
11
|
+
it('should return true if certificateContent is provided', () => {
|
|
12
|
+
assert.strictEqual(isValidCertificate(undefined, 'thisIsAfakeCertificate'), true);
|
|
13
|
+
});
|
|
14
|
+
it('should return true if certificateContent and certificateFilePath are provided', () => {
|
|
15
|
+
assert.strictEqual(isValidCertificate('./certs/transport.key', 'thisIsAfakeCertificate'), true);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('validatePurpose', () => {
|
|
19
|
+
it('should reject when purpose length < 3', () => {
|
|
20
|
+
assert.strictEqual(validatePurpose('aa'), 'INVALID_LENGTH');
|
|
21
|
+
});
|
|
22
|
+
it('should reject when purpose length > 300', () => {
|
|
23
|
+
assert.strictEqual(validatePurpose('a'.repeat(301)), 'INVALID_LENGTH');
|
|
24
|
+
});
|
|
25
|
+
const specialChars = ['<', '>', '(', ')', '{', '}', "'", '\\'];
|
|
26
|
+
specialChars.forEach((char) => {
|
|
27
|
+
it('should reject special character', () => {
|
|
28
|
+
const purpose = `valid string ${char} more stuff`;
|
|
29
|
+
assert.strictEqual(validatePurpose(purpose), 'INVALID_CHARACTERS');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
it('should accept when purpose length = 3', () => {
|
|
33
|
+
assert.strictEqual(validatePurpose('aaa'), 'VALID');
|
|
34
|
+
});
|
|
35
|
+
it('should accept when purpose length = 300', () => {
|
|
36
|
+
assert.strictEqual(validatePurpose('a'.repeat(300)), 'VALID');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { IdTokenClaims
|
|
1
|
+
import { IdTokenClaims } from './model/claims.js';
|
|
2
|
+
export type { IdTokenClaims, AddressClaim, VerifiedClaims } from './model/claims.js';
|
|
3
|
+
export type { CallbackParams } from './model/callback-params.js';
|
|
4
|
+
export type { TokenResponse } from './model/token-response.js';
|
|
2
5
|
export type RelyingPartyClientSdkConfig = {
|
|
3
6
|
data: {
|
|
4
7
|
ca_pem?: string;
|
|
@@ -20,35 +23,7 @@ export type RelyingPartyClientSdkConfig = {
|
|
|
20
23
|
log_level: 'debug' | 'info';
|
|
21
24
|
enable_auto_compliance_verification: boolean;
|
|
22
25
|
purpose?: string;
|
|
23
|
-
|
|
24
|
-
client: {
|
|
25
|
-
client_id: string;
|
|
26
|
-
organisation_id: string;
|
|
27
|
-
jwks_uri: string;
|
|
28
|
-
redirect_uris: string[];
|
|
29
|
-
organisation_name: string;
|
|
30
|
-
organisation_number: string;
|
|
31
|
-
software_description: string;
|
|
32
|
-
software_roles: string[];
|
|
33
|
-
application_type: 'web';
|
|
34
|
-
grant_types: ['client_credentials', 'authorization_code', 'implicit'];
|
|
35
|
-
id_token_signed_response_alg: 'PS256';
|
|
36
|
-
post_logout_redirect_uris: [];
|
|
37
|
-
require_auth_time: false;
|
|
38
|
-
response_types: ['code id_token', 'code'];
|
|
39
|
-
subject_type: 'public';
|
|
40
|
-
token_endpoint_auth_method: 'private_key_jwt';
|
|
41
|
-
token_endpoint_auth_signing_alg: 'PS256';
|
|
42
|
-
introspection_endpoint_auth_method: 'private_key_jwt';
|
|
43
|
-
revocation_endpoint_auth_method: 'private_key_jwt';
|
|
44
|
-
request_object_signing_alg: 'PS256';
|
|
45
|
-
require_signed_request_object: true;
|
|
46
|
-
require_pushed_authorization_requests: true;
|
|
47
|
-
authorization_signed_response_alg: 'PS256';
|
|
48
|
-
tls_client_certificate_bound_access_tokens: true;
|
|
49
|
-
backchannel_user_code_parameter: false;
|
|
50
|
-
scope: 'openid';
|
|
51
|
-
};
|
|
26
|
+
client_id: string;
|
|
52
27
|
};
|
|
53
28
|
};
|
|
54
29
|
export type Participant = {
|
|
@@ -152,9 +127,63 @@ export type ClaimsRequest = {
|
|
|
152
127
|
};
|
|
153
128
|
};
|
|
154
129
|
};
|
|
155
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Consolidated Token Set
|
|
132
|
+
*
|
|
133
|
+
* Represents a complete token response with additional helper methods.
|
|
134
|
+
* Combines token response data with parsed ID token claims.
|
|
135
|
+
*/
|
|
136
|
+
export interface ConsolidatedTokenSet {
|
|
137
|
+
/**
|
|
138
|
+
* The access token issued by the authorization server.
|
|
139
|
+
*/
|
|
140
|
+
readonly access_token?: string;
|
|
141
|
+
/**
|
|
142
|
+
* The type of token issued (typically "Bearer").
|
|
143
|
+
*/
|
|
144
|
+
readonly token_type?: string;
|
|
145
|
+
/**
|
|
146
|
+
* The lifetime in seconds of the access token.
|
|
147
|
+
*/
|
|
148
|
+
readonly expires_in?: number;
|
|
149
|
+
/**
|
|
150
|
+
* The refresh token for obtaining new access tokens.
|
|
151
|
+
*/
|
|
152
|
+
readonly refresh_token?: string;
|
|
153
|
+
/**
|
|
154
|
+
* The scope of the access token.
|
|
155
|
+
*/
|
|
156
|
+
readonly scope?: string;
|
|
157
|
+
/**
|
|
158
|
+
* The ID token as a JWT string.
|
|
159
|
+
*/
|
|
160
|
+
readonly id_token?: string;
|
|
161
|
+
/**
|
|
162
|
+
* The x-fapi-interaction-id from the token response.
|
|
163
|
+
*/
|
|
164
|
+
readonly xFapiInteractionId: string;
|
|
165
|
+
/**
|
|
166
|
+
* Checks if the access token has expired.
|
|
167
|
+
*
|
|
168
|
+
* @returns true if the token is expired, false otherwise
|
|
169
|
+
*/
|
|
170
|
+
expired(): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Returns the parsed ID token claims.
|
|
173
|
+
*
|
|
174
|
+
* @returns Parsed ID token claims
|
|
175
|
+
*/
|
|
176
|
+
claims(): IdTokenClaims;
|
|
177
|
+
/**
|
|
178
|
+
* Returns consolidated claims with verified_claims merged into top level.
|
|
179
|
+
*
|
|
180
|
+
* This is useful for accessing extended claims directly without
|
|
181
|
+
* navigating the verified_claims structure.
|
|
182
|
+
*
|
|
183
|
+
* @returns Consolidated claims object
|
|
184
|
+
*/
|
|
156
185
|
consolidatedClaims(): IdTokenClaims;
|
|
157
|
-
}
|
|
186
|
+
}
|
|
158
187
|
export type CertificationFilter = {
|
|
159
188
|
profileVariant: string;
|
|
160
189
|
profileType: string;
|
package/src/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { PushAuthorisationRequestParams } from '../types';
|
|
1
|
+
import { PushAuthorisationRequestParams } from '../types.js';
|
|
2
2
|
export declare const generatePushAuthorisationRequestParams: () => PushAuthorisationRequestParams;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PkceHelper } from '../crypto/pkce-helper.js';
|
|
2
|
+
export const generatePushAuthorisationRequestParams = () => {
|
|
3
|
+
const state = PkceHelper.generateState();
|
|
4
|
+
const nonce = PkceHelper.generateNonce();
|
|
5
|
+
const codeVerifier = PkceHelper.generateCodeVerifier();
|
|
6
|
+
const codeChallenge = PkceHelper.generateCodeChallenge(codeVerifier);
|
|
7
|
+
return { state, nonce, codeVerifier, codeChallenge };
|
|
8
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const packageJsonVersion = "
|
|
1
|
+
export declare const packageJsonVersion = "5.0.0";
|
|
2
2
|
export declare const buildUserAgent: (clientId: string) => string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { getSystemInformation } from './system-information.js';
|
|
2
2
|
// important: Update this every time the package version changes
|
|
3
|
-
export const packageJsonVersion = '
|
|
3
|
+
export const packageJsonVersion = '5.0.0';
|
|
4
4
|
export const buildUserAgent = (clientId) => `cid-rp-nodejs-sdk/${packageJsonVersion} ${getSystemInformation()} +${clientId}`;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { CallbackParamsType } from 'openid-client';
|
|
2
|
-
import { AuthorisationServer, ConsolidatedTokenSet, Participant, RelyingPartyClientSdkConfig } from './types';
|
|
3
|
-
export default class RelyingPartyClientSdk {
|
|
4
|
-
private readonly logger;
|
|
5
|
-
private config;
|
|
6
|
-
private readonly transportKey;
|
|
7
|
-
private readonly transportPem;
|
|
8
|
-
private readonly signingKey;
|
|
9
|
-
private readonly caPem;
|
|
10
|
-
private readonly purpose;
|
|
11
|
-
private participantFilters;
|
|
12
|
-
private readonly default_cache_ttl;
|
|
13
|
-
private cachedParticipantsExpiry;
|
|
14
|
-
private cachedParticipants;
|
|
15
|
-
constructor(config: RelyingPartyClientSdkConfig);
|
|
16
|
-
getParticipants(): Promise<Participant[]>;
|
|
17
|
-
getFallbackProviderParticipants(): Promise<Participant[]>;
|
|
18
|
-
getCurrentDate(): Date;
|
|
19
|
-
fetchParticipants(participantsUri: string): Promise<Participant[]>;
|
|
20
|
-
private retrieveFullParticipantsList;
|
|
21
|
-
sendPushedAuthorisationRequest(authServerId: string, essentialClaims: string[], voluntaryClaims?: string[], purpose?: string): Promise<{
|
|
22
|
-
authUrl: string;
|
|
23
|
-
code_verifier: string;
|
|
24
|
-
state: string;
|
|
25
|
-
nonce: string;
|
|
26
|
-
xFapiInteractionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
27
|
-
}>;
|
|
28
|
-
retrieveTokens(authorisationServerId: string, requestParams: CallbackParamsType, codeVerifier: string, state: string, nonce: string): Promise<ConsolidatedTokenSet>;
|
|
29
|
-
private buildConsolidatedTokenSet;
|
|
30
|
-
getAuthServerDetails(authServerId: string): Promise<AuthorisationServer>;
|
|
31
|
-
private generateClaimsRequest;
|
|
32
|
-
getUserInfo(authorisationServerId: string, accessToken: string): Promise<import("openid-client").UserinfoResponse<import("openid-client").UnknownObject, import("openid-client").UnknownObject>>;
|
|
33
|
-
private getKeyset;
|
|
34
|
-
private setupClient;
|
|
35
|
-
private generateRequest;
|
|
36
|
-
private generateXFapiInteractionId;
|
|
37
|
-
}
|