From d28acfdb20003c7d17a9495f9e3f1b81973425e3 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sat, 24 Aug 2024 01:50:34 +0200 Subject: [PATCH] Improve URL-validation for blocked and discouraged sites --- langs/en.json | 5 ++-- .../InputElement/Validators/UrlValidator.ts | 28 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/langs/en.json b/langs/en.json index f894c64115..23b50736ee 100644 --- a/langs/en.json +++ b/langs/en.json @@ -847,9 +847,10 @@ }, "tooLong": "The text is too long, at most 255 characters are allowed. You have {count} characters now.", "url": { - "aggregator": "{host} is a third-party aggregator website. If possible, search the official website.", + "aggregator": "{host} is a third-party website. If possible, search the official website.", "description": "link to a website", - "feedback": "This is not a valid web address" + "feedback": "This is not a valid web address", + "spamSite": "{host} is considered a low-quality website. Using this website is not allowed." }, "wikidata": { "description": "A Wikidata identifier", diff --git a/src/UI/InputElement/Validators/UrlValidator.ts b/src/UI/InputElement/Validators/UrlValidator.ts index 148562f42e..6854c94153 100644 --- a/src/UI/InputElement/Validators/UrlValidator.ts +++ b/src/UI/InputElement/Validators/UrlValidator.ts @@ -5,14 +5,19 @@ import Translations from "../../i18n/Translations" export default class UrlValidator extends Validator { private readonly _forceHttps: boolean - private static readonly aggregatorWebsites = new Set([ + private static readonly spamWebsites = new Set([ "booking.com", "hotel-details-guide.com", "tripingguide.com", "tripadvisor.com", "tripadvisor.co.uk", "tripadvisor.com.au", - "katestravelexperience.eu" + "katestravelexperience.eu", + "hoteldetails.eu" + ]) + + private static readonly discouragedWebsites = new Set([ + "facebook.com" ]) constructor(name?: string, explanation?: string, forceHttps?: boolean) { @@ -89,15 +94,27 @@ export default class UrlValidator extends Validator { * */ getFeedback(s: string, getCountry?: () => string): Translation | undefined { + if ( + !s.startsWith("http://") && + !s.startsWith("https://") && + !s.startsWith("http:") + ) { + s = "https://" + s + } try{ const url = new URL(s) let host = url.host.toLowerCase() if (host.startsWith("www.")) { host = host.slice(4) } - if (UrlValidator.aggregatorWebsites.has(host)) { + if (UrlValidator.spamWebsites.has(host)) { + return Translations.t.validation.url.spamSite.Subs({ host }) + } + if (UrlValidator.discouragedWebsites.has(host)) { return Translations.t.validation.url.aggregator.Subs({ host }) } + + }catch (e) { // pass } @@ -111,6 +128,7 @@ export default class UrlValidator extends Validator { } isValid(str: string): boolean { + try { if ( !str.startsWith("http://") && @@ -120,16 +138,16 @@ export default class UrlValidator extends Validator { str = "https://" + str } const url = new URL(str) - const dotIndex = url.host.indexOf(".") let host = url.host.toLowerCase() if (host.startsWith("www.")) { host = host.slice(4) } - if (UrlValidator.aggregatorWebsites.has(host)) { + if (UrlValidator.spamWebsites.has(host)) { return false } + const dotIndex = url.host.indexOf(".") return dotIndex > 0 && url.host[url.host.length - 1] !== "." } catch (e) { return false