Skip to content

Commit 4c30043

Browse files
committed
Add unit tests and rename env var to GRIST_OIDC_SP_HTTP_TIMEOUT
1 parent 246e9eb commit 4c30043

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

app/server/lib/OIDCConfig.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@
4747
* A JSON object with extra client metadata to pass to openid-client. Optional.
4848
* Be aware that setting this object may override any other values passed to the openid client.
4949
* More info: https://github.com/panva/node-openid-client/tree/main/docs#new-clientmetadata-jwks-options
50-
* env GRIST_OIDC_HTTP_TIMEOUT
51-
* The timeout in milliseconds for HTTP requests to the IdP. Defaults to 3500.
50+
* env GRIST_OIDC_SP_HTTP_TIMEOUT
51+
* The timeout in milliseconds for HTTP requests to the IdP. The default value is set to 3500 by the
52+
* openid-client library. See: https://github.com/panva/node-openid-client/blob/main/docs/README.md#customizing-http-requests
5253
*
5354
* This version of OIDCConfig has been tested with Keycloak OIDC IdP following the instructions
5455
* at:
@@ -139,10 +140,7 @@ export class OIDCConfig {
139140
censor: true,
140141
});
141142
const httpTimeout = section.flag('httpTimeout').readInt({
142-
envVar: 'GRIST_OIDC_HTTP_TIMEOUT',
143-
// Default value matching that of node-openid-client
144-
// See https://github.com/panva/node-openid-client/blob/main/docs/README.md#customizing-http-requests for more details.
145-
defaultValue: 3500,
143+
envVar: 'GRIST_OIDC_SP_HTTP_TIMEOUT',
146144
});
147145
this._namePropertyKey = section.flag('namePropertyKey').readString({
148146
envVar: 'GRIST_OIDC_SP_PROFILE_NAME_ATTR',
@@ -180,11 +178,11 @@ export class OIDCConfig {
180178
this._protectionManager = new ProtectionsManager(enabledProtections);
181179

182180
this._redirectUrl = new URL(CALLBACK_URL, spHost).href;
183-
await this._initClient({ issuerUrl, clientId, clientSecret, extraMetadata });
184-
185181
custom.setHttpOptionsDefaults({
186-
timeout: httpTimeout,
182+
...(httpTimeout !== undefined ? {timeout: httpTimeout} : {}),
187183
});
184+
await this._initClient({ issuerUrl, clientId, clientSecret, extraMetadata });
185+
188186
if (this._client.issuer.metadata.end_session_endpoint === undefined &&
189187
!this._endSessionEndpoint && !this._skipEndSessionEndpoint) {
190188
throw new Error('The Identity provider does not propose end_session_endpoint. ' +
@@ -302,6 +300,7 @@ export class OIDCConfig {
302300
protected async _initClient({ issuerUrl, clientId, clientSecret, extraMetadata }:
303301
{ issuerUrl: string, clientId: string, clientSecret: string, extraMetadata: Partial<ClientMetadata> }
304302
): Promise<void> {
303+
Issuer[custom.http_options] = () => ({});
305304
const issuer = await Issuer.discover(issuerUrl);
306305
this._client = new issuer.Client({
307306
client_id: clientId,

test/server/lib/OIDCConfig.ts

+50-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {Sessions} from "app/server/lib/Sessions";
55
import log from "app/server/lib/log";
66
import {assert} from "chai";
77
import Sinon from "sinon";
8-
import {Client, generators, errors as OIDCError} from "openid-client";
8+
import {Client, custom, generators, errors as OIDCError} from "openid-client";
99
import express from "express";
1010
import _ from "lodash";
1111
import {RequestWithLogin} from "app/server/lib/Authorizer";
@@ -192,6 +192,55 @@ describe('OIDCConfig', () => {
192192
});
193193
});
194194
});
195+
196+
describe('GRIST_OIDC_SP_HTTP_TIMEOUT', function () {
197+
[
198+
{
199+
itMsg: 'when omitted should not override openid-client default value',
200+
expectedUserDefinedHttpOptions: {}
201+
},
202+
{
203+
itMsg: 'should reject when the provided value is not a number',
204+
env: {
205+
GRIST_OIDC_SP_HTTP_TIMEOUT: '__NOT_A_NUMBER__',
206+
},
207+
expectedErrorMsg: /__NOT_A_NUMBER__ does not look like a number/,
208+
},
209+
{
210+
itMsg: 'should override openid-client timeout accordingly to the provided value',
211+
env: {
212+
GRIST_OIDC_SP_HTTP_TIMEOUT: '10000',
213+
},
214+
shouldSetTimeout: true,
215+
expectedUserDefinedHttpOptions: {
216+
timeout: 10000
217+
}
218+
},
219+
{
220+
itMsg: 'should allow disabling the timeout by having its value set to 0',
221+
env: {
222+
GRIST_OIDC_SP_HTTP_TIMEOUT: '0',
223+
},
224+
expectedUserDefinedHttpOptions: {
225+
timeout: 0
226+
}
227+
}
228+
].forEach(ctx => {
229+
it(ctx.itMsg, async () => {
230+
const setHttpOptionsDefaultsStub = sandbox.stub(custom, 'setHttpOptionsDefaults');
231+
setEnvVars();
232+
Object.assign(process.env, ctx.env);
233+
const promise = OIDCConfigStubbed.buildWithStub();
234+
if (ctx.expectedErrorMsg) {
235+
await assert.isRejected(promise, ctx.expectedErrorMsg);
236+
} else {
237+
await assert.isFulfilled(promise, 'initOIDC should have been fulfilled');
238+
assert.isTrue(setHttpOptionsDefaultsStub.calledOnce, 'Should have called custom.setHttpOptionsDefaults');
239+
assert.deepEqual(setHttpOptionsDefaultsStub.firstCall.args[0], ctx.expectedUserDefinedHttpOptions);
240+
}
241+
});
242+
});
243+
});
195244
});
196245

197246
describe('GRIST_OIDC_IDP_ENABLED_PROTECTIONS', () => {

0 commit comments

Comments
 (0)