From 9deaaf4fb2a6b0e3d9bd524f2b0626aef3df19ba Mon Sep 17 00:00:00 2001 From: Chris Taylor Date: Tue, 14 Jan 2025 22:27:27 +0000 Subject: [PATCH] Add tests for domain parser --- packages/util/src/tests/url.unit.test.ts | 63 ++++++++++++++++++++++++ packages/util/src/url.ts | 16 ++++-- 2 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 packages/util/src/tests/url.unit.test.ts diff --git a/packages/util/src/tests/url.unit.test.ts b/packages/util/src/tests/url.unit.test.ts new file mode 100644 index 0000000000..2431e962e6 --- /dev/null +++ b/packages/util/src/tests/url.unit.test.ts @@ -0,0 +1,63 @@ +// Copyright 2021-2024 Prosopo (UK) Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import { describe, expect, it } from "vitest"; +import { validateDomain } from "../url.js"; + +describe("url", () => { + it("validates valid domains", () => { + const domains = [ + "google.com", + "www.google.com", + "www.google.co.uk", + "www.google.co", + "google.co", + "google.co.uk", + "www.google.com.au", + "prosopo.io", + "averylongdomainnamethatnobodywouldeverremember.com", + ]; + domains.map((domain) => { + expect(validateDomain(domain)).to.equal(true); + }); + }); + it("does not validate an email address", () => { + expect(validateDomain("blah@gmail.com")).to.equal(false); + }); + it("does not validate a domain ending in a dot", () => { + expect(validateDomain("google.")).to.equal(false); + }); + it("does not validate a domain containing an @", () => { + expect(validateDomain("goo@gle")).to.equal(false); + }); + it("does not validate a domain with a leading dot", () => { + expect(validateDomain(".google.com")).to.equal(false); + }); + it("validates a very long domain name", () => { + // 253 characters is the maximum length of full domain name, including dots: e.g. www.example.com = 15 characters. + // + // 63 characters in the maximum length of a "label" (part of domain name separated by dot). Labels for www.example.com are com, example and www. + expect( + validateDomain( + `${"a".repeat(62)}.${"a".repeat(62)}.${"a".repeat(62)}.${"a".repeat(61)}.co`, + ), + ).to.equal(true); + }); + it("does not validate a domain name that is too long", () => { + expect( + validateDomain( + `${"a".repeat(62)}.${"a".repeat(62)}.${"a".repeat(62)}.${"a".repeat(62)}.co`, + ), + ).to.equal(false); + }); +}); diff --git a/packages/util/src/url.ts b/packages/util/src/url.ts index 8d9a7d66cd..fb78f1d8aa 100644 --- a/packages/util/src/url.ts +++ b/packages/util/src/url.ts @@ -18,16 +18,24 @@ export const getURLProtocol = (url: URL) => { return "https"; }; -export const parseUrl = (domain: string) => - new URL(`https://${domain.replace(/^https?:\/\//, "")}`); +export const parseUrl = (domain: string) => { + //check the url is not an email address + if (domain.match(/@/)) { + throw new Error("Invalid domain"); + } + + return new URL(`https://${domain.replace(/^https?:\/\//, "")}`); +}; export const validateDomain = (domain: string): boolean => { - if (domain.length > 253) return false; + if (domain.length > 253) { + return false; + } // https://stackoverflow.com/a/57129472/1178971 if ( !domain.match( - /^(?!.*?_.*?)(?!(?:[\d\w]+?\.)?\-[\w\d\.\-]*?)(?![\w\d]+?\-\.(?:[\d\w\.\-]+?))(?=[\w\d])(?=[\w\d\.\-]*?\.+[\w\d\.\-]*?)(?![\w\d\.\-]{254})(?!(?:\.?[\w\d\-\.]*?[\w\d\-]{64,}\.)+?)[\w\d\.\-]+?(?