From c1bd8fbe37e9daca101678e925d47098dd8b612f Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Tue, 10 Dec 2019 12:56:49 -0800 Subject: [PATCH 1/2] fix(rate limits): Fixed corner case with JWT token handling --- src/middleware/route-ratelimit.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/middleware/route-ratelimit.js b/src/middleware/route-ratelimit.js index 172d0d1..7c75acf 100644 --- a/src/middleware/route-ratelimit.js +++ b/src/middleware/route-ratelimit.js @@ -93,12 +93,15 @@ const routeRateLimit = async function(req, res, next) { const route = rateLimitTier + req.method + + req.locals.apiLevel + // Generates new rate limit when user upgrades JWT token. path .split("/") .slice(0, 4) .join("/") //console.log(`route identifier: ${JSON.stringify(route, null, 2)}`) + console.log(`req.locals: ${JSON.stringify(req.locals, null, 2)}`) + // This boolean value is passed from the auth.js middleware. const proRateLimits = req.locals.proLimit @@ -112,6 +115,8 @@ const routeRateLimit = async function(req, res, next) { let PRO_RPM = 10 // Default value for free tier if (req.locals.apiLevel > 0) PRO_RPM = 100 // RPM for paid tiers. + // console.log(`PRO_RPM: ${PRO_RPM}, apiLevel: ${req.locals.apiLevel}`) + // Create new RateLimit if none exists for this route if (!uniqueRateLimits[route]) { uniqueRateLimits[route] = new RateLimit({ @@ -123,7 +128,7 @@ const routeRateLimit = async function(req, res, next) { res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330 return res.json({ - error: `Too many requests. Limits are ${PRO_RPM} requests per minute.` + error: `Too many requests. Limits are ${PRO_RPM} requests per minute. Increase rate limits at https://account.bchjs.cash` }) } }) @@ -145,7 +150,7 @@ const routeRateLimit = async function(req, res, next) { res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330 return res.json({ - error: `Too many requests. Your limits are currently ${maxRequests} requests per minute.` + error: `Too many requests. Your limits are currently ${maxRequests} requests per minute. Increase rate limits at https://account.bchjs.cash` }) } }) From c982c247f71171edd30f335d05362077fc7188c7 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Tue, 10 Dec 2019 13:10:37 -0800 Subject: [PATCH 2/2] Cleaning up code comments --- src/middleware/route-ratelimit.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/middleware/route-ratelimit.js b/src/middleware/route-ratelimit.js index 7c75acf..cdad7a6 100644 --- a/src/middleware/route-ratelimit.js +++ b/src/middleware/route-ratelimit.js @@ -8,6 +8,11 @@ - anonymous access: 3 - free access: 10, apiLevel = 0 - any paid tier: 100, apiLevel > 0 + + If a person signs up for full node access but not indexer access, then the + apiLevel will be 10. If they call an endpoint that uses an indexer, the apiLevel + will be downgraded to 0 on-the-fly. Indexer endpoints will effectively be + downgraded to the anonymous access tier. */ "use strict" @@ -72,15 +77,6 @@ const routeRateLimit = async function(req, res, next) { req.locals.proLimit = userPermissions.proLimit req.locals.apiLevel = userPermissions.apiLevel - - // const locals = req.locals - // console.log(`locals: ${JSON.stringify(locals, null, 2)}`) - // const url = req.url - // console.log(`url: ${JSON.stringify(url, null, 2)}`) - // - // // console.log(`JWT is valid. Enabling pro-tier rate limits.`) - // req.locals.proLimit = true - // req.locals.apiLevel = jwtInfo.apiLevel } } } @@ -100,7 +96,7 @@ const routeRateLimit = async function(req, res, next) { .join("/") //console.log(`route identifier: ${JSON.stringify(route, null, 2)}`) - console.log(`req.locals: ${JSON.stringify(req.locals, null, 2)}`) + // console.log(`req.locals: ${JSON.stringify(req.locals, null, 2)}`) // This boolean value is passed from the auth.js middleware. const proRateLimits = req.locals.proLimit