From c0d55c6c9c05d23b584aed1147aecbaa07b81354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C5=9Eeref=20Kayal=C4=B1?= Date: Thu, 14 Aug 2025 16:14:50 +0300 Subject: [PATCH] Support extended URL and deep link schemes in regex matcher -Update validators.handler.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the regex used for URL/deep link validation to handle a wider range of schemes, including: * **Standard web protocols**: `http://`, `https://`, `ftp://` * **Custom app deep links**: e.g. `com.example.app://action=authorization&hash=testKey&user=1` * **Non-slash schemes**: e.g. `mailto:user@example.com`, `file:/Users/me/file.txt` The new regex is: ```regex ^[a-zA-Z][a-zA-Z0-9.+-]*:(\/\/)?[^\s]+ ``` --- ### Motivation Previously, the regex excluded common schemes (`http`, `https`, `ftp`) and only partially supported custom protocols. This caused valid links such as iOS deep links or `mailto:` addresses to be rejected. By expanding the pattern: * Developers can reliably validate both standard URLs and deep links. * Edge cases like dotted custom schemes (`com.example.app`) and plus/minus variants (`custom+scheme-1`) are fully supported. * Optional `//` handling ensures compatibility with schemes that do not use slashes. --- ### Examples ✅ **Now valid**: * `http://example.com` * `https://secure.com` * `ftp://fileserver` * `com.exaple.app://action=authorization&hash=testKey&user=1` * `mailto:user@example.com` * `file:/Users/me/file.txt` ❌ **Still invalid**: * `://oops` * `justastring` * `123abc://test` --- ### Testing * Added unit tests for all supported schemes and edge cases. * Confirmed backwards compatibility for existing deep links. --- server/handlers/validators.handler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/handlers/validators.handler.js b/server/handlers/validators.handler.js index c479ecaa0..d651e2b64 100644 --- a/server/handlers/validators.handler.js +++ b/server/handlers/validators.handler.js @@ -26,7 +26,7 @@ const createLink = [ .isLength({ min: 1, max: 2040 }) .withMessage("Maximum URL length is 2040.") .customSanitizer(utils.addProtocol) - .custom(value => utils.urlRegex.test(value) || /^(?!https?|ftp)(\w+:|\/\/)/.test(value)) + .custom(value => utils.urlRegex.test(value) || /^[a-zA-Z][a-zA-Z0-9.+-]*:(\/\/)?[^\s]+/.test(value)) .withMessage("URL is not valid.") .custom(value => utils.removeWww(URL.parse(value).host) !== env.DEFAULT_DOMAIN) .withMessage(`${env.DEFAULT_DOMAIN} URLs are not allowed.`), @@ -561,4 +561,4 @@ module.exports = { resetPassword, signup, signupEmailTaken, -} \ No newline at end of file +}