fix #415: move throttle to env vars and test
This commit is contained in:
Родитель
8ffc9cc783
Коммит
e3e1b95b7e
|
@ -44,3 +44,7 @@ HIBP_RELOAD_BREACHES_TIMER=600
|
|||
# HIBP API for range search and subscription
|
||||
HIBP_KANON_API_ROOT="https://api.haveibeenpwned.com"
|
||||
HIBP_KANON_API_TOKEN=""
|
||||
# How many seconds to wait before retrying an HIBP request
|
||||
HIBP_THROTTLE_DELAY=2000
|
||||
# Max number of times to try an HIBP request before throwing error
|
||||
HIBP_THROTTLE_MAX_TRIES=5
|
||||
|
|
|
@ -29,6 +29,8 @@ const kEnvironmentVariables = [
|
|||
"HIBP_API_ROOT",
|
||||
"HIBP_API_TOKEN",
|
||||
"HIBP_RELOAD_BREACHES_TIMER",
|
||||
"HIBP_THROTTLE_DELAY",
|
||||
"HIBP_THROTTLE_MAX_TRIES",
|
||||
"DATABASE_URL",
|
||||
"SERVER_URL",
|
||||
"DELETE_UNVERIFIED_SUBSCRIBERS_TIMER",
|
||||
|
|
13
hibp.js
13
hibp.js
|
@ -10,8 +10,6 @@ const pkg = require("./package.json");
|
|||
|
||||
const DOMPurify = createDOMPurify((new JSDOM("")).window);
|
||||
const HIBP_USER_AGENT = `${pkg.name}/${pkg.version}`;
|
||||
const HIBP_THROTTLE_DELAY = 2000;
|
||||
const HIBP_THROTTLE_MAX_RETRIES = 5;
|
||||
|
||||
|
||||
const HIBP = {
|
||||
|
@ -25,18 +23,19 @@ const HIBP = {
|
|||
return Object.assign(options, hibpOptions);
|
||||
},
|
||||
|
||||
async _throttledGot (url, reqOptions, retryCount = 0) {
|
||||
async _throttledGot (url, reqOptions, tryCount = 1) {
|
||||
try {
|
||||
return await got(url, reqOptions);
|
||||
} catch (err) {
|
||||
console.error("got an error: " + err);
|
||||
if (err.statusCode === 429) {
|
||||
console.log("got a 429, retryCount: ", retryCount);
|
||||
if (retryCount >= HIBP_THROTTLE_MAX_RETRIES) {
|
||||
console.log("got a 429, tryCount: ", tryCount);
|
||||
if (tryCount >= AppConstants.HIBP_THROTTLE_MAX_TRIES) {
|
||||
throw new Error(err.message);
|
||||
} else {
|
||||
await new Promise(resolve => setTimeout(resolve, HIBP_THROTTLE_DELAY * retryCount));
|
||||
return await this._throttledGot(url, reqOptions, retryCount)
|
||||
tryCount++;
|
||||
await new Promise(resolve => setTimeout(resolve, AppConstants.HIBP_THROTTLE_DELAY * tryCount));
|
||||
return await this._throttledGot(url, reqOptions, tryCount);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Error connecting to HIBP.");
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
const got = require("got");
|
||||
|
||||
const AppConstants = require("../app-constants");
|
||||
const getSha1 = require("../sha1-utils");
|
||||
const hibp = require("../hibp");
|
||||
|
||||
const { testBreaches } = require("./test-breaches");
|
||||
|
@ -59,3 +60,18 @@ test("filterOutUnsafeBreaches removes sensitive breaches", async() => {
|
|||
expect(breach.IsVerified).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test("getBreachesForEmail HIBP responses with status of 429 cause throttled retries up to HIBP_THROTTLE_MAX_TRIES", async() => {
|
||||
// Assumes running with max tries of 3 and delay of 1000
|
||||
jest.setTimeout(20000);
|
||||
got.mockClear();
|
||||
got.mockRejectedValue( { statusCode: 429 });
|
||||
|
||||
await expect(hibp.getBreachesForEmail(getSha1("unverifiedemail@test.com"), testBreaches)).rejects.toThrow();
|
||||
|
||||
const gotCalls = got.mock.calls;
|
||||
expect(gotCalls.length).toEqual(Number(AppConstants.HIBP_THROTTLE_MAX_TRIES));
|
||||
|
||||
jest.setTimeout(5000);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче