whitelistip
Version:
Whitelist middleware for express routing function. When present it allows request comming from the whitelisted IPs only. A 403 Forbidden error is sent to all other IP addresses.
68 lines (60 loc) • 3.54 kB
JavaScript
/**
* Middleware to allow only whitelisted IPs to access resources
*/
module.exports = WhitelistIP;
/**
* Constructor function that return a Whitelist objcet
* @param {mixed} allowedIPs The IP addresses to whitelist. Can be a single IP or an array of IP addresses
*/
function WhitelistIP (allowedIPs) {
if (!(this instanceof WhitelistIP)) {
return new WhitelistIP(allowedIPs);
}
//If no IP are provided, forbid all IPs
allowedIPs = allowedIPs || [];
//Check the type of the configuration if String or Array.
if (typeof allowedIPs == "string") {
allowedIPs = [allowedIPs];
} else if (!(allowedIPs instanceof Array)) {
throw new Error("Supplied IPs are in an unsupported format. Provide a single IP as a string or an array of IPs as strings");
}
//Check if it is a valid IP
for (var i = allowedIPs.length - 1; i >= 0; i--) {
if (typeof allowedIPs[i] != "string") {
throw new Error("Supplied IPs are in an unsupported format. Provide a single IP as a string or an array of IPs as strings");
} else if (!this.validateIPv4Address(allowedIPs[i]) && !this.validateIPv6Address(allowedIPs[i])) {
throw new Error(allowedIPs[i] + " is not a valid IP address!");
}
}
this.allowedIPs = allowedIPs;
}
/**
* Apply the restriction to a route
* @return {function} Return a middleware function
*/
WhitelistIP.prototype.restrict = function() {
var self = this;
return function (req, res, next) {
if (self.allowedIPs.indexOf(req.connection.remoteAddress) >= 0) {
next();
} else {
res.status(403).end('Forbidden');
}
}
};
/**
* Validate an IP v4 address
* @param {String} ipaddress The IP address to validate
* @return {Boolean} True if the address is a valid IP
*/
WhitelistIP.prototype.validateIPv4Address = function(ipaddress) {
return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress)
}
/**
* Validate an IP v6 address
* @param {String} ipaddress The IP address to validate
* @return {Boolean} True if the address is a valid IP
*/
WhitelistIP.prototype.validateIPv6Address = function(ipaddress) {
return /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ipaddress);
}