Home > Enterprise >  Is there a regex to be able to match two url's , one that has a wildcard and one that doesn
Is there a regex to be able to match two url's , one that has a wildcard and one that doesn

Time:11-01

I am writing a program in Nodejs with the following scenarios.

I have an array of url's that include wildcards, such as the following: https://*.example.com/example/login http://www.example2.com/*/example2/callback

Secondly, I have an incoming redirect url that I need to validate matches what is in the array of url's above. I was wondering if there was a way using Regex or anything else that I can use something like arr.includes(incomingRedirectUrl) and compare the two.

I can match non-wildcard url's using array.includes(incomingRedirectUrl), but when it comes to matching the array that has wildcards, I cannot think of a solution.

For example, https://x.example.com/example/login should work because it matches the first url in the above example, only replacing the "*" with the x.

Is there a way I can achieve this? Or do I have to break down the url's using something like slice at the "*" to compare the two?

Thanks in advance for any help.

  for (let i = 0; i < arr.length; i  ) {
    if (arr[i].indexOf('*') !== -1) {
      wildcardArr.push(arr[i]);
    } else {
      noWildcardArr.push(arr[i]);
    }
  }
***Note, the reason I check noWildcardArr first is because most of the validate redirect url's do not contain wildcard

  if (noWildcardArr.includes(incomingRedirectUrl)) {
    //Validated correct url, proceed with the next part of my code (this part already works)
  } else if (wildcardArr.includes(incomingRedirectUrl)) {
    //need to figure out this logic here, not sure if the above is possible without formatting wildcardArr but url should be validated if url matches with wildcard
  } else {
    log.error('authorize: Bad Request - Invalid Redirect URL');
    context.res = {
      status: 400,
      body: 'Bad Request - Invalid Redirect URL',
    };
  }

CodePudding user response:

You could compile your URL array into proper regex and then iterate over them to see if it matches. Similar to something like a web framework would do that allows URL path parameters such as /users/:id.

function makeMatcher(urls) {
  const compiled = urls.map(url => {
    // regex escape the url but dont escape *
    let exp = url.replace(/[-[\]{}() ?.,\\^$|#\s]/g, '\\$&');
    // replace * with .  for the wildcard
    exp = exp.replaceAll('*', '. ');
    // the expression is used to create the match function    
    return new RegExp(`^${exp}$`);
  });

  // return the match function, which returns true, on the first match,
  // or false, if there is no match at all
  return function match(url) {
    return compiled.find(regex => url.match(regex)) == undefined ?
      false :
      true;
  };

}

const matches = makeMatcher([
  'https://*.example.com/example/login',
  'http://www.example2.com/*/example2/callback'
]);

// these 2 should match
console.log(matches('https://x.example.com/example/login'));
console.log(matches('http://www.example2.com/foo/example2/callback'));

// this one not
console.log(matches('http://nope.example2.com/foo/example2/callback'));

  • Related