Auth.constants.ts46 lines · main
1// Regex from: https://stackoverflow.com/a/68002755/4807782
2// modified to accept numbers in the body of domain though
3// examples of matches:
4// "vercel.com"
5// "www.vercel.com"
6// "uptime-monitor-fe.vercel.app"
7// "https://uptime-monitor-fe.vercel.app/"
8
9// Supports wildcards, port numbers at the end, paths at the end and query params
10const baseUrlRegex =
11 /^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_*-]+(\.[a-zA-Z0-9_*-]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)+(?:\.[a-z]+)*(?::\d+)?(?![^<]*(?:<\/\w+>|\/?>))(.*)?\/?(.)*?$/gm
12
13// iOS deep linking scheme https://benoitpasquier.com/deep-linking-url-scheme-ios/
14const appRegex =
15 /^[a-z0-9-]+([.][a-z0-9]+)*:\/(\/[-a-z0-9._~!$&'()*+,;=:@%]+)+(?:\.[a-z]+)*(?::\d+)?(?![^<]*(?:<\/\w+>|\/?>))(.*)?\/?(.)*?$/i
16
17// Regex from https://stackoverflow.com/a/18696953/4807782
18const localhostRegex = /^(?:^|\s)((https?:\/\/)?(?:localhost|[\w-]+(?:\.[\w-]+)+)(:\d+)?(\/\S*)?)/i
19
20// "chrome-extension://<extension-id>"
21const chromeExtensionRegex = /chrome-extension:\/\/([a-zA-Z]*)/gm
22
23// New regex for custom scheme URLs
24const customSchemeRegex = /^([a-zA-Z][a-zA-Z0-9+.-]*):(?:\/{1,3})?([a-zA-Z0-9_.-]*)$/
25
26// Exclude simple domain names without protocol
27const excludeSimpleDomainRegex = /^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$/
28
29// combine the above regexes, with optional exclusion of options
30// usage: urlRegex() or urlRegex({ excludeSimpleDomains: false })
31export function urlRegex(
32 options: { excludeSimpleDomains?: boolean } = { excludeSimpleDomains: true }
33): RegExp {
34 const { excludeSimpleDomains } = options
35 const excludeSimpleDomainPart = excludeSimpleDomains
36 ? `(?!${excludeSimpleDomainRegex.source})`
37 : ''
38
39 return new RegExp(
40 `${excludeSimpleDomainPart}((${baseUrlRegex.source})|(${localhostRegex.source})|(${appRegex.source})|(${chromeExtensionRegex.source})|(${customSchemeRegex.source}))`,
41 'i'
42 )
43}
44
45// Use a const string to represent no chars option. Represented as empty string on the backend side.
46export const NO_REQUIRED_CHARACTERS = 'NO_REQUIRED_CHARS'