Launch Week Day 3: Introducing Organization Notifications in Socket.Learn More
Socket
Book a DemoSign in
Socket

express-ipfilter

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-ipfilter - npm Package Compare versions

Comparing version
0.3.0
to
0.3.1
+3
-7
CONTRIBUTING.md

@@ -17,12 +17,8 @@ # Contributing

Make sure the tests pass:
**Add tests** for your change. Make sure the tests pass:
npm test
grunt test
Make your change. **Add tests** for your change. Make the tests pass:
Update the version number at the top of the README, add your change to the changelog, and update the version in `package.json`
npm test
Update the version number at the top of the README, add your change to the changelog, and update the version in `packet.json`
Push to your fork and [submit a pull request][pr].

@@ -29,0 +25,0 @@

@@ -50,3 +50,5 @@ /*!

var ipsIsFunction = _.isFunction(ips);
var getIps = _.isFunction(ips) ? ips : function () {
return ips;
};
var logger = function logger(message) {

@@ -65,6 +67,2 @@ console.log(message);

function getIps() {
return ipsIsFunction ? ips() : ips;
}
function getClientIp(req) {

@@ -170,2 +168,7 @@ var ipAddress;

var error = function error(ip, next) {
var err = new IpDeniedError('Access denied to IP address: ' + ip);
return next(err);
};
return function (req, res, next) {

@@ -186,10 +189,15 @@ if (settings.excluding.length > 0) {

var ip = settings.detectIp(req);
// If no IPs were specified, skip
// this middleware
var _ips = getIps();
if (!_ips || !_ips.length) {
return next();
if (settings.mode == 'allow') {
// ip list is empty, thus no one allowed
return error('0.0.0.0/0', next);
} else {
// there are no blocked ips, skip
return next();
}
}
var ip = settings.detectIp(req);
if (matchClientIp(ip, req)) {

@@ -209,6 +217,5 @@ // Grant access

var err = new IpDeniedError('Access denied to IP address: ' + ip);
return next(err);
return error(ip, next);
};
};
//# sourceMappingURL=ipfilter.js.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/ipfilter.js"],"names":["_","require","iputil","rangeCheck","IpDeniedError","module","exports","ipfilter","ips","opts","ipsIsFunction","isFunction","logger","message","console","log","settings","defaults","mode","logF","allowedHeaders","allowPrivateIPs","excluding","detectIp","getClientIp","getIps","req","ipAddress","headerIp","reduce","acc","header","testIp","headers","splitHeaderIp","split","connection","remoteAddress","isV6Format","indexOf","isV4Format","matchClientIp","ip","toLowerCase","result","invoke","some","every","constraint","validRange","testCidrBlock","testExplicitIp","testRange","inRange","filteredSet","filter","length","startIp","toLong","endIp","longIp","res","next","results","exclude","regex","RegExp","test","url","logLevel","_ips","err"],"mappings":"AAAA;;;;;;AAMA;;AAEA;;;;;;AAGA,IAAIA,IAAIC,QAAQ,QAAR,CAAR;AACA,IAAIC,SAASD,QAAQ,IAAR,CAAb;AACA,IAAIE,aAAaF,QAAQ,aAAR,CAAjB;AACA,IAAIG,gBAAgBH,QAAQ,eAAR,CAApB;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BAI,OAAOC,OAAP,GAAiB,SAASC,QAAT,CAAkBC,GAAlB,EAAuBC,IAAvB,EAA6B;AAC5CD,QAAMA,OAAO,KAAb;;AAEA,MAAIE,gBAAgBV,EAAEW,UAAF,CAAaH,GAAb,CAApB;AACA,MAAII,SAAS,SAATA,MAAS,CAASC,OAAT,EAAiB;AAAEC,YAAQC,GAAR,CAAYF,OAAZ;AAAsB,GAAtD;AACA,MAAIG,WAAWhB,EAAEiB,QAAF,CAAYR,QAAQ,EAApB,EAAwB;AACrCS,UAAM,MAD+B;AAErCH,SAAK,IAFgC;AAGrCI,UAAMP,MAH+B;AAIrCQ,oBAAgB,EAJqB;AAKrCC,qBAAiB,KALoB;AAMrCC,eAAW,EAN0B;AAOrCC,cAAUC;AAP2B,GAAxB,CAAf;;AAUA,WAASC,MAAT,GAAkB;AAChB,WAAOf,gBAAgBF,KAAhB,GAAwBA,GAA/B;AACD;;AAED,WAASgB,WAAT,CAAqBE,GAArB,EAA0B;AACxB,QAAIC,SAAJ;;AAEA,QAAIC,WAAW5B,EAAE6B,MAAF,CAASb,SAASI,cAAlB,EAAkC,UAASU,GAAT,EAAcC,MAAd,EAAqB;AACpE,UAAIC,SAASN,IAAIO,OAAJ,CAAYF,MAAZ,CAAb;AACA,UAAGC,UAAU,EAAb,EAAgB;AACdF,cAAME,MAAN;AACD;;AAED,aAAOF,GAAP;AACD,KAPc,EAOb,EAPa,CAAf;;AASA,QAAGF,QAAH,EAAa;AACX,UAAIM,gBAAgBN,SAASO,KAAT,CAAe,GAAf,CAApB;AACAR,kBAAYO,cAAc,CAAd,CAAZ;AACD;;AAED,QAAG,CAACP,SAAJ,EAAe;AACbA,kBAAYD,IAAIU,UAAJ,CAAeC,aAA3B;AACD;;AAED,QAAG,CAACV,SAAJ,EAAc;AACZ,aAAO,EAAP;AACD;;AAED,QAAGzB,OAAOoC,UAAP,CAAkBX,SAAlB,KAAgC,CAACA,UAAUY,OAAV,CAAkB,QAAlB,CAApC,EAAgE;AAC9DZ,kBAAYA,UAAUQ,KAAV,CAAgB,SAAhB,EAA2B,CAA3B,CAAZ;AACD;;AAED,QAAGjC,OAAOsC,UAAP,CAAkBb,SAAlB,KAAgC,CAACA,UAAUY,OAAV,CAAkB,GAAlB,CAApC,EAA2D;AACzDZ,kBAAYA,UAAUQ,KAAV,CAAgB,GAAhB,EAAqB,CAArB,CAAZ;AACD;;AAED,WAAOR,SAAP;AACD;;AAED,MAAIc,gBAAgB,SAAhBA,aAAgB,CAASC,EAAT,EAAY;AAC9B,QAAIxB,OAAOF,SAASE,IAAT,CAAcyB,WAAd,EAAX;;AAEA,QAAIC,SAAS5C,EAAE6C,MAAF,CAASpB,QAAT,EAAkBO,MAAlB,EAAyBU,EAAzB,EAA4BxB,IAA5B,CAAb;;AAEA,QAAGA,SAAS,OAAZ,EAAoB;AAClB,aAAOlB,EAAE8C,IAAF,CAAOF,MAAP,CAAP;AACD,KAFD,MAEK;AACH,aAAO5C,EAAE+C,KAAF,CAAQH,MAAR,CAAP;AACD;AACF,GAVD;;AAYA,MAAIZ,SAAS,SAATA,MAAS,CAASU,EAAT,EAAYxB,IAAZ,EAAiB;AAC5B,QAAI8B,aAAa,IAAjB;;AAEA;AACA,QAAG,OAAOA,UAAP,KAAsB,QAAzB,EAAkC;AAChC,UAAG7C,WAAW8C,UAAX,CAAsBD,UAAtB,CAAH,EAAqC;AACnC,eAAOE,cAAcR,EAAd,EAAiBM,UAAjB,EAA4B9B,IAA5B,CAAP;AACD,OAFD,MAEK;AACH,eAAOiC,eAAeT,EAAf,EAAkBM,UAAlB,EAA6B9B,IAA7B,CAAP;AACD;AACF;;AAED,QAAG,QAAO8B,UAAP,yCAAOA,UAAP,OAAsB,QAAzB,EAAkC;AAChC,aAAOI,UAAUV,EAAV,EAAaM,UAAb,EAAwB9B,IAAxB,CAAP;AACD;AACF,GAfD;;AAiBA,MAAIiC,iBAAiB,SAAjBA,cAAiB,CAAST,EAAT,EAAYM,UAAZ,EAAuB9B,IAAvB,EAA4B;AAC/C,QAAGwB,OAAOM,UAAV,EAAqB;AACnB,aAAO9B,SAAS,OAAhB;AACD,KAFD,MAEK;AACH,aAAOA,SAAS,MAAhB;AACD;AACF,GAND;;AAQA,MAAIgC,gBAAgB,SAAhBA,aAAgB,CAASR,EAAT,EAAYM,UAAZ,EAAuB9B,IAAvB,EAA4B;AAC9C,QAAGf,WAAWkD,OAAX,CAAmBX,EAAnB,EAAuBM,UAAvB,CAAH,EAAsC;AACpC,aAAO9B,SAAS,OAAhB;AACD,KAFD,MAEK;AACH,aAAOA,SAAS,MAAhB;AACD;AACF,GAND;;AAQA,MAAIkC,YAAY,SAAZA,SAAY,CAASV,EAAT,EAAYM,UAAZ,EAAuB9B,IAAvB,EAA4B;AAC1C,QAAIoC,cAActD,EAAEuD,MAAF,CAAS9B,QAAT,EAAkB,UAASuB,UAAT,EAAoB;AACtD,UAAGA,WAAWQ,MAAX,GAAoB,CAAvB,EAAyB;AACvB,YAAIC,UAAUvD,OAAOwD,MAAP,CAAcV,WAAW,CAAX,CAAd,CAAd;AACA,YAAIW,QAAQzD,OAAOwD,MAAP,CAAcV,WAAW,CAAX,CAAd,CAAZ;AACA,YAAIY,SAAS1D,OAAOwD,MAAP,CAAchB,EAAd,CAAb;AACA,eAAQkB,UAAUH,OAAV,IAAqBG,UAAUD,KAAvC;AACD,OALD,MAKK;AACH,eAAOjB,OAAOM,WAAW,CAAX,CAAd;AACD;AACF,KATiB,CAAlB;;AAWA,QAAGM,YAAYE,MAAZ,GAAqB,CAAxB,EAA0B;AACxB,aAAOtC,SAAS,OAAhB;AACD,KAFD,MAEK;AACH,aAAOA,SAAS,MAAhB;AACD;AACF,GAjBD;;AAmBA,SAAO,UAASQ,GAAT,EAAcmC,GAAd,EAAmBC,IAAnB,EAAyB;AAC9B,QAAG9C,SAASM,SAAT,CAAmBkC,MAAnB,GAA4B,CAA/B,EAAiC;AAC/B,UAAIO,UAAU/D,EAAEuD,MAAF,CAASvC,SAASM,SAAlB,EAA4B,UAAS0C,OAAT,EAAiB;AACzD,YAAIC,QAAQ,IAAIC,MAAJ,CAAWF,OAAX,CAAZ;AACA,eAAOC,MAAME,IAAN,CAAWzC,IAAI0C,GAAf,CAAP;AACD,OAHa,CAAd;;AAKA,UAAGL,QAAQP,MAAR,GAAiB,CAApB,EAAsB;AACpB,YAAGxC,SAASD,GAAT,IAAgBC,SAASqD,QAAT,KAAsB,MAAzC,EAAgD;AAC9CrD,mBAASG,IAAT,CAAc,uCAAuC4C,QAAQ,CAAR,CAArD;AACD;AACD,eAAOD,MAAP;AACD;AACF;;AAED,QAAIpB,KAAK1B,SAASO,QAAT,CAAkBG,GAAlB,CAAT;AACA;AACA;AACA,QAAI4C,OAAO7C,QAAX;AACA,QAAG,CAAC6C,IAAD,IAAS,CAACA,KAAKd,MAAlB,EAA0B;AAAE,aAAOM,MAAP;AAAgB;;AAE5C,QAAGrB,cAAcC,EAAd,EAAiBhB,GAAjB,CAAH,EAA0B;AACxB;AACA,UAAGV,SAASD,GAAT,IAAgBC,SAASqD,QAAT,KAAsB,MAAzC,EAAiD;AAC/CrD,iBAASG,IAAT,CAAc,mCAAmCuB,EAAjD;AACD;;AAED,aAAOoB,MAAP;AACD;;AAED;AACA,QAAG9C,SAASD,GAAT,IAAgBC,SAASqD,QAAT,KAAsB,OAAzC,EAAkD;AAChDrD,eAASG,IAAT,CAAc,kCAAkCuB,EAAhD;AACD;;AAED,QAAI6B,MAAM,IAAInE,aAAJ,CAAkB,kCAAkCsC,EAApD,CAAV;AACA,WAAOoB,KAAKS,GAAL,CAAP;AACD,GArCD;AAsCD,CA7JD","file":"ipfilter.js","sourcesContent":["/*!\n * Express - IP Filter\n * Copyright(c) 2014 Bradley and Montgomery Inc.\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module dependencies.\n */\nvar _ = require('lodash');\nvar iputil = require('ip');\nvar rangeCheck = require('range_check');\nvar IpDeniedError = require('./deniedError');\n\n/**\n * express-ipfilter:\n *\n * IP Filtering middleware;\n *\n * Examples:\n *\n * var ipfilter = require('ipfilter'),\n * ips = ['127.0.0.1'];\n * getIps = function() { return ['127.0.0.1']; };\n *\n * app.use(ipfilter(ips));\n * app.use(ipfilter(getIps));\n *\n * Options:\n *\n * - `mode` whether to deny or grant access to the IPs provided. Defaults to 'deny'.\n * - `logF` Function to use for logging.\n * - `log` console log actions. Defaults to true.\n * - `allowPrivateIPs` whether to allow private IPs.\n * - `allowedHeaders` Array of headers to check for forwarded IPs.\n * - 'excluding' routes that should be excluded from ip filtering\n *\n * @param [ips] {Array} IP addresses or {Function} that returns the array of IP addresses\n * @param [opts] {Object} options\n * @api public\n */\nmodule.exports = function ipfilter(ips, opts) {\n ips = ips || false;\n\n var ipsIsFunction = _.isFunction(ips);\n var logger = function(message){ console.log(message);};\n var settings = _.defaults( opts || {}, {\n mode: 'deny',\n log: true,\n logF: logger,\n allowedHeaders: [],\n allowPrivateIPs: false,\n excluding: [],\n detectIp: getClientIp\n });\n\n function getIps() {\n return ipsIsFunction ? ips() : ips;\n }\n\n function getClientIp(req) {\n var ipAddress;\n\n var headerIp = _.reduce(settings.allowedHeaders, function(acc, header){\n var testIp = req.headers[header];\n if(testIp != ''){\n acc = testIp;\n }\n\n return acc;\n },'');\n\n if(headerIp) {\n var splitHeaderIp = headerIp.split(',');\n ipAddress = splitHeaderIp[0];\n }\n\n if(!ipAddress) {\n ipAddress = req.connection.remoteAddress;\n }\n\n if(!ipAddress){\n return '';\n }\n\n if(iputil.isV6Format(ipAddress) && ~ipAddress.indexOf('::ffff')){\n ipAddress = ipAddress.split('::ffff:')[1];\n }\n\n if(iputil.isV4Format(ipAddress) && ~ipAddress.indexOf(':')){\n ipAddress = ipAddress.split(':')[0];\n }\n\n return ipAddress;\n }\n\n var matchClientIp = function(ip){\n var mode = settings.mode.toLowerCase();\n\n var result = _.invoke(getIps(),testIp,ip,mode);\n\n if(mode === 'allow'){\n return _.some(result);\n }else{\n return _.every(result);\n }\n };\n\n var testIp = function(ip,mode){\n var constraint = this;\n\n // Check if it is an array or a string\n if(typeof constraint === 'string'){\n if(rangeCheck.validRange(constraint)){\n return testCidrBlock(ip,constraint,mode);\n }else{\n return testExplicitIp(ip,constraint,mode);\n }\n }\n\n if(typeof constraint === 'object'){\n return testRange(ip,constraint,mode);\n }\n };\n\n var testExplicitIp = function(ip,constraint,mode){\n if(ip === constraint){\n return mode === 'allow';\n }else{\n return mode === 'deny';\n }\n };\n\n var testCidrBlock = function(ip,constraint,mode){\n if(rangeCheck.inRange(ip, constraint)){\n return mode === 'allow';\n }else{\n return mode === 'deny';\n }\n };\n\n var testRange = function(ip,constraint,mode){\n var filteredSet = _.filter(getIps(),function(constraint){\n if(constraint.length > 1){\n var startIp = iputil.toLong(constraint[0]);\n var endIp = iputil.toLong(constraint[1]);\n var longIp = iputil.toLong(ip);\n return longIp >= startIp && longIp <= endIp;\n }else{\n return ip === constraint[0];\n }\n });\n\n if(filteredSet.length > 0){\n return mode === 'allow';\n }else{\n return mode === 'deny';\n }\n };\n\n return function(req, res, next) {\n if(settings.excluding.length > 0){\n var results = _.filter(settings.excluding,function(exclude){\n var regex = new RegExp(exclude);\n return regex.test(req.url);\n });\n\n if(results.length > 0){\n if(settings.log && settings.logLevel !== 'deny'){\n settings.logF('Access granted for excluded path: ' + results[0]);\n }\n return next();\n }\n }\n\n var ip = settings.detectIp(req);\n // If no IPs were specified, skip\n // this middleware\n var _ips = getIps();\n if(!_ips || !_ips.length) { return next(); }\n\n if(matchClientIp(ip,req)) {\n // Grant access\n if(settings.log && settings.logLevel !== 'deny') {\n settings.logF('Access granted to IP address: ' + ip);\n }\n\n return next();\n }\n\n // Deny access\n if(settings.log && settings.logLevel !== 'allow') {\n settings.logF('Access denied to IP address: ' + ip);\n }\n\n var err = new IpDeniedError('Access denied to IP address: ' + ip);\n return next(err);\n };\n};\n"]}
{"version":3,"sources":["../src/ipfilter.js"],"names":["_","require","iputil","rangeCheck","IpDeniedError","module","exports","ipfilter","ips","opts","getIps","isFunction","logger","message","console","log","settings","defaults","mode","logF","allowedHeaders","allowPrivateIPs","excluding","detectIp","getClientIp","req","ipAddress","headerIp","reduce","acc","header","testIp","headers","splitHeaderIp","split","connection","remoteAddress","isV6Format","indexOf","isV4Format","matchClientIp","ip","toLowerCase","result","invoke","some","every","constraint","validRange","testCidrBlock","testExplicitIp","testRange","inRange","filteredSet","filter","length","startIp","toLong","endIp","longIp","error","next","err","res","results","exclude","regex","RegExp","test","url","logLevel","_ips"],"mappings":"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","file":"ipfilter.js","sourcesContent":["/*!\n * Express - IP Filter\n * Copyright(c) 2014 Bradley and Montgomery Inc.\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module dependencies.\n */\nvar _ = require('lodash');\nvar iputil = require('ip');\nvar rangeCheck = require('range_check');\nvar IpDeniedError = require('./deniedError');\n\n/**\n * express-ipfilter:\n *\n * IP Filtering middleware;\n *\n * Examples:\n *\n * var ipfilter = require('ipfilter'),\n * ips = ['127.0.0.1'];\n * getIps = function() { return ['127.0.0.1']; };\n *\n * app.use(ipfilter(ips));\n * app.use(ipfilter(getIps));\n *\n * Options:\n *\n * - `mode` whether to deny or grant access to the IPs provided. Defaults to 'deny'.\n * - `logF` Function to use for logging.\n * - `log` console log actions. Defaults to true.\n * - `allowPrivateIPs` whether to allow private IPs.\n * - `allowedHeaders` Array of headers to check for forwarded IPs.\n * - 'excluding' routes that should be excluded from ip filtering\n *\n * @param [ips] {Array} IP addresses or {Function} that returns the array of IP addresses\n * @param [opts] {Object} options\n * @api public\n */\nmodule.exports = function ipfilter(ips, opts) {\n ips = ips || false;\n\n var getIps = _.isFunction(ips) ? ips : function(){ return ips; };\n var logger = function(message){ console.log(message);};\n var settings = _.defaults( opts || {}, {\n mode: 'deny',\n log: true,\n logF: logger,\n allowedHeaders: [],\n allowPrivateIPs: false,\n excluding: [],\n detectIp: getClientIp\n });\n\n function getClientIp(req) {\n var ipAddress;\n\n var headerIp = _.reduce(settings.allowedHeaders, function(acc, header){\n var testIp = req.headers[header];\n if(testIp != ''){\n acc = testIp;\n }\n\n return acc;\n },'');\n\n if(headerIp) {\n var splitHeaderIp = headerIp.split(',');\n ipAddress = splitHeaderIp[0];\n }\n\n if(!ipAddress) {\n ipAddress = req.connection.remoteAddress;\n }\n\n if(!ipAddress){\n return '';\n }\n\n if(iputil.isV6Format(ipAddress) && ~ipAddress.indexOf('::ffff')){\n ipAddress = ipAddress.split('::ffff:')[1];\n }\n\n if(iputil.isV4Format(ipAddress) && ~ipAddress.indexOf(':')){\n ipAddress = ipAddress.split(':')[0];\n }\n\n return ipAddress;\n }\n\n var matchClientIp = function(ip){\n var mode = settings.mode.toLowerCase();\n\n var result = _.invoke(getIps(),testIp,ip,mode);\n\n if(mode === 'allow'){\n return _.some(result);\n }else{\n return _.every(result);\n }\n };\n\n var testIp = function(ip,mode){\n var constraint = this;\n\n // Check if it is an array or a string\n if(typeof constraint === 'string'){\n if(rangeCheck.validRange(constraint)){\n return testCidrBlock(ip,constraint,mode);\n }else{\n return testExplicitIp(ip,constraint,mode);\n }\n }\n\n if(typeof constraint === 'object'){\n return testRange(ip,constraint,mode);\n }\n };\n\n var testExplicitIp = function(ip,constraint,mode){\n if(ip === constraint){\n return mode === 'allow';\n }else{\n return mode === 'deny';\n }\n };\n\n var testCidrBlock = function(ip,constraint,mode){\n if(rangeCheck.inRange(ip, constraint)){\n return mode === 'allow';\n }else{\n return mode === 'deny';\n }\n };\n\n var testRange = function(ip,constraint,mode){\n var filteredSet = _.filter(getIps(),function(constraint){\n if(constraint.length > 1){\n var startIp = iputil.toLong(constraint[0]);\n var endIp = iputil.toLong(constraint[1]);\n var longIp = iputil.toLong(ip);\n return longIp >= startIp && longIp <= endIp;\n }else{\n return ip === constraint[0];\n }\n });\n\n if(filteredSet.length > 0){\n return mode === 'allow';\n }else{\n return mode === 'deny';\n }\n };\n\n var error = function(ip, next){\n var err = new IpDeniedError('Access denied to IP address: ' + ip);\n return next(err);\n };\n\n return function(req, res, next) {\n if(settings.excluding.length > 0){\n var results = _.filter(settings.excluding,function(exclude){\n var regex = new RegExp(exclude);\n return regex.test(req.url);\n });\n\n if(results.length > 0){\n if(settings.log && settings.logLevel !== 'deny'){\n settings.logF('Access granted for excluded path: ' + results[0]);\n }\n return next();\n }\n }\n\n var _ips = getIps();\n if(!_ips || !_ips.length) {\n if(settings.mode == 'allow'){\n // ip list is empty, thus no one allowed\n return error('0.0.0.0/0', next);\n } else {\n // there are no blocked ips, skip\n return next();\n }\n }\n\n var ip = settings.detectIp(req);\n\n if(matchClientIp(ip,req)) {\n // Grant access\n if(settings.log && settings.logLevel !== 'deny') {\n settings.logF('Access granted to IP address: ' + ip);\n }\n\n return next();\n }\n\n // Deny access\n if(settings.log && settings.logLevel !== 'allow') {\n settings.logF('Access denied to IP address: ' + ip);\n }\n\n return error(ip, next);\n };\n};\n"]}
{
"name": "express-ipfilter",
"description": "A light-weight IP address based filtering system",
"version": "0.3.0",
"version": "0.3.1",
"author": "BaM Interactive",

@@ -6,0 +6,0 @@ "dependencies": {

@@ -9,3 +9,3 @@ express-ipfilter: A light-weight IP address based filtering system

## Version
0.3.0
0.3.1

@@ -160,2 +160,7 @@ ## Installation

0.3.1
* Fixes critical bug that allowed access when ips is empty and mode == 'allow'.
* Adds minor speed improvements for middleware.
* Minor spelling and documentation fixes in README
0.3.0

@@ -162,0 +167,0 @@ * Adds the ability to pass IPs by function so that we can dynamically retrieve white/black listed addresses.

@@ -47,3 +47,3 @@ /*!

var ipsIsFunction = _.isFunction(ips);
var getIps = _.isFunction(ips) ? ips : function(){ return ips; };
var logger = function(message){ console.log(message);};

@@ -60,6 +60,2 @@ var settings = _.defaults( opts || {}, {

function getIps() {
return ipsIsFunction ? ips() : ips;
}
function getClientIp(req) {

@@ -165,2 +161,7 @@ var ipAddress;

var error = function(ip, next){
var err = new IpDeniedError('Access denied to IP address: ' + ip);
return next(err);
};
return function(req, res, next) {

@@ -181,8 +182,15 @@ if(settings.excluding.length > 0){

var ip = settings.detectIp(req);
// If no IPs were specified, skip
// this middleware
var _ips = getIps();
if(!_ips || !_ips.length) { return next(); }
if(!_ips || !_ips.length) {
if(settings.mode == 'allow'){
// ip list is empty, thus no one allowed
return error('0.0.0.0/0', next);
} else {
// there are no blocked ips, skip
return next();
}
}
var ip = settings.detectIp(req);
if(matchClientIp(ip,req)) {

@@ -202,5 +210,4 @@ // Grant access

var err = new IpDeniedError('Access denied to IP address: ' + ip);
return next(err);
return error(ip, next);
};
};

@@ -67,43 +67,62 @@ /* global describe, it, beforeEach */

describe('enforcing IP address whitelist restrictions', function () {
describe('with a whitelist with no ips', function () {
beforeEach(function () {
this.ipfilter = ipfilter([], { mode: 'allow', log: true });
this.req = {
session: {},
headers: [],
connection: {
remoteAddress: ''
}
};
});
beforeEach(function () {
this.ipfilter = ipfilter(['127.0.0.1'], { log: false, mode: 'allow', allowedHeaders: ['x-forwarded-for'] });
this.req = {
session: {},
headers: [],
connection: {
remoteAddress: ''
}
};
it('should deny', function (done) {
this.req.connection.remoteAddress = '127.0.0.1';
checkError(this.ipfilter, this.req, done);
});
});
it('should allow whitelisted ips', function (done) {
this.req.connection.remoteAddress = '127.0.0.1';
this.ipfilter(this.req, {}, function () {
done();
describe('with a whitelist with ips', function () {
beforeEach(function () {
this.ipfilter = ipfilter(['127.0.0.1'], { log: false, mode: 'allow', allowedHeaders: ['x-forwarded-for'] });
this.req = {
session: {},
headers: [],
connection: {
remoteAddress: ''
}
};
});
});
it('should allow whitelisted forwarded ips', function (done) {
this.req.headers['x-forwarded-for'] = '127.0.0.1';
this.ipfilter(this.req, {}, function () {
done();
it('should allow whitelisted ips', function (done) {
this.req.connection.remoteAddress = '127.0.0.1';
this.ipfilter(this.req, {}, function () {
done();
});
});
});
it('should allow whitelisted port ips', function (done) {
this.req.connection.remoteAddress = '127.0.0.1:84849';
this.ipfilter(this.req, {}, function () {
done();
it('should allow whitelisted forwarded ips', function (done) {
this.req.headers['x-forwarded-for'] = '127.0.0.1';
this.ipfilter(this.req, {}, function () {
done();
});
});
});
it('should deny all non-whitelisted ips', function (done) {
this.req.connection.remoteAddress = '127.0.0.2';
checkError(this.ipfilter, this.req, done);
});
it('should allow whitelisted port ips', function (done) {
this.req.connection.remoteAddress = '127.0.0.1:84849';
this.ipfilter(this.req, {}, function () {
done();
});
});
it('should deny all non-whitelisted forwarded ips', function (done) {
this.req.headers['x-forwarded-for'] = '127.0.0.2';
checkError(this.ipfilter, this.req, done);
it('should deny all non-whitelisted ips', function (done) {
this.req.connection.remoteAddress = '127.0.0.2';
checkError(this.ipfilter, this.req, done);
});
it('should deny all non-whitelisted forwarded ips', function (done) {
this.req.headers['x-forwarded-for'] = '127.0.0.2';
checkError(this.ipfilter, this.req, done);
});
});

@@ -110,0 +129,0 @@ });