mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 13:47:33 +01:00
Fix liveliness probes being rate limited (#15236)
* Do not rate limit any liveliness probes * update example config
This commit is contained in:
@@ -84,6 +84,7 @@
|
|||||||
"BLOCKED_IPS": "",
|
"BLOCKED_IPS": "",
|
||||||
"LOG_AMPLITUDE_EVENTS": "false",
|
"LOG_AMPLITUDE_EVENTS": "false",
|
||||||
"RATE_LIMITER_ENABLED": "false",
|
"RATE_LIMITER_ENABLED": "false",
|
||||||
|
"LIVELINESS_PROBE_KEY": "",
|
||||||
"REDIS_HOST": "aaabbbcccdddeeefff",
|
"REDIS_HOST": "aaabbbcccdddeeefff",
|
||||||
"REDIS_PORT": "1234",
|
"REDIS_PORT": "1234",
|
||||||
"REDIS_PASSWORD": "12345678",
|
"REDIS_PASSWORD": "12345678",
|
||||||
|
|||||||
@@ -87,6 +87,67 @@ describe('rateLimiter middleware', () => {
|
|||||||
expect(logger.error).to.have.been.calledWithMatch(Error, 'Rate Limiter Error');
|
expect(logger.error).to.have.been.calledWithMatch(Error, 'Rate Limiter Error');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not throw when LIVELINESS_PROBE_KEY is correct', async () => {
|
||||||
|
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||||
|
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('abc');
|
||||||
|
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||||
|
|
||||||
|
req.query.liveliness = 'abc';
|
||||||
|
await attachRateLimiter(req, res, next);
|
||||||
|
|
||||||
|
expect(next).to.have.been.calledOnce;
|
||||||
|
const calledWith = next.getCall(0).args;
|
||||||
|
expect(typeof calledWith[0] === 'undefined').to.equal(true);
|
||||||
|
expect(res.set).to.not.have.been.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('limits when LIVELINESS_PROBE_KEY is incorrect', async () => {
|
||||||
|
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||||
|
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('abc');
|
||||||
|
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||||
|
|
||||||
|
req.query.liveliness = 'das';
|
||||||
|
await attachRateLimiter(req, res, next);
|
||||||
|
|
||||||
|
expect(next).to.have.been.calledOnce;
|
||||||
|
expect(res.set).to.have.been.calledWithMatch({
|
||||||
|
'X-RateLimit-Limit': 30,
|
||||||
|
'X-RateLimit-Remaining': 29,
|
||||||
|
'X-RateLimit-Reset': sinon.match(Date),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('limits when LIVELINESS_PROBE_KEY is not set', async () => {
|
||||||
|
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||||
|
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns(undefined);
|
||||||
|
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||||
|
|
||||||
|
await attachRateLimiter(req, res, next);
|
||||||
|
|
||||||
|
expect(next).to.have.been.calledOnce;
|
||||||
|
expect(res.set).to.have.been.calledWithMatch({
|
||||||
|
'X-RateLimit-Limit': 30,
|
||||||
|
'X-RateLimit-Remaining': 29,
|
||||||
|
'X-RateLimit-Reset': sinon.match(Date),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when LIVELINESS_PROBE_KEY is blank', async () => {
|
||||||
|
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||||
|
nconfGetStub.withArgs('LIVELINESS_PROBE_KEY').returns('');
|
||||||
|
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||||
|
|
||||||
|
req.query.liveliness = '';
|
||||||
|
await attachRateLimiter(req, res, next);
|
||||||
|
|
||||||
|
expect(next).to.have.been.calledOnce;
|
||||||
|
expect(res.set).to.have.been.calledWithMatch({
|
||||||
|
'X-RateLimit-Limit': 30,
|
||||||
|
'X-RateLimit-Remaining': 29,
|
||||||
|
'X-RateLimit-Reset': sinon.match(Date),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('throws when there are no available points remaining', async () => {
|
it('throws when there are no available points remaining', async () => {
|
||||||
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
nconfGetStub.withArgs('RATE_LIMITER_ENABLED').returns('true');
|
||||||
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
const attachRateLimiter = requireAgain(pathToRateLimiter).default;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const RATE_LIMITER_ENABLED = nconf.get('RATE_LIMITER_ENABLED') === 'true';
|
|||||||
const REDIS_HOST = nconf.get('REDIS_HOST');
|
const REDIS_HOST = nconf.get('REDIS_HOST');
|
||||||
const REDIS_PASSWORD = nconf.get('REDIS_PASSWORD');
|
const REDIS_PASSWORD = nconf.get('REDIS_PASSWORD');
|
||||||
const REDIS_PORT = nconf.get('REDIS_PORT');
|
const REDIS_PORT = nconf.get('REDIS_PORT');
|
||||||
|
const LIVELINESS_PROBE_KEY = nconf.get('LIVELINESS_PROBE_KEY');
|
||||||
|
|
||||||
let redisClient;
|
let redisClient;
|
||||||
let rateLimiter;
|
let rateLimiter;
|
||||||
@@ -71,6 +72,7 @@ function setResponseHeaders (res, rateLimiterRes) {
|
|||||||
|
|
||||||
export default function rateLimiterMiddleware (req, res, next) {
|
export default function rateLimiterMiddleware (req, res, next) {
|
||||||
if (!RATE_LIMITER_ENABLED) return next();
|
if (!RATE_LIMITER_ENABLED) return next();
|
||||||
|
if (LIVELINESS_PROBE_KEY && req.query.liveliness === LIVELINESS_PROBE_KEY) return next();
|
||||||
|
|
||||||
const userId = req.header('x-api-user');
|
const userId = req.header('x-api-user');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user