ise ip instead of rolling my own ip address validation

This commit is contained in:
Matthew Bell 2024-08-19 16:47:44 -04:00
parent 6ff2333220
commit 628b97c6dc
6 changed files with 76 additions and 84 deletions

View file

@ -1,66 +1,6 @@
const passport = require('passport')
const requestIp = require('../libs/requestIp')
function ipToBinary(ip) {
if (ip === '::1') {
ip = '127.0.0.1'
}
return ip
.split('.')
.map(Number)
.map((num) => num.toString(2).padStart(8, '0'))
.join('')
}
function binaryToIp(binary) {
return binary
.match(/.{8}/g)
.map((bin) => parseInt(bin, 2))
.join('.')
}
function cidrToMask(cidr) {
const mask = Array(32).fill('0')
for (let i = 0; i < cidr; i++) {
mask[i] = '1'
}
return mask
.join('')
.match(/.{8}/g)
.map((bin) => parseInt(bin, 2))
.join('.')
}
/**
* Checks if an IP address falls within a given CIDR range.
* If no range is provided, it assumes the CIDR + range are in the "0.0.0.0/0" format.
*
* @param {string} ip - The IP address to check. Can be either IPv4 or IPv6.
* @param {string} cidr - The CIDR notation specifying the network. If `range` is not provided, this value represents the network IP and CIDR in "IP/CIDR" format.
* @param {string} [range] - The IP address representing the range or network. Optional. If not provided, the function assumes "0.0.0.0/0" as the default range.
* @returns {boolean} `true` if the IP address is within the given CIDR range; otherwise, `false`.
*/
function ipInRange(ip, cidr, range) {
// if no range is provided, assume the cidr + range are in the "0.0.0.0/0" format
if (!range) {
let [rangeIp, rangeCidr] = cidr.split('/')
if (!rangeCidr) {
rangeCidr = '0' // if no cidr is provided, assume 0 (exact match)
}
return ipInRange(ip, rangeCidr, rangeIp)
}
const mask = cidrToMask(cidr)
const ipBin = ipToBinary(ip)
const maskBin = ipToBinary(mask)
const rangeBin = ipToBinary(range)
// Apply the mask to the IP and range
const ipNetwork = ipBin.substring(0, maskBin.length)
const rangeNetwork = rangeBin.substring(0, maskBin.length)
return ipNetwork === rangeNetwork
}
class ForwardStrategy extends passport.Strategy {
/**
* Creates a new ForwardStrategy instance.
@ -88,12 +28,17 @@ class ForwardStrategy extends passport.Strategy {
*/
authenticate(req) {
const username = req.headers[this._header]
const ip = requestIp.getClientIp(req)
const ipAddress = requestIp.getClientIp(req)
if (!username) {
return this.fail('No username found')
}
this._verify(req, username, ip, (err, user) => {
if (!ipAddress) {
return this.fail('No IP address found')
}
this._verify(req, username, ipAddress, (err, user) => {
if (err) {
return this.error(err)
}
@ -105,7 +50,4 @@ class ForwardStrategy extends passport.Strategy {
}
}
module.exports = {
ForwardStrategy,
ipInRange
}
module.exports = ForwardStrategy