chore: refactor rate limit

This commit is contained in:
AP 2019-12-10 20:16:46 +01:00
parent ae923e9fcc
commit 8441ff9795
24 changed files with 85 additions and 55 deletions

View file

@ -1,25 +1,22 @@
import { getGraphQLRateLimiter } from "graphql-rate-limit";
import { getGraphQLRateLimiter } from 'graphql-rate-limit';
import { RateConfig } from '../utils/rateLimitConfig';
const rateLimiter = getGraphQLRateLimiter({
identifyContext: (ctx: string) => ctx,
formatError: () => "rateLimitReached"
identifyContext: (ctx: string) => ctx,
formatError: () => 'Rate Limit Reached',
});
export const requestLimiter = async (
root: string,
params: any,
field: string,
max: number,
window: string
) => {
const errorMessage = await rateLimiter(
{
parent: root,
args: params,
context: root,
info: { fieldName: field } as any
},
{ max, window }
);
if (errorMessage) throw new Error(errorMessage);
export const requestLimiter = async (rate: string, field: string) => {
if (!RateConfig[field]) throw new Error('Invalid Rate Field');
const { max, window } = RateConfig[field];
const errorMessage = await rateLimiter(
{
parent: rate,
args: {},
context: rate,
info: { fieldName: field } as any,
},
{ max, window },
);
if (errorMessage) throw new Error(errorMessage);
};

View file

@ -25,7 +25,8 @@ export const closeChannel = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'closeChannel', 1, '1s');
await requestLimiter(context.ip, 'closeChannel')
const lnd = getAuthLnd(params.auth);
try {

View file

@ -24,7 +24,8 @@ export const openChannel = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'openChannel', 1, '1s');
await requestLimiter(context.ip, 'openChannel')
const lnd = getAuthLnd(params.auth);
try {

View file

@ -23,7 +23,8 @@ export const createInvoice = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'createInvoice', 1, '1s');
await requestLimiter(context.ip, 'createInvoice')
const lnd = getAuthLnd(params.auth);
try {

View file

@ -32,7 +32,8 @@ export const decodeRequest = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'decodeRequest', 1, '1s');
await requestLimiter(context.ip, 'decode')
const lnd = getAuthLnd(params.auth);
try {

View file

@ -36,7 +36,8 @@ export const parsePayment = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'parsePayment', 1, '1s');
await requestLimiter(context.ip, 'parsePayment');
const lnd = getAuthLnd(params.auth);
try {

View file

@ -33,7 +33,8 @@ export const pay = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'payRequest', 1, '1s');
await requestLimiter(context.ip, 'pay')
const lnd = getAuthLnd(params.auth);
try {

View file

@ -15,7 +15,8 @@ export const createAddress = {
nested: { type: GraphQLBoolean },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'createAddress', 1, '1s');
await requestLimiter(context.ip, 'getAddress')
const lnd = getAuthLnd(params.auth);
const format = params.nested ? 'np2wpkh' : 'p2wpkh';

View file

@ -29,7 +29,8 @@ export const sendToAddress = {
sendAll: { type: GraphQLBoolean },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'sendToAddress', 1, '1s');
await requestLimiter(context.ip, 'sendToAddress')
const lnd = getAuthLnd(params.auth);
const props = params.fee

View file

@ -14,7 +14,7 @@ export const getChannelBalance = {
type: ChannelBalanceType,
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'channelBalance', 1, '1s');
await requestLimiter(context.ip, 'channelBalance');
const lnd = getAuthLnd(params.auth);

View file

@ -39,7 +39,7 @@ export const getChannels = {
type: new GraphQLList(ChannelType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'channels', 1, '1s');
await requestLimiter(context.ip, 'channels');
const lnd = getAuthLnd(params.auth);

View file

@ -60,7 +60,8 @@ export const getClosedChannels = {
auth: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'closedChannels', 1, '1s');
await requestLimiter(context.ip, 'closedChannels')
const lnd = getAuthLnd(params.auth);
try {

View file

@ -33,7 +33,7 @@ export const getPendingChannels = {
type: new GraphQLList(PendingChannelType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'pendingChannels', 1, '1s');
await requestLimiter(context.ip, 'pendingChannels')
const lnd = getAuthLnd(params.auth);

View file

@ -14,7 +14,7 @@ export const getBitcoinFees = {
},
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'bitcoinFee', 1, '1s');
await requestLimiter(context.ip, 'bitcoinFee')
try {
const response = await fetch(url);

View file

@ -19,7 +19,7 @@ export const getInOut = {
time: { type: GraphQLString },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'getInvoices', 1, '1s');
await requestLimiter(context.ip, 'getInOut');
const lnd = getAuthLnd(params.auth);

View file

@ -19,7 +19,7 @@ export const getChainBalance = {
type: GraphQLInt,
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'chainBalance', 1, '1s');
await requestLimiter(context.ip, 'chainBalance');
const lnd = getAuthLnd(params.auth);
@ -39,13 +39,7 @@ export const getPendingChainBalance = {
type: GraphQLInt,
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(
context.ip,
params,
'pendingChainBalance',
1,
'1s',
);
await requestLimiter(context.ip, 'pendingChainBalance');
const lnd = getAuthLnd(params.auth);

View file

@ -20,7 +20,7 @@ export const getNetworkInfo = {
type: NetworkInfoType,
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'networkInfo', 1, '1s');
await requestLimiter(context.ip, 'networkInfo')
const lnd = getAuthLnd(params.auth);

View file

@ -26,7 +26,7 @@ export const getNodeInfo = {
type: NodeInfoType,
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'nodeInfo', 1, '1s');
await requestLimiter(context.ip, 'nodeInfo');
const lnd = getAuthLnd(params.auth);

View file

@ -24,7 +24,8 @@ export const getForwards = {
type: new GraphQLList(GetForwardType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'getForwards', 1, '1s');
await requestLimiter(context.ip, 'forwards');
const lnd = getAuthLnd(params.auth);
try {

View file

@ -48,7 +48,7 @@ export const getInvoices = {
type: new GraphQLList(GetInvoiceType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'getInvoices', 1, '1s');
await requestLimiter(context.ip, 'invoices');
const lnd = getAuthLnd(params.auth);

View file

@ -28,7 +28,7 @@ export const getPayments = {
type: new GraphQLList(GetPaymentType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'getPayments', 1, '1s');
await requestLimiter(context.ip, 'payments');
const lnd = getAuthLnd(params.auth);

View file

@ -17,13 +17,7 @@ export const getForwardChannelsReport = {
order: { type: GraphQLString },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(
context.ip,
params,
'getForwardChannelsReport',
1,
'1s',
);
await requestLimiter(context.ip, 'forwardChannels')
const lnd = getAuthLnd(params.auth);

View file

@ -20,7 +20,7 @@ export const getForwardReport = {
time: { type: GraphQLString },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, params, 'getForwardReport', 1, '1s');
await requestLimiter(context.ip, 'forwardReport');
const lnd = getAuthLnd(params.auth);

View file

@ -0,0 +1,35 @@
interface RateConfigProps {
[key: string]: {
max: number;
window: string;
};
}
export const RateConfig: RateConfigProps = {
channelBalance: { max: 3, window: '1s' },
channelFees: { max: 3, window: '1s' },
channels: { max: 3, window: '1s' },
closedChannels: { max: 3, window: '1s' },
pendingChannels: { max: 3, window: '1s' },
bitcoinFee: { max: 3, window: '1s' },
bitcoinPrice: { max: 3, window: '1s' },
getInOut: { max: 3, window: '1s' },
chainBalance: { max: 3, window: '1s' },
pendingChainBalance: { max: 3, window: '1s' },
networkInfo: { max: 3, window: '1s' },
nodeInfo: { max: 3, window: '1s' },
forwards: { max: 3, window: '1s' },
invoices: { max: 3, window: '1s' },
payments: { max: 3, window: '1s' },
forwardChannels: { max: 3, window: '1s' },
forwardReport: { max: 3, window: '1s' },
getRoute: { max: 3, window: '1s' },
closeChannel: { max: 3, window: '1s' },
openChannel: { max: 3, window: '1s' },
createInvoice: { max: 3, window: '1s' },
decode: { max: 3, window: '1s' },
parsePayment: { max: 3, window: '1s' },
pay: { max: 3, window: '1s' },
getAddress: { max: 3, window: '1s' },
sendToAddress: { max: 3, window: '1s' },
};