UNPKG

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
/** * 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); }