diff --git a/README.md b/README.md
index 3cf71c7c..78ed84de 100644
--- a/README.md
+++ b/README.md
@@ -277,10 +277,6 @@ See [Client Authentication Methods (docs)][documentation-methods].
See [Customizing (docs)](https://github.com/panva/node-openid-client/blob/master/docs/README.md#customizing).
-#### How can I debug the requests and responses?
-
-See [Customizing (docs)](https://github.com/panva/node-openid-client/blob/master/docs/README.md#customizing).
-
[openid-connect]: https://openid.net/connect/
[feature-core]: https://openid.net/specs/openid-connect-core-1_0.html
diff --git a/docs/README.md b/docs/README.md
index 86571895..15279a5a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -659,65 +659,41 @@ This function will then be called before executing each and every request on the
const { custom } = require('openid-client');
// you can also set this on Issuer constructor, Issuer instance, or Client constructor
-client[custom.http_options] = function (options) {
+client[custom.http_options] = function (url, options) {
+ // console.log(url);
// console.log(options);
- options.timeout = 5000;
- return options;
+ return { timeout: 5000 };
}
```
-This is meant to change request options on per-request basis should there be a specific IdP quirk
-you need to work around, e.g. adding custom headers or body payload parameters.
+The following options can be provided `agent`, `ca`, `cert`, `crl`, `headers`, `key`, `lookup`, `passphrase`,
+`pfx`, `timeout`. These are all relayed to https://nodejs.org/api/https.html#httpsrequesturl-options-callback
Example (Click to expand) providing mutual-TLS client certificate and key
```js
const { custom } = require('openid-client');
-client[custom.http_options] = function (options) {
- // see https://github.com/sindresorhus/got/tree/v11.8.0#advanced-https-api
- options.https = options.https || {};
- options.https.certificate = certificate; // | | |
- options.https.key = key; // | | | |
-
-
- Example (Click to expand) Other options
-
-```js
-const { custom } = require('openid-client');
-client[custom.http_options] = function (options) {
- // https://github.com/sindresorhus/got/tree/v11.8.0#headers
- // options.headers = Object.assign(options.headers, { 'custom': 'foo' });
+client[custom.http_options] = function (url, options) {
+ // https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions
+ const result = {};
- // https://github.com/sindresorhus/got/tree/v11.8.0#timeout
- // options.timeout = timeout;
+ result.cert = cert; // | | |
+ result.key = key; // | | | |
- // https://github.com/sindresorhus/got/tree/v11.8.0#retry
- // options.retry = retry;
+ // custom CA
+ // result.ca = ca; // | | |
- // https://github.com/sindresorhus/got/tree/v11.8.0#followredirect
- // options.followRedirect = false;
+ // use with .p12/.pfx files
+ // result.pfx = pfx; // | | | |
+ // result.passphrase = passphrase; //
// use HTTP(S)_PROXY
- // https://github.com/sindresorhus/got/tree/v11.8.0#agent
- // options.agent = agent;
+ // https://nodejs.org/api/http.html#httprequesturl-options-callback
+ // e.g. using https://www.npmjs.com/package/proxy-agent
+ // result.agent = agent;
- return options;
+ return result;
}
```
diff --git a/lib/client.js b/lib/client.js
index 69ca0f6f..5a5a7333 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -7,7 +7,6 @@ const { strict: assert } = require('assert');
const querystring = require('querystring');
const url = require('url');
-const { ParseError } = require('got');
const jose = require('jose');
const tokenHash = require('oidc-token-hash');
@@ -95,6 +94,10 @@ function authorizationParams(params) {
async function claimJWT(label, jwt) {
try {
+ if (Buffer.isBuffer(jwt)) {
+ // eslint-disable-next-line no-param-reassign
+ jwt = jwt.toString('ascii');
+ }
const { header, payload } = jose.JWT.decode(jwt, { complete: true });
const { iss } = payload;
@@ -1160,8 +1163,9 @@ module.exports = (issuer, aadIssValidation = false) => class Client extends Base
} else {
try {
parsed = JSON.parse(response.body);
- } catch (error) {
- throw new ParseError(error, response);
+ } catch (err) {
+ Object.defineProperty(err, 'response', response);
+ throw err;
}
}
diff --git a/lib/helpers/is_absolute_url.js b/lib/helpers/is_absolute_url.js
deleted file mode 100644
index 4bfbe440..00000000
--- a/lib/helpers/is_absolute_url.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const url = require('url');
-const { strict: assert } = require('assert');
-
-module.exports = (target) => {
- try {
- const { protocol } = new url.URL(target);
- assert(protocol.match(/^(https?:)$/));
- return true;
- } catch (err) {
- throw new TypeError('only valid absolute URLs can be requested');
- }
-};
diff --git a/lib/helpers/process_response.js b/lib/helpers/process_response.js
index 989f82ad..923aeb81 100644
--- a/lib/helpers/process_response.js
+++ b/lib/helpers/process_response.js
@@ -29,7 +29,7 @@ const isStandardBodyError = (response) => {
jsonbody = response.body;
}
result = typeof jsonbody.error === 'string' && jsonbody.error.length;
- if (result) response.body = jsonbody;
+ if (result) Object.defineProperty(response, 'body', { value: jsonbody, configurable: true });
} catch (err) {}
return result;
diff --git a/lib/helpers/request.js b/lib/helpers/request.js
index 44b876d5..48e0f9af 100644
--- a/lib/helpers/request.js
+++ b/lib/helpers/request.js
@@ -1,30 +1,57 @@
-const Got = require('got');
+const assert = require('assert');
+const querystring = require('querystring');
+const http = require('http');
+const https = require('https');
+const { once } = require('events');
+
+const CacheableLookup = require('cacheable-lookup');
+const QuickLRU = require('quick-lru');
const pkg = require('../../package.json');
+const { RPError } = require('../errors');
+const pick = require('./pick');
const { deep: defaultsDeep } = require('./defaults');
-const isAbsoluteUrl = require('./is_absolute_url');
const { HTTP_OPTIONS } = require('./consts');
let DEFAULT_HTTP_OPTIONS;
-let got;
-const setDefaults = (options) => {
- DEFAULT_HTTP_OPTIONS = defaultsDeep({}, options, DEFAULT_HTTP_OPTIONS);
- got = Got.extend(DEFAULT_HTTP_OPTIONS);
+const cacheable = new CacheableLookup({
+ cache: new QuickLRU({ maxSize: 1000 }),
+});
+const allowed = [
+ 'agent',
+ 'ca',
+ 'cert',
+ 'crl',
+ 'headers',
+ 'key',
+ 'lookup',
+ 'passphrase',
+ 'pfx',
+ 'timeout',
+];
+
+const setDefaults = (props, options) => {
+ // eslint-disable-next-line max-len
+ DEFAULT_HTTP_OPTIONS = defaultsDeep({}, props.length ? pick(options, ...props) : options, DEFAULT_HTTP_OPTIONS);
};
-setDefaults({
- followRedirect: false,
+setDefaults([], {
headers: { 'User-Agent': `${pkg.name}/${pkg.version} (${pkg.homepage})` },
- retry: 0,
timeout: 3500,
- throwHttpErrors: false,
+ lookup: cacheable.lookup,
});
module.exports = async function request(options, { accessToken, mTLS = false, DPoP } = {}) {
- const { url } = options;
- isAbsoluteUrl(url);
+ let url;
+ try {
+ url = new URL(options.url);
+ delete options.url;
+ assert(/^(https?:)$/.test(url.protocol));
+ } catch (err) {
+ throw new TypeError('only valid absolute URLs can be requested');
+ }
const optsFn = this[HTTP_OPTIONS];
let opts = options;
@@ -36,21 +63,117 @@ module.exports = async function request(options, { accessToken, mTLS = false, DP
}, DPoP, accessToken);
}
+ let userOptions;
if (optsFn) {
- opts = optsFn.call(this, defaultsDeep({}, opts, DEFAULT_HTTP_OPTIONS));
+ userOptions = pick(
+ optsFn.call(this, url, defaultsDeep({}, opts, DEFAULT_HTTP_OPTIONS)),
+ ...allowed,
+ );
}
+ opts = defaultsDeep({}, userOptions, opts, DEFAULT_HTTP_OPTIONS);
- if (
- mTLS
- && (
- (!opts.key || !opts.cert)
- && (!opts.https || !((opts.https.key && opts.https.certificate) || opts.https.pfx))
- )
- ) {
+ if (mTLS && (!opts.pfx && !(opts.key && opts.cert))) {
throw new TypeError('mutual-TLS certificate and key not set');
}
- return got(opts);
+ if (opts.searchParams) {
+ // eslint-disable-next-line no-restricted-syntax
+ for (const [key, value] of Object.entries(opts.searchParams)) {
+ url.searchParams.delete(key);
+ url.searchParams.set(key, value);
+ }
+ }
+
+ let responseType;
+ let form;
+ let json;
+ let body;
+ ({
+ // eslint-disable-next-line prefer-const
+ form, responseType, json, body, ...opts
+ } = opts);
+
+ // eslint-disable-next-line no-restricted-syntax
+ for (const [key, value] of Object.entries(opts.headers || {})) {
+ if (value === undefined) {
+ delete opts.headers[key];
+ }
+ }
+
+ let response;
+ const req = (url.protocol === 'https:' ? https.request : http.request)(url, opts);
+ return (async () => {
+ // if (GET (and other && form, json, body)) throw;
+ if (json) {
+ req.removeHeader('content-type');
+ req.setHeader('content-type', 'application/json');
+ req.write(JSON.stringify(json));
+ } else if (form) {
+ req.removeHeader('content-type');
+ req.setHeader('content-type', 'application/x-www-form-urlencoded');
+ req.write(querystring.stringify(form));
+ } else if (body) {
+ req.write(body);
+ }
+
+ req.end();
+
+ [response] = await Promise.race([once(req, 'response'), once(req, 'timeout')]);
+
+ // timeout reached
+ if (!response) {
+ req.destroy();
+ throw new RPError(`outgoing request timed out after ${opts.timeout}ms`);
+ }
+
+ const parts = [];
+ // eslint-disable-next-line no-restricted-syntax
+ for await (const part of response) {
+ parts.push(part);
+ }
+
+ if (parts.length) {
+ switch (responseType) {
+ case 'json': {
+ Object.defineProperty(response, 'body', {
+ get() {
+ let value = Buffer.concat(parts);
+ try {
+ value = JSON.parse(value);
+ } catch (err) {
+ Object.defineProperty(err, 'response', response);
+ throw err;
+ } finally {
+ Object.defineProperty(response, 'body', { value, configurable: true });
+ }
+ return value;
+ },
+ configurable: true,
+ });
+ break;
+ }
+ case undefined:
+ case 'buffer': {
+ Object.defineProperty(response, 'body', {
+ get() {
+ const value = Buffer.concat(parts);
+ Object.defineProperty(response, 'body', { value, configurable: true });
+ return value;
+ },
+ configurable: true,
+ });
+ break;
+ }
+ default:
+ throw new TypeError('unsupported responseType request option');
+ }
+ }
+
+ return response;
+ })().catch((err) => {
+ Object.defineProperty(err, 'response', response);
+ throw err;
+ });
};
-module.exports.setDefaults = setDefaults;
+module.exports.setDefaults = setDefaults.bind(undefined, allowed);
diff --git a/lib/issuer.js b/lib/issuer.js
index 1b6170ca..9885b160 100644
--- a/lib/issuer.js
+++ b/lib/issuer.js
@@ -4,7 +4,7 @@ const { inspect } = require('util');
const url = require('url');
const jose = require('jose');
-const LRU = require('lru-cache');
+const QuickLRU = require('quick-lru');
const objectHash = require('object-hash');
const { RPError } = require('./errors');
@@ -57,7 +57,7 @@ class Issuer {
}
});
- instance(this).set('cache', new LRU({ max: 100 }));
+ instance(this).set('cache', new QuickLRU({ maxSize: 100 }));
registry.set(this.issuer, this);
@@ -80,7 +80,7 @@ class Issuer {
const cache = instance(this).get('cache');
if (reload || !keystore) {
- cache.reset();
+ cache.clear();
const response = await request.call(this, {
method: 'GET',
responseType: 'json',
@@ -168,7 +168,6 @@ class Issuer {
url: webfingerUrl,
responseType: 'json',
searchParams: { resource, rel: REL },
- followRedirect: true,
});
const body = processResponse(response);
diff --git a/package.json b/package.json
index d09ccec4..b16c2ab7 100644
--- a/package.json
+++ b/package.json
@@ -52,14 +52,15 @@
]
},
"dependencies": {
- "got": "^11.8.0",
+ "cacheable-lookup": "^6.0.4",
"jose": "^2.0.5",
- "lru-cache": "^6.0.0",
"make-error": "^1.3.6",
"object-hash": "^2.0.1",
- "oidc-token-hash": "^5.0.1"
+ "oidc-token-hash": "^5.0.1",
+ "quick-lru": "^5.1.1"
},
"devDependencies": {
+ "@types/node": "^16.11.1",
"@types/passport": "^1.0.4",
"base64url": "^3.0.1",
"chai": "^4.2.0",
diff --git a/test/client/client_instance.test.js b/test/client/client_instance.test.js
index d4b30600..d887f6f6 100644
--- a/test/client/client_instance.test.js
+++ b/test/client/client_instance.test.js
@@ -1352,8 +1352,7 @@ describe('Client', () => {
return client.userinfo()
.then(fail, function (error) {
- expect(error.name).to.eql('ParseError');
- expect(error.message).to.eql('Unexpected token } in JSON at position 12 in "https://op.example.com/me"');
+ expect(error.message).to.eql('Unexpected token } in JSON at position 12');
expect(error).to.have.property('response');
});
});
@@ -1542,8 +1541,7 @@ describe('Client', () => {
return client.introspect('tokenValue')
.then(fail, function (error) {
- expect(error.name).to.eql('ParseError');
- expect(error.message).to.eql('Unexpected token } in JSON at position 12 in "https://op.example.com/token/introspect"');
+ expect(error.message).to.eql('Unexpected token } in JSON at position 12');
expect(error).to.have.property('response');
});
});
diff --git a/test/client/discover_client.test.js b/test/client/discover_client.test.js
index d63fa259..b4fd4f9d 100644
--- a/test/client/discover_client.test.js
+++ b/test/client/discover_client.test.js
@@ -73,8 +73,7 @@ describe('Client#fromUri()', () => {
return issuer.Client.fromUri('https://op.example.com/client/identifier')
.then(fail, function (error) {
- expect(error.name).to.eql('ParseError');
- expect(error.message).to.eql('Unexpected token } in JSON at position 12 in "https://op.example.com/client/identifier"');
+ expect(error.message).to.eql('Unexpected token } in JSON at position 12');
expect(error).to.have.property('response');
});
});
@@ -85,10 +84,7 @@ describe('Client#fromUri()', () => {
});
it('allows for http options to be defined for issuer.Client.fromUri calls', async () => {
- const httpOptions = sinon.stub().callsFake((opts) => {
- opts.headers.custom = 'foo';
- return opts;
- });
+ const httpOptions = sinon.stub().callsFake(() => ({ headers: { custom: 'foo' } }));
issuer.Client[custom.http_options] = httpOptions;
nock('https://op.example.com')
diff --git a/test/client/dpop.test.js b/test/client/dpop.test.js
index e89507b0..6d561ff6 100644
--- a/test/client/dpop.test.js
+++ b/test/client/dpop.test.js
@@ -24,7 +24,7 @@ describe('DPoP', () => {
client_id: 'client',
token_endpoint_auth_method: 'none',
});
- this.client[custom.http_options] = (opts) => {
+ this.client[custom.http_options] = (url, opts) => {
this.httpOpts = opts;
return opts;
};
diff --git a/test/client/mtls.test.js b/test/client/mtls.test.js
index ec26b077..fb5691f8 100644
--- a/test/client/mtls.test.js
+++ b/test/client/mtls.test.js
@@ -92,7 +92,7 @@ describe('mutual-TLS', () => {
token_endpoint_auth_method: 'self_signed_tls_client_auth',
tls_client_certificate_bound_access_tokens: true,
});
- this.client[custom.http_options] = (opts) => ({ ...opts, https: { key, certificate: cert } });
+ this.client[custom.http_options] = () => ({ key, cert });
this.jwtAuthClient = new issuer.Client({
client_id: 'client',
client_secret: 'secret',
@@ -100,7 +100,7 @@ describe('mutual-TLS', () => {
token_endpoint_auth_signing_alg: 'HS256',
tls_client_certificate_bound_access_tokens: true,
});
- this.client[custom.http_options] = (opts) => ({ ...opts, https: { key, certificate: cert } });
+ this.client[custom.http_options] = () => ({ key, cert });
});
it('uses the mtls endpoint alias for token endpoint when using jwt auth and tls certs', async function () {
@@ -174,7 +174,7 @@ describe('mutual-TLS', () => {
});
it('works with a PKCS#12 file and a passphrase', async function () {
- this.client[custom.http_options] = (opts) => ({ ...opts, https: { pfx } });
+ this.client[custom.http_options] = () => ({ pfx });
nock('https://mtls.op.example.com')
.get('/me').reply(200, { sub: 'foo' });
diff --git a/test/client/register_client.test.js b/test/client/register_client.test.js
index cbeed298..c27acfda 100644
--- a/test/client/register_client.test.js
+++ b/test/client/register_client.test.js
@@ -86,8 +86,7 @@ describe('Client#register', () => {
return issuer.Client.register({})
.then(fail, function (error) {
- expect(error.name).to.eql('ParseError');
- expect(error.message).to.eql('Unexpected token } in JSON at position 12 in "https://op.example.com/client/registration"');
+ expect(error.message).to.eql('Unexpected token } in JSON at position 12');
expect(error).to.have.property('response');
});
});
@@ -207,10 +206,7 @@ describe('Client#register', () => {
});
it('allows for http options to be defined for issuer.Client.register calls', async () => {
- const httpOptions = sinon.stub().callsFake((opts) => {
- opts.headers.custom = 'foo';
- return opts;
- });
+ const httpOptions = sinon.stub().callsFake(() => ({ headers: { custom: 'foo' } }));
issuer.Client[custom.http_options] = httpOptions;
nock('https://op.example.com')
diff --git a/test/issuer/discover_issuer.test.js b/test/issuer/discover_issuer.test.js
index cfbf57af..5589b575 100644
--- a/test/issuer/discover_issuer.test.js
+++ b/test/issuer/discover_issuer.test.js
@@ -235,8 +235,7 @@ describe('Issuer#discover()', () => {
return Issuer.discover('https://op.example.com')
.then(fail, function (error) {
- expect(error.name).to.eql('ParseError');
- expect(error.message).to.eql('Unexpected token } in JSON at position 12 in "https://op.example.com/.well-known/openid-configuration"');
+ expect(error.message).to.eql('Unexpected token } in JSON at position 12');
expect(error).to.have.property('response');
});
});
@@ -276,10 +275,7 @@ describe('Issuer#discover()', () => {
.get('/.well-known/openid-configuration')
.reply(200, success);
- const httpOptions = sinon.stub().callsFake((opts) => {
- opts.headers.custom = 'foo';
- return opts;
- });
+ const httpOptions = sinon.stub().callsFake(() => ({ headers: { custom: 'foo' } }));
Issuer[custom.http_options] = httpOptions;
await Issuer.discover('https://op.example.com/.well-known/openid-configuration');
diff --git a/test/issuer/discover_webfinger.test.js b/test/issuer/discover_webfinger.test.js
index fdf73015..67656788 100644
--- a/test/issuer/discover_webfinger.test.js
+++ b/test/issuer/discover_webfinger.test.js
@@ -255,10 +255,7 @@ describe('Issuer#webfinger()', () => {
});
it('allows for http options to be defined for Issuer.webfinger calls', async () => {
- const httpOptions = sinon.stub().callsFake((opts) => {
- opts.headers.custom = 'foo';
- return opts;
- });
+ const httpOptions = sinon.stub().callsFake(() => ({ headers: { custom: 'foo' } }));
Issuer[custom.http_options] = httpOptions;
nock('https://opemail.example.com')
diff --git a/test/issuer/issuer_instance.test.js b/test/issuer/issuer_instance.test.js
index ba6bc4a4..0054e856 100644
--- a/test/issuer/issuer_instance.test.js
+++ b/test/issuer/issuer_instance.test.js
@@ -1,5 +1,5 @@
const { expect } = require('chai');
-const LRU = require('lru-cache');
+const QuickLRU = require('quick-lru');
const nock = require('nock');
const sinon = require('sinon');
const jose = require('jose');
@@ -40,7 +40,7 @@ describe('Issuer', () => {
after(nock.cleanAll);
afterEach(function () {
- if (LRU.prototype.get.restore) LRU.prototype.get.restore();
+ if (QuickLRU.prototype.get.restore) QuickLRU.prototype.get.restore();
});
it('does not refetch immidiately', function () {
@@ -64,7 +64,7 @@ describe('Issuer', () => {
});
it('asks to fetch if the keystore is stale and new key definition is requested', function () {
- sinon.stub(LRU.prototype, 'get').returns(undefined);
+ sinon.stub(QuickLRU.prototype, 'get').returns(undefined);
return this.issuer.queryKeyStore({ kid: 'yeah' }).then(fail, () => {
nock('https://op.example.com')
.get('/certs')
@@ -83,7 +83,7 @@ describe('Issuer', () => {
});
it('requires a kid is provided in definition if more keys are in the storage', function () {
- sinon.stub(LRU.prototype, 'get').returns(undefined);
+ sinon.stub(QuickLRU.prototype, 'get').returns(undefined);
return this.keystore.generate('RSA').then(() => {
nock('https://op.example.com')
.get('/certs')
@@ -97,7 +97,7 @@ describe('Issuer', () => {
});
it('multiple keys can match the JWT header', function () {
- sinon.stub(LRU.prototype, 'get').returns(undefined);
+ sinon.stub(QuickLRU.prototype, 'get').returns(undefined);
const { kid } = this.keystore.get({ kty: 'RSA' });
return this.keystore.generate('RSA', undefined, { kid }).then(() => {
nock('https://op.example.com')
@@ -121,10 +121,7 @@ describe('Issuer', () => {
.get('/certs')
.reply(200, this.keystore.toJWKS());
- const httpOptions = sinon.stub().callsFake((opts) => {
- opts.headers.custom = 'foo';
- return opts;
- });
+ const httpOptions = sinon.stub().callsFake(() => ({ headers: { custom: 'foo' } }));
this.issuer[custom.http_options] = httpOptions;
await this.issuer.keystore(true);
diff --git a/types/index.d.ts b/types/index.d.ts
index d5b9e3a1..b4568f38 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -6,16 +6,16 @@
* @see https://github.com/panva/node-openid-client/blob/master/docs/README.md
*/
import * as http from "http";
+import * as https from "https";
import * as http2 from "http2";
-import { Options as GotOptions, CancelableRequest, Response } from "got";
import { URL } from "url";
import * as jose from "jose";
import * as crypto from "crypto";
-export type HttpOptions = GotOptions;
+export type HttpOptions = Pick
export type RetryFunction = (retry: number, error: Error) => number;
-export type CustomHttpOptionsProvider = (options: HttpOptions) => HttpOptions;
+export type CustomHttpOptionsProvider = (options: HttpOptions & { url: URL } & UnknownObject) => HttpOptions;
export type TokenTypeHint = "access_token" | "refresh_token" | string;
export type DPoPInput =
| crypto.KeyObject
diff --git a/types/openid-client-tests.ts b/types/openid-client-tests.ts
index 27b8babc..941219c7 100644
--- a/types/openid-client-tests.ts
+++ b/types/openid-client-tests.ts
@@ -8,15 +8,7 @@ import passport from 'passport';
async (req: IncomingMessage) => {
// Custom HTTP options on the `Issuer` _c'tor_ (e.g. used for `Issuer.discover()`):
- Issuer[custom.http_options] = options => {
- console.log(options.followRedirect, options.timeout, options.retry);
- return {
- ...options,
- followRedirect: true,
- timeout: 10_000,
- retry: 3,
- };
- };
+ Issuer[custom.http_options] = () => ({ timeout: 10000 });
let issuer = await Issuer.discover('https://accounts.google.com');
console.log('Discovered issuer %O', issuer.metadata.issuer);
@@ -35,11 +27,11 @@ async (req: IncomingMessage) => {
token_endpoint_auth_methods_supported: ['client_secret_post', 'client_secret_basic'],
});
- issuer[custom.http_options] = options => ({ ...options, retry: 3 });
+ issuer[custom.http_options] = () => ({ timeout: 10000 });
//
- issuer.Client[custom.http_options] = options => ({ ...options, retry: 3 });
+ issuer.Client[custom.http_options] = () => ({ timeout: 10000 });
const client = new issuer.Client({
client_id: 'c',
@@ -50,7 +42,7 @@ async (req: IncomingMessage) => {
console.log(client.metadata.client_id);
// Custom HTTP options on the `Client` _instance_
- client[custom.http_options] = options => ({ ...options, retry: 3 });
+ client[custom.http_options] = () => ({ timeout: 10000 });
client[custom.clock_tolerance] = 5;
//