@connectid-tools/rp-nodejs-sdk 4.2.0 → 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.
Files changed (98) hide show
  1. package/README.md +284 -237
  2. package/package.json +7 -5
  3. package/{config.js → src/config.js} +2 -31
  4. package/src/conformance/api/conformance-api.d.ts +38 -0
  5. package/src/conformance/api/conformance-api.js +53 -0
  6. package/src/conformance/config.json +60 -0
  7. package/src/conformance/conformance-config.d.ts +2 -0
  8. package/src/conformance/conformance-config.js +34 -0
  9. package/src/conformance/conformance.test.js +101 -0
  10. package/src/conformance/variant.json +1 -0
  11. package/src/crypto/crypto-loader.d.ts +32 -0
  12. package/src/crypto/crypto-loader.js +49 -0
  13. package/src/crypto/jwt-helper.d.ts +61 -0
  14. package/src/crypto/jwt-helper.js +92 -0
  15. package/src/crypto/pkce-helper.d.ts +43 -0
  16. package/src/crypto/pkce-helper.js +75 -0
  17. package/src/endpoints/participants-endpoint.d.ts +55 -0
  18. package/src/endpoints/participants-endpoint.js +137 -0
  19. package/src/endpoints/pushed-authorisation-request-endpoint.d.ts +87 -0
  20. package/src/endpoints/pushed-authorisation-request-endpoint.js +192 -0
  21. package/src/endpoints/retrieve-token-endpoint.d.ts +66 -0
  22. package/src/endpoints/retrieve-token-endpoint.js +159 -0
  23. package/src/endpoints/userinfo-endpoint.d.ts +24 -0
  24. package/src/endpoints/userinfo-endpoint.js +50 -0
  25. package/src/fapi/fapi-utils.d.ts +6 -0
  26. package/src/fapi/fapi-utils.js +9 -0
  27. package/src/http/http-client-extensions.d.ts +60 -0
  28. package/src/http/http-client-extensions.js +106 -0
  29. package/src/http/http-client-factory.d.ts +27 -0
  30. package/src/http/http-client-factory.js +45 -0
  31. package/src/integration/integration.test.d.ts +1 -0
  32. package/src/integration/integration.test.js +30 -0
  33. package/src/model/callback-params.d.ts +31 -0
  34. package/src/model/callback-params.js +1 -0
  35. package/src/model/claims.d.ts +100 -0
  36. package/src/model/claims.js +1 -0
  37. package/src/model/consolidated-token-set.d.ts +74 -0
  38. package/src/model/consolidated-token-set.js +100 -0
  39. package/src/model/discovery-service.d.ts +46 -0
  40. package/src/model/discovery-service.js +112 -0
  41. package/src/model/issuer-metadata.d.ts +165 -0
  42. package/src/model/issuer-metadata.js +1 -0
  43. package/src/model/jwks.d.ts +12 -0
  44. package/src/model/jwks.js +1 -0
  45. package/src/model/token-response.d.ts +31 -0
  46. package/src/model/token-response.js +1 -0
  47. package/src/model/token-set.d.ts +73 -0
  48. package/src/model/token-set.js +179 -0
  49. package/src/relying-party-client-sdk.d.ts +68 -0
  50. package/src/relying-party-client-sdk.js +150 -0
  51. package/src/test-data/large-participants-test-data.d.ts +865 -0
  52. package/src/test-data/large-participants-test-data.js +18907 -0
  53. package/src/test-data/participants-test-data.d.ts +149 -0
  54. package/src/test-data/participants-test-data.js +458 -0
  55. package/src/test-data/sandbox-participants-test-data.d.ts +865 -0
  56. package/src/test-data/sandbox-participants-test-data.js +3794 -0
  57. package/src/tests/cert-utils.test.d.ts +1 -0
  58. package/src/tests/cert-utils.test.js +13 -0
  59. package/src/tests/functional-utils.test.d.ts +1 -0
  60. package/src/tests/functional-utils.test.js +13 -0
  61. package/src/tests/participant-filters.test.d.ts +1 -0
  62. package/src/tests/participant-filters.test.js +151 -0
  63. package/src/tests/pushed-authorisation-request-endpoint.test.d.ts +1 -0
  64. package/src/tests/pushed-authorisation-request-endpoint.test.js +159 -0
  65. package/src/tests/relying-party-client-sdk.test.d.ts +1 -0
  66. package/src/tests/relying-party-client-sdk.test.js +313 -0
  67. package/src/tests/request-utils.test.d.ts +1 -0
  68. package/src/tests/request-utils.test.js +16 -0
  69. package/src/tests/system-information.test.d.ts +1 -0
  70. package/src/tests/system-information.test.js +16 -0
  71. package/src/tests/user-agent.test.d.ts +1 -0
  72. package/src/tests/user-agent.test.js +23 -0
  73. package/src/tests/validator.test.d.ts +1 -0
  74. package/src/tests/validator.test.js +38 -0
  75. package/{types.d.ts → src/types.d.ts} +61 -32
  76. package/src/types.js +1 -0
  77. package/{utils → src/utils}/request-utils.d.ts +1 -1
  78. package/src/utils/request-utils.js +8 -0
  79. package/{utils → src/utils}/user-agent.d.ts +1 -1
  80. package/src/utils/user-agent.js +4 -0
  81. package/relying-party-client-sdk.d.ts +0 -37
  82. package/relying-party-client-sdk.js +0 -364
  83. package/utils/request-utils.js +0 -8
  84. package/utils/user-agent.js +0 -6
  85. /package/{config.d.ts → src/config.d.ts} +0 -0
  86. /package/{types.js → src/conformance/conformance.test.d.ts} +0 -0
  87. /package/{filter → src/filter}/participant-filters.d.ts +0 -0
  88. /package/{filter → src/filter}/participant-filters.js +0 -0
  89. /package/{logger.d.ts → src/logger.d.ts} +0 -0
  90. /package/{logger.js → src/logger.js} +0 -0
  91. /package/{utils → src/utils}/cert-utils.d.ts +0 -0
  92. /package/{utils → src/utils}/cert-utils.js +0 -0
  93. /package/{utils → src/utils}/functional-utils.d.ts +0 -0
  94. /package/{utils → src/utils}/functional-utils.js +0 -0
  95. /package/{utils → src/utils}/system-information.d.ts +0 -0
  96. /package/{utils → src/utils}/system-information.js +0 -0
  97. /package/{validator.d.ts → src/validator.d.ts} +0 -0
  98. /package/{validator.js → src/validator.js} +0 -0
@@ -0,0 +1,179 @@
1
+ import { jwtVerify, decodeProtectedHeader, importJWK } from 'jose';
2
+ /**
3
+ * Token Set
4
+ *
5
+ * Represents an OAuth 2.0 / OIDC token response with validation capabilities.
6
+ * Handles ID token validation and claims extraction.
7
+ */
8
+ export class TokenSet {
9
+ /**
10
+ * Creates a new TokenSet from a token response.
11
+ *
12
+ * @param tokenResponse - Raw token response from the token endpoint
13
+ */
14
+ constructor(tokenResponse) {
15
+ this.access_token = tokenResponse.access_token;
16
+ this.token_type = tokenResponse.token_type;
17
+ this.expires_in = tokenResponse.expires_in;
18
+ this.refresh_token = tokenResponse.refresh_token;
19
+ this.scope = tokenResponse.scope;
20
+ this.id_token = tokenResponse.id_token;
21
+ this.tokenIssuedAt = Math.floor(Date.now() / 1000);
22
+ }
23
+ /**
24
+ * Validates the ID token.
25
+ *
26
+ * Performs the following validations:
27
+ * - Algorithm validation against allowed algorithms
28
+ * - Signature verification using JWKS
29
+ * - Issuer validation
30
+ * - Audience validation
31
+ * - Nonce validation
32
+ * - Timestamp validation (iat, exp)
33
+ *
34
+ * @param jwks - JSON Web Key Set for signature verification
35
+ * @param expectedIssuer - Expected issuer claim value
36
+ * @param expectedAudience - Expected audience claim value
37
+ * @param expectedNonce - Expected nonce value
38
+ * @param allowedAlgorithms - Optional list of allowed signing algorithms from discovery document
39
+ * @throws Error if validation fails
40
+ */
41
+ async validate(jwks, expectedIssuer, expectedAudience, expectedNonce, allowedAlgorithms) {
42
+ if (!this.id_token) {
43
+ throw new Error('No id_token to validate');
44
+ }
45
+ try {
46
+ // Decode header to check algorithm before verification
47
+ const header = decodeProtectedHeader(this.id_token);
48
+ // Validate algorithm if allowed algorithms are provided
49
+ if (allowedAlgorithms && allowedAlgorithms.length > 0) {
50
+ if (!header.alg) {
51
+ throw new Error('ID token missing alg in header');
52
+ }
53
+ const isAllowed = allowedAlgorithms.some((alg) => alg.toLowerCase() === header.alg.toLowerCase());
54
+ if (!isAllowed) {
55
+ throw new Error(`ID token algorithm '${header.alg}' is not one of the allowed algorithms: ${allowedAlgorithms.join(', ')}`);
56
+ }
57
+ }
58
+ // Select the appropriate key from JWKS
59
+ const key = await this.selectKey(jwks);
60
+ // Verify signature and standard claims
61
+ const { payload } = await jwtVerify(this.id_token, key, {
62
+ issuer: expectedIssuer,
63
+ audience: expectedAudience,
64
+ algorithms: ['PS256', 'RS256'], // Accept both algorithms
65
+ });
66
+ // Validate nonce
67
+ if (payload.nonce !== expectedNonce) {
68
+ throw new Error(`Nonce mismatch: expected ${expectedNonce}, got ${payload.nonce}`);
69
+ }
70
+ // Validate audience claim per OpenID Connect Core 3.1.3.7
71
+ // If aud is an array, all audiences must be trusted (only our client ID is trusted)
72
+ // and azp claim should be present
73
+ if (Array.isArray(payload.aud)) {
74
+ // Check if all audiences are trusted (only client ID is trusted)
75
+ const untrustedAudiences = payload.aud.filter((aud) => aud !== expectedAudience);
76
+ if (untrustedAudiences.length > 0) {
77
+ throw new Error(`ID token contains untrusted audiences: ${untrustedAudiences.join(', ')}`);
78
+ }
79
+ // Per OIDC spec clause 4: if multiple audiences, azp should be present
80
+ if (payload.aud.length > 1 && !payload.azp) {
81
+ throw new Error('ID token contains multiple audiences but azp claim is missing');
82
+ }
83
+ }
84
+ // Validate required claims are present
85
+ const now = Math.floor(Date.now() / 1000);
86
+ if (!payload.iat) {
87
+ throw new Error('ID token missing iat claim');
88
+ }
89
+ if (!payload.exp) {
90
+ throw new Error('ID token missing exp claim');
91
+ }
92
+ // Validate iat (must not be more than 10 minutes old per Java SDK)
93
+ if (now - payload.iat > 600) {
94
+ throw new Error(`ID token iat is too old: issued at ${payload.iat}, current time ${now}`);
95
+ }
96
+ // Validate exp (must not be more than 5 minutes in the past - clock skew tolerance)
97
+ if (payload.exp < now - 300) {
98
+ throw new Error(`ID token expired more than 5 minutes ago: exp ${payload.exp}, current time ${now}`);
99
+ }
100
+ // Store validated claims
101
+ this.jwtPayload = payload;
102
+ this.idTokenClaims = payload;
103
+ }
104
+ catch (error) {
105
+ throw new Error(`ID token validation failed: ${error instanceof Error ? error.message : String(error)}`);
106
+ }
107
+ }
108
+ /**
109
+ * Returns the parsed ID token claims.
110
+ *
111
+ * Must call validate() first.
112
+ *
113
+ * @returns Parsed and validated ID token claims
114
+ * @throws Error if token has not been validated
115
+ */
116
+ claims() {
117
+ if (!this.idTokenClaims) {
118
+ throw new Error('ID token has not been validated. Call validate() first.');
119
+ }
120
+ return this.idTokenClaims;
121
+ }
122
+ /**
123
+ * Checks if the access token has expired.
124
+ *
125
+ * @returns true if the token is expired, false otherwise
126
+ */
127
+ expired() {
128
+ if (!this.expires_in) {
129
+ // If no expires_in, assume token doesn't expire
130
+ return false;
131
+ }
132
+ const now = Math.floor(Date.now() / 1000);
133
+ const expiresAt = this.tokenIssuedAt + this.expires_in;
134
+ return now >= expiresAt;
135
+ }
136
+ /**
137
+ * Selects the appropriate key from JWKS for verification.
138
+ *
139
+ * Matches based on:
140
+ * - kid (key ID)
141
+ * - alg (algorithm)
142
+ * - use (key usage - should be 'sig')
143
+ *
144
+ * @param jwks - JSON Web Key Set
145
+ * @returns Imported crypto key for verification
146
+ * @throws Error if no matching key is found
147
+ */
148
+ async selectKey(jwks) {
149
+ if (!this.id_token) {
150
+ throw new Error('No id_token present');
151
+ }
152
+ // Decode header to get kid and alg
153
+ const header = decodeProtectedHeader(this.id_token);
154
+ if (!header.kid) {
155
+ throw new Error('ID token missing kid in header');
156
+ }
157
+ // Find matching key
158
+ const matchingKey = jwks.keys.find((key) => {
159
+ // Match by kid (required)
160
+ if (key.kid !== header.kid) {
161
+ return false;
162
+ }
163
+ // Match by alg if present in key
164
+ if (key.alg && key.alg !== header.alg) {
165
+ return false;
166
+ }
167
+ // Match by use if present (should be 'sig' for signing)
168
+ if (key.use && key.use !== 'sig') {
169
+ return false;
170
+ }
171
+ return true;
172
+ });
173
+ if (!matchingKey) {
174
+ throw new Error(`No matching key found in JWKS for kid: ${header.kid}, alg: ${header.alg}`);
175
+ }
176
+ // Import the JWK for verification
177
+ return importJWK(matchingKey, header.alg);
178
+ }
179
+ }
@@ -0,0 +1,68 @@
1
+ import { CallbackParams, ConsolidatedTokenSet, Participant, RelyingPartyClientSdkConfig } from './types.js';
2
+ export default class RelyingPartyClientSdk {
3
+ private readonly logger;
4
+ private config;
5
+ private readonly purpose;
6
+ private readonly participantsEndpoint;
7
+ private readonly pushedAuthorisationRequestEndpoint;
8
+ private readonly retrieveTokenEndpoint;
9
+ private readonly userInfoEndpoint;
10
+ private readonly httpClient;
11
+ private readonly jwtHelper;
12
+ constructor(config: RelyingPartyClientSdkConfig);
13
+ /**
14
+ * Get the list of participating identity providers within the scheme.
15
+ *
16
+ * Applies filtering based on SDK configuration.
17
+ *
18
+ * @returns List of participants
19
+ */
20
+ getParticipants(): Promise<Participant[]>;
21
+ /**
22
+ * Get the list of fallback provider participants.
23
+ *
24
+ * @returns List of fallback provider participants
25
+ */
26
+ getFallbackProviderParticipants(): Promise<Participant[]>;
27
+ /**
28
+ * Sends a Pushed Authorization Request (PAR).
29
+ *
30
+ * @param authServerId - Authorization server ID
31
+ * @param essentialClaims - Claims that must be provided
32
+ * @param voluntaryClaims - Claims that are optional
33
+ * @param purpose - Purpose string for data sharing
34
+ * @returns Object containing authorization URL and PKCE parameters
35
+ */
36
+ sendPushedAuthorisationRequest(authServerId: string, essentialClaims: string[], voluntaryClaims?: string[], purpose?: string): Promise<{
37
+ authUrl: string;
38
+ codeVerifier: string;
39
+ state: string;
40
+ nonce: string;
41
+ xFapiInteractionId: string;
42
+ }>;
43
+ /**
44
+ * Retrieves tokens using an authorisation code.
45
+ *
46
+ * @param authorisationServerId - Authorisation server ID
47
+ * @param requestParams - OAuth callback parameters
48
+ * @param codeVerifier - PKCE code verifier from PAR
49
+ * @param state - State parameter from PAR
50
+ * @param nonce - Nonce parameter from PAR
51
+ * @returns Consolidated token set with validated claims
52
+ */
53
+ retrieveTokens(authorisationServerId: string, requestParams: CallbackParams, codeVerifier: string, state: string, nonce: string): Promise<ConsolidatedTokenSet>;
54
+ /**
55
+ * Retrieves user information from the UserInfo endpoint.
56
+ *
57
+ * @param authorisationServerId - Authorization server ID
58
+ * @param accessToken - Access token
59
+ * @returns UserInfo claims
60
+ */
61
+ getUserInfo(authorisationServerId: string, accessToken: string): Promise<Record<string, unknown>>;
62
+ /**
63
+ * Gets the current date (for testing purposes).
64
+ *
65
+ * @returns Current date
66
+ */
67
+ getCurrentDate(): Date;
68
+ }
@@ -0,0 +1,150 @@
1
+ import { getCertificate } from './utils/cert-utils.js';
2
+ import { getLogger } from './logger.js';
3
+ import ParticipantFilters from './filter/participant-filters.js';
4
+ import { illegalPurposeChars, isValidCertificate, validatePurpose } from './validator.js';
5
+ import { CryptoLoader } from './crypto/crypto-loader.js';
6
+ import { JwtHelper } from './crypto/jwt-helper.js';
7
+ import { HttpClientFactory } from './http/http-client-factory.js';
8
+ import { ParticipantsEndpoint } from './endpoints/participants-endpoint.js';
9
+ import { PushedAuthorisationRequestEndpoint } from './endpoints/pushed-authorisation-request-endpoint.js';
10
+ import { RetrieveTokenEndpoint } from './endpoints/retrieve-token-endpoint.js';
11
+ import { UserInfoEndpoint } from './endpoints/userinfo-endpoint.js';
12
+ export default class RelyingPartyClientSdk {
13
+ constructor(config) {
14
+ this.purpose = 'verifying your identity';
15
+ this.config = config;
16
+ // Validate certificates
17
+ if (!isValidCertificate(this.config.data.transport_key, this.config.data.transport_key_content)) {
18
+ throw new Error('Either transport_key or transport_key_content must be provided');
19
+ }
20
+ if (!isValidCertificate(this.config.data.transport_pem, this.config.data.transport_pem_content)) {
21
+ throw new Error('Either transport_pem or transport_pem_content must be provided');
22
+ }
23
+ if (!isValidCertificate(this.config.data.signing_key, this.config.data.signing_key_content)) {
24
+ throw new Error('Either signing_key or signing_key_content must be provided');
25
+ }
26
+ if (!isValidCertificate(this.config.data.ca_pem, this.config.data.ca_pem_content)) {
27
+ throw new Error('Either ca_pem or ca_pem_content must be provided');
28
+ }
29
+ this.logger = getLogger(this.config.data.log_level);
30
+ this.logger.info(`Creating RelyingPartyClientSdk - version ${process.env.SDK_VERSION}`);
31
+ // Validate and set purpose
32
+ if (this.config.data.purpose) {
33
+ const purposeValidation = validatePurpose(this.config.data.purpose);
34
+ if (purposeValidation === 'INVALID_LENGTH') {
35
+ this.logger.warn('Purpose must be between 3 and 300 characters');
36
+ throw new Error(`Invalid purpose supplied in config: ${this.config.data.purpose}`);
37
+ }
38
+ if (purposeValidation === 'INVALID_CHARACTERS') {
39
+ this.logger.warn(`Purpose cannot contain any of the following characters: ${illegalPurposeChars.join(',')}, purpose supplied: [${this.config.data.purpose}]`);
40
+ throw new Error(`Invalid purpose supplied in config: ${this.config.data.purpose}`);
41
+ }
42
+ this.purpose = this.config.data.purpose;
43
+ this.logger.info(`Using default purpose supplied in config: ${this.purpose}`);
44
+ }
45
+ else {
46
+ this.logger.info(`Using built-in default purpose: ${this.purpose}`);
47
+ }
48
+ // Log filtering configuration
49
+ if (this.config.data.include_uncertified_participants) {
50
+ this.logger.info('Identity provider list will not be filtered as include_uncertified_participants=true');
51
+ }
52
+ else {
53
+ if (this.config.data.required_claims) {
54
+ this.logger.info(`Identity provider list will be filtered for participants that support the following claims: ${JSON.stringify(this.config.data.required_claims)}`);
55
+ }
56
+ if (this.config.data.required_participant_certifications) {
57
+ this.logger.info(`Identity provider list will be filtered for participants that support the following certifications: ${JSON.stringify(this.config.data.required_participant_certifications)}`);
58
+ }
59
+ }
60
+ // Log certificate source
61
+ this.logger.info(`Using ${this.config.data.transport_key_content ? 'transport_key_content' : 'transport_key'} config prop`);
62
+ this.logger.info(`Using ${this.config.data.transport_pem_content ? 'transport_pem_content' : 'transport_pem'} config prop`);
63
+ this.logger.info(`Using ${this.config.data.ca_pem_content ? 'ca_pem_content' : 'ca_pem'} config prop`);
64
+ this.logger.info(`Using ${this.config.data.signing_key_content ? 'signing_key_content' : 'signing_key'} config prop`);
65
+ // Initialize crypto
66
+ const signingKeyObject = CryptoLoader.loadPrivateKey(getCertificate(this.config.data.signing_key, this.config.data.signing_key_content));
67
+ // Initialize JWT helper
68
+ this.jwtHelper = new JwtHelper(signingKeyObject, this.config.data.signing_kid, this.config.data.client_id);
69
+ // Initialize HTTP client
70
+ this.httpClient = HttpClientFactory.createClient({
71
+ transportKey: getCertificate(this.config.data.transport_key, this.config.data.transport_key_content),
72
+ transportPem: getCertificate(this.config.data.transport_pem, this.config.data.transport_pem_content),
73
+ caPem: getCertificate(this.config.data.ca_pem, this.config.data.ca_pem_content),
74
+ clientId: this.config.data.client_id,
75
+ });
76
+ // Initialize endpoints
77
+ this.participantsEndpoint = new ParticipantsEndpoint(this.config, new ParticipantFilters(), this.httpClient, this.logger, () => this.getCurrentDate());
78
+ this.pushedAuthorisationRequestEndpoint = new PushedAuthorisationRequestEndpoint(this.config, this.httpClient, this.jwtHelper, this.logger, this.participantsEndpoint);
79
+ this.retrieveTokenEndpoint = new RetrieveTokenEndpoint(this.config, this.httpClient, this.jwtHelper, this.logger, this.participantsEndpoint);
80
+ this.userInfoEndpoint = new UserInfoEndpoint(this.httpClient, this.logger, this.config.data.client_id, this.participantsEndpoint);
81
+ }
82
+ /**
83
+ * Get the list of participating identity providers within the scheme.
84
+ *
85
+ * Applies filtering based on SDK configuration.
86
+ *
87
+ * @returns List of participants
88
+ */
89
+ async getParticipants() {
90
+ return this.participantsEndpoint.getParticipants();
91
+ }
92
+ /**
93
+ * Get the list of fallback provider participants.
94
+ *
95
+ * @returns List of fallback provider participants
96
+ */
97
+ async getFallbackProviderParticipants() {
98
+ return this.participantsEndpoint.getFallbackProviderParticipants();
99
+ }
100
+ /**
101
+ * Sends a Pushed Authorization Request (PAR).
102
+ *
103
+ * @param authServerId - Authorization server ID
104
+ * @param essentialClaims - Claims that must be provided
105
+ * @param voluntaryClaims - Claims that are optional
106
+ * @param purpose - Purpose string for data sharing
107
+ * @returns Object containing authorization URL and PKCE parameters
108
+ */
109
+ async sendPushedAuthorisationRequest(authServerId, essentialClaims, voluntaryClaims = [], purpose = this.purpose) {
110
+ const { authUrl, codeVerifier, state, nonce, xFapiInteractionId } = await this.pushedAuthorisationRequestEndpoint.sendPushedAuthorisationRequest(authServerId, essentialClaims, voluntaryClaims, purpose);
111
+ return {
112
+ authUrl,
113
+ codeVerifier,
114
+ state,
115
+ nonce,
116
+ xFapiInteractionId,
117
+ };
118
+ }
119
+ /**
120
+ * Retrieves tokens using an authorisation code.
121
+ *
122
+ * @param authorisationServerId - Authorisation server ID
123
+ * @param requestParams - OAuth callback parameters
124
+ * @param codeVerifier - PKCE code verifier from PAR
125
+ * @param state - State parameter from PAR
126
+ * @param nonce - Nonce parameter from PAR
127
+ * @returns Consolidated token set with validated claims
128
+ */
129
+ async retrieveTokens(authorisationServerId, requestParams, codeVerifier, state, nonce) {
130
+ return this.retrieveTokenEndpoint.retrieveTokens(authorisationServerId, requestParams, codeVerifier, state, nonce);
131
+ }
132
+ /**
133
+ * Retrieves user information from the UserInfo endpoint.
134
+ *
135
+ * @param authorisationServerId - Authorization server ID
136
+ * @param accessToken - Access token
137
+ * @returns UserInfo claims
138
+ */
139
+ async getUserInfo(authorisationServerId, accessToken) {
140
+ return this.userInfoEndpoint.getUserInfo(authorisationServerId, accessToken);
141
+ }
142
+ /**
143
+ * Gets the current date (for testing purposes).
144
+ *
145
+ * @returns Current date
146
+ */
147
+ getCurrentDate() {
148
+ return new Date();
149
+ }
150
+ }