Skip to content

Instantly share code, notes, and snippets.

@jd1378
Last active December 10, 2020 05:09
Show Gist options
  • Save jd1378/5125b51c14827acd3d4664f94fb9ac41 to your computer and use it in GitHub Desktop.
Save jd1378/5125b51c14827acd3d4664f94fb9ac41 to your computer and use it in GitHub Desktop.
rate limit hooks
const RateLimiterMongo = require('rate-limiter-flexible/lib/RateLimiterMongo');
const { rateLimit } = require('feathers-fletching');
const { iff, isProvider } = require('feathers-hooks-common');
const mongoose = require('mongoose');
const maxWrongAttemptsByIPperDay = 100;
const maxConsecutiveFailsByUsernameAndIP = 5;
const limiterSlowBruteByIP = new RateLimiterMongo({
storeClient: mongoose.connection,
points: maxWrongAttemptsByIPperDay,
duration: 60 * 60 * 24,
blockDuration: 60 * 60 * 24, // Block for 1 day, if 100 wrong attempts per day
});
const limiterConsecutiveFailsByUsernameAndIP = new RateLimiterMongo({
storeClient: mongoose.connection,
points: maxConsecutiveFailsByUsernameAndIP,
duration: 60 * 60 * 24 * 90, // Store number for 90 days since first fail
blockDuration: 60 * 60, // Block for 1 hour
});
const makeKeyIp = (ctx) => {
return ctx.params.ip;
};
const makeKeyUserIp = (ctx) => {
if (ctx.data) {
return (ctx.data.phoneNumber || '') + ctx.params.ip;
}
return ctx.params.ip;
};
const makePoints = (ctx) => {
if (ctx.params.user && ctx.method !== 'create') {
return 0;
}
return 1;
};
module.exports = {
before: {
all: [
iff(
isProvider('external'),
rateLimit(limiterSlowBruteByIP, { makeKey: makeKeyIp, makePoints }),
rateLimit(limiterConsecutiveFailsByUsernameAndIP, {
makeKey: makeKeyUserIp,
makePoints,
}),
),
],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: [],
},
after: {
create: [
iff(isProvider('external'), (ctx) => {
if (ctx.result.accessToken) {
limiterConsecutiveFailsByUsernameAndIP.delete(makeKeyUserIp(ctx));
}
}),
],
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment