express-unless icon indicating copy to clipboard operation
express-unless copied to clipboard

can't use unless for req.params

Open imakshath opened this issue 9 years ago • 2 comments

Hi,

I have the requirement to unless the endpoint url as below,

/api/sample/:type

here 'type' is the request param. The problem is that i can't unless the url . Its still showing unauthorized. So what is the solution for this?

imakshath avatar Jan 13 '16 12:01 imakshath

Hi Admin,

I have made some changes in index.js for fixing this issue. the changed index.js file looks as below,

var URL = require('url');
var UrlPattern = require('url-pattern');

module.exports = function (options) {
  var parent = this;

  var opts = typeof options === 'function' ? {custom: options} : options;
  opts.useOriginalUrl = (typeof opts.useOriginalUrl === 'undefined') ? true : opts.useOriginalUrl;

  return function (req, res, next) {
    var url = URL.parse((opts.useOriginalUrl ? req.originalUrl : req.url) || req.url || '', true);

    var skip = false;

    if (opts.custom) {
      skip = skip || opts.custom(req);
    }

    var paths = !opts.path || Array.isArray(opts.path) ?
                opts.path : [opts.path];

    if (paths) {
      skip = skip || paths.some(function (p) {
        return isUrlMatch(p, url.pathname) && isMethodMatch(p.methods, req.method);
      });
    }

    var exts = (!opts.ext || Array.isArray(opts.ext)) ?
               opts.ext : [opts.ext];

    if (exts) {
      skip = skip || exts.some(function (ext) {
        return url.pathname.substr(ext.length * -1) === ext;
      });
    }

    var methods = (!opts.method || Array.isArray(opts.method)) ?
                  opts.method : [opts.method];

    if (methods) {
      skip = skip || !!~methods.indexOf(req.method);
    }

    if (skip) {
      return next();
    }

    parent(req, res, next);
  };
};

function isUrlMatch(p, url) {
  var pattern = new UrlPattern(p);
  var ret = (typeof p === 'string' && p === url) || (p instanceof RegExp && !!p.exec(url)) || (typeof p === 'string' && pattern.match(url) != null);
  if (p instanceof RegExp) {
    p.lastIndex = 0;
  }

  if (p && p.url) {
    ret = isUrlMatch(p.url, url)
  }
  return ret;
}

function isMethodMatch(methods, m) {
  if (!methods) {
    return true;
  }

  methods = Array.isArray(methods) ? methods : [methods];

  return !!~methods.indexOf(m);
}

I have injected url-pattern npm module for tracking the url and as well as updated the isUrlMatch() function for comparing the url with the array. Now its working fine for me.

imakshath avatar Jan 15 '16 06:01 imakshath

Hi akshath4u, i think i'm faceing the same problem but what i need now is to be able to pass as a url parameter a jwt token, for example i need to be able to do this:

http://localhost:8080/setNewPassword/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZhY3VuZG9fbGFyb2NjYUB5YWhvby5jb20uYXIiLCJpYXQiOjE0NzYxMjgxNTZ9.uaLidLZ2eQLSa5ppW7N3z61xUHj5kSyTUUc8Q9nN_KY

GET http://localhost:8080/setNewPassword/:token

Have you got any idea how to solve this?

Thanks a lot.

flarocca avatar Oct 10 '16 20:10 flarocca