Skip to content

Commit

Permalink
[AC-1609] Update domain name validation regex to support single lette…
Browse files Browse the repository at this point in the history
…r name (#9336)
  • Loading branch information
r-tome authored Jun 25, 2024
1 parent 1826403 commit 591f444
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { AbstractControl, ValidationErrors } from "@angular/forms";

import { domainNameValidator } from "./domain-name.validator";

describe("domainNameValidator", () => {
let validatorFn: (control: AbstractControl) => ValidationErrors | null;
const errorMessage = "Invalid domain name";

beforeEach(() => {
validatorFn = domainNameValidator(errorMessage);
});

const testCases = [
{ value: "e.com", expected: null },
{ value: "example.com", expected: null },
{ value: "sub.example.com", expected: null },
{ value: "sub.sub.example.com", expected: null },
{ value: "example.co.uk", expected: null },
{ value: "example", expected: { invalidDomainName: { message: errorMessage } } },
{ value: "-example.com", expected: { invalidDomainName: { message: errorMessage } } },
{ value: "example-.com", expected: { invalidDomainName: { message: errorMessage } } },
{ value: "example..com", expected: { invalidDomainName: { message: errorMessage } } },
{ value: "http://example.com", expected: { invalidDomainName: { message: errorMessage } } },
{ value: "www.example.com", expected: { invalidDomainName: { message: errorMessage } } },
{ value: "", expected: null },
{ value: "x".repeat(64) + ".com", expected: { invalidDomainName: { message: errorMessage } } },
];

describe("run test cases", () => {
testCases.forEach(({ value, expected }) => {
test(`should return ${JSON.stringify(expected)} for value "${value}"`, () => {
const control = { value } as AbstractControl;
expect(validatorFn(control)).toEqual(expected);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,22 @@ export function domainNameValidator(errorMessage: string): ValidatorFn {
// We do not want any prefixes per industry standards.

// Must support top-level domains and any number of subdomains.
// / # start regex
// ^ # start of string
// (?!(http(s)?:\/\/|www\.)) # negative lookahead to check if input doesn't match "http://", "https://" or "www."
// [a-zA-Z0-9] # first character must be a letter or a number
// [a-zA-Z0-9-]{0,61} # domain name can have 0 to 61 characters that are letters, numbers, or hyphens
// [a-zA-Z0-9] # domain name must end with a letter or a number
// (?: # start of non-capturing group (subdomain sections are optional)
// \. # subdomain must have a period
// [a-zA-Z0-9] # first character of subdomain must be a letter or a number
// [a-zA-Z0-9-]{0,61} # subdomain can have 0 to 61 characters that are letters, numbers, or hyphens
// [a-zA-Z0-9] # subdomain must end with a letter or a number
// )* # end of non-capturing group (subdomain sections are optional)
// \. # domain name must have a period
// [a-zA-Z]{2,} # domain name must have at least two letters (the domain extension)
// $/ # end of string
// / # start regex
// ^ # start of string
// (?!(http(s)?:\/\/|www\.)) # negative lookahead to check if input doesn't match "http://", "https://" or "www."
// ( # start of capturing group for the entire domain
// [a-zA-Z0-9] # first character of domain must be a letter or a number
// ( # start of optional group for subdomain or domain section
// [a-zA-Z0-9-]{0,61} # subdomain/domain section can have 0 to 61 characters that are letters, numbers, or hyphens
// [a-zA-Z0-9] # subdomain/domain section must end with a letter or a number
// )? # end of optional group for subdomain or domain section
// \. # subdomain/domain section must have a period
// )+ # end of capturing group for the entire domain, repeatable for subdomains
// [a-zA-Z]{2,} # domain name must have at least two letters (the domain extension)
// $/ # end of string

const validDomainNameRegex =
/^(?!(http(s)?:\/\/|www\.))[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])*\.[a-zA-Z]{2,}$/;
/^(?!(http(s)?:\/\/|www\.))([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;

const invalid = !validDomainNameRegex.test(control.value);

Expand Down

0 comments on commit 591f444

Please sign in to comment.