mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-22 09:12:05 -07:00
Trying to reinstate basic auth
This commit is contained in:
+49
-49
@@ -22,9 +22,9 @@
|
||||
'use strict'
|
||||
|
||||
const passport = require('passport')
|
||||
// const BasicStrategy = require('passport-http').BasicStrategy
|
||||
const BasicStrategy = require('passport-http').BasicStrategy
|
||||
const AnonymousStrategy = require('passport-anonymous')
|
||||
// const wlogger = require('../util/winston-logging')
|
||||
const wlogger = require('../util/winston-logging')
|
||||
|
||||
// Used for debugging and iterrogating JS objects.
|
||||
const util = require('util')
|
||||
@@ -33,9 +33,9 @@ util.inspect.defaultOptions = { depth: 1 }
|
||||
// let _this
|
||||
|
||||
// Set default rate limit value for testing
|
||||
// const PRO_PASSES = process.env.PRO_PASS ? process.env.PRO_PASS : 'BITBOX'
|
||||
const PRO_PASSES = process.env.PRO_PASS ? process.env.PRO_PASS : 'BITBOX'
|
||||
// Convert the pro-tier password string into an array split by ':'.
|
||||
// const PRO_PASS = PRO_PASSES.split(':')
|
||||
const PRO_PASS = PRO_PASSES.split(':')
|
||||
|
||||
// wlogger.verbose(`PRO_PASS set to: ${PRO_PASS}`)
|
||||
|
||||
@@ -48,55 +48,55 @@ class AuthMW {
|
||||
passport.use(new AnonymousStrategy())
|
||||
|
||||
// Initialize passport for 'basic' authentication.
|
||||
// passport.use(
|
||||
// new BasicStrategy({ passReqToCallback: true }, function (
|
||||
// req,
|
||||
// username,
|
||||
// password,
|
||||
// done
|
||||
// ) {
|
||||
// // console.log(`req: ${util.inspect(req)}`)
|
||||
// // console.log(`username: ${username}`)
|
||||
// // console.log(`password: ${password}`)
|
||||
//
|
||||
// // Create the req.locals property if it does not yet exist.
|
||||
// if (!req.locals) {
|
||||
// req.locals = {
|
||||
// // default values
|
||||
// proLimit: false,
|
||||
// apiLevel: 0
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Set pro-tier rate limit to flag to false by default.
|
||||
// req.locals.proLimit = false
|
||||
//
|
||||
// // Evaluate the username and password and set the rate limit accordingly.
|
||||
// // if (username === "BITBOX" && password === PRO_PASS) {
|
||||
// if (username === 'BITBOX') {
|
||||
// for (let i = 0; i < PRO_PASS.length; i++) {
|
||||
// const thisPass = PRO_PASS[i]
|
||||
//
|
||||
// if (password === thisPass) {
|
||||
// wlogger.verbose(`${req.url} called by ${password.slice(0, 6)}`)
|
||||
//
|
||||
// // Success
|
||||
// req.locals.proLimit = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // console.log(`req.locals: ${util.inspect(req.locals)}`)
|
||||
//
|
||||
// return done(null, true)
|
||||
// })
|
||||
// )
|
||||
passport.use(
|
||||
new BasicStrategy({ passReqToCallback: true }, function (
|
||||
req,
|
||||
username,
|
||||
password,
|
||||
done
|
||||
) {
|
||||
// console.log(`req: ${util.inspect(req)}`)
|
||||
// console.log(`username: ${username}`)
|
||||
// console.log(`password: ${password}`)
|
||||
|
||||
// Create the req.locals property if it does not yet exist.
|
||||
if (!req.locals) {
|
||||
req.locals = {
|
||||
// default values
|
||||
proLimit: false,
|
||||
apiLevel: 0
|
||||
}
|
||||
}
|
||||
|
||||
// Set pro-tier rate limit to flag to false by default.
|
||||
req.locals.proLimit = false
|
||||
|
||||
// Evaluate the username and password and set the rate limit accordingly.
|
||||
// if (username === "BITBOX" && password === PRO_PASS) {
|
||||
if (username === 'fullstackcash') {
|
||||
for (let i = 0; i < PRO_PASS.length; i++) {
|
||||
const thisPass = PRO_PASS[i]
|
||||
|
||||
if (password === thisPass) {
|
||||
wlogger.verbose(`${req.url} called by ${password.slice(0, 6)}`)
|
||||
|
||||
// Success
|
||||
req.locals.proLimit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(`req.locals: ${util.inspect(req.locals)}`)
|
||||
|
||||
return done(null, true)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// Middleware called by the route.
|
||||
mw () {
|
||||
return passport.authenticate(['anonymous'], {
|
||||
return passport.authenticate(['anonymous', 'basic'], {
|
||||
session: false
|
||||
})
|
||||
}
|
||||
|
||||
@@ -113,74 +113,77 @@ class RateLimits {
|
||||
// Default value is 50 points per request = 20 RPM
|
||||
let rateLimit = 50
|
||||
|
||||
// Code here for the rate limiter is adapted from this example:
|
||||
// https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#authorized-and-not-authorized-users
|
||||
try {
|
||||
// The resource being consumed: full node, indexer, SLPDB, etc.
|
||||
const resource = _this.getResource(req.url)
|
||||
wlogger.debug(`resource: ${resource}`)
|
||||
// Only evaluate the JWT token if the user is not using Basic Authentication.
|
||||
if (!req.locals.proLimit) {
|
||||
// Code here for the rate limiter is adapted from this example:
|
||||
// https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#authorized-and-not-authorized-users
|
||||
try {
|
||||
// The resource being consumed: full node, indexer, SLPDB, etc.
|
||||
const resource = _this.getResource(req.url)
|
||||
wlogger.debug(`resource: ${resource}`)
|
||||
|
||||
let key = userId || req.ip
|
||||
res.locals.key = key // Feedback for tests.
|
||||
let key = userId || req.ip
|
||||
res.locals.key = key // Feedback for tests.
|
||||
|
||||
// const pointsToConsume = userId ? 1 : 30
|
||||
decoded.resource = resource
|
||||
let pointsToConsume = _this.calcPoints(decoded)
|
||||
res.locals.pointsToConsume = pointsToConsume // Feedback for tests.
|
||||
|
||||
// Retrieve the origin.
|
||||
let origin = req.get('origin')
|
||||
|
||||
// Handle calls coming from the intranet.
|
||||
if (origin === undefined && key.indexOf('10.0.0.5') > -1) {
|
||||
origin = 'slp-api'
|
||||
}
|
||||
|
||||
wlogger.info(`origin: ${origin}`)
|
||||
|
||||
// If the request originates from one of the approved wallet apps, then
|
||||
// apply paid-access rate limits.
|
||||
if (
|
||||
origin &&
|
||||
(origin.toString().indexOf('wallet.fullstack.cash') > -1 ||
|
||||
origin.toString().indexOf('sandbox.fullstack.cash') > -1 ||
|
||||
origin === 'slp-api')
|
||||
) {
|
||||
pointsToConsume = 10
|
||||
// const pointsToConsume = userId ? 1 : 30
|
||||
decoded.resource = resource
|
||||
let pointsToConsume = _this.calcPoints(decoded)
|
||||
res.locals.pointsToConsume = pointsToConsume // Feedback for tests.
|
||||
|
||||
// Retrieve the origin.
|
||||
let origin = req.get('origin')
|
||||
|
||||
// Handle calls coming from the intranet.
|
||||
if (origin === undefined && key.indexOf('10.0.0.5') > -1) {
|
||||
origin = 'slp-api'
|
||||
}
|
||||
|
||||
wlogger.info(`origin: ${origin}`)
|
||||
|
||||
// If the request originates from one of the approved wallet apps, then
|
||||
// apply paid-access rate limits.
|
||||
if (
|
||||
origin &&
|
||||
(origin.toString().indexOf('wallet.fullstack.cash') > -1 ||
|
||||
origin.toString().indexOf('sandbox.fullstack.cash') > -1 ||
|
||||
origin === 'slp-api')
|
||||
) {
|
||||
pointsToConsume = 10
|
||||
res.locals.pointsToConsume = pointsToConsume // Feedback for tests.
|
||||
}
|
||||
|
||||
// For internal calls, increase rate limits to as fast as possible.
|
||||
if (
|
||||
key.toString().indexOf('172.17.') > -1 ||
|
||||
key.toString().indexOf('::ffff:127.0.0.1') > -1
|
||||
) {
|
||||
pointsToConsume = 1
|
||||
res.locals.pointsToConsume = pointsToConsume // Feedback for tests.
|
||||
}
|
||||
|
||||
wlogger.info(
|
||||
`User ${key} consuming ${pointsToConsume} point for resource ${resource}.`
|
||||
)
|
||||
|
||||
rateLimit = Math.floor(1000 / pointsToConsume)
|
||||
|
||||
// Update the key so that rate limits track both the user and the resource.
|
||||
key = `${key}-${resource}`
|
||||
|
||||
await _this.rateLimiter.consume(key, pointsToConsume)
|
||||
} catch (err) {
|
||||
// console.log('err: ', err)
|
||||
|
||||
// Used for returning data for tests.
|
||||
res.locals.rateLimitTriggered = true
|
||||
// console.log('res.locals: ', res.locals)
|
||||
|
||||
// Rate limited was triggered
|
||||
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||
return res.json({
|
||||
error: `Too many requests. Your limits are currently ${rateLimit} requests per minute. Increase rate limits at https://fullstack.cash`
|
||||
})
|
||||
}
|
||||
|
||||
// For internal calls, increase rate limits to as fast as possible.
|
||||
if (
|
||||
key.toString().indexOf('172.17.') > -1 ||
|
||||
key.toString().indexOf('::ffff:127.0.0.1') > -1
|
||||
) {
|
||||
pointsToConsume = 1
|
||||
res.locals.pointsToConsume = pointsToConsume // Feedback for tests.
|
||||
}
|
||||
|
||||
wlogger.info(
|
||||
`User ${key} consuming ${pointsToConsume} point for resource ${resource}.`
|
||||
)
|
||||
|
||||
rateLimit = Math.floor(1000 / pointsToConsume)
|
||||
|
||||
// Update the key so that rate limits track both the user and the resource.
|
||||
key = `${key}-${resource}`
|
||||
|
||||
await _this.rateLimiter.consume(key, pointsToConsume)
|
||||
} catch (err) {
|
||||
// console.log('err: ', err)
|
||||
|
||||
// Used for returning data for tests.
|
||||
res.locals.rateLimitTriggered = true
|
||||
// console.log('res.locals: ', res.locals)
|
||||
|
||||
// Rate limited was triggered
|
||||
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||
return res.json({
|
||||
error: `Too many requests. Your limits are currently ${rateLimit} requests per minute. Increase rate limits at https://fullstack.cash`
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
wlogger.error('Error in route-ratelimit.js/newRateLimit(): ', err)
|
||||
|
||||
Reference in New Issue
Block a user