From 4ff337b2c40413019373e02302a83c2fe0bbea06 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sat, 25 Jun 2022 19:43:07 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Adds=20helper=20function=20to=20det?= =?UTF-8?q?ermine=20address=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/address-type-checker.ts | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/utils/address-type-checker.ts diff --git a/src/utils/address-type-checker.ts b/src/utils/address-type-checker.ts new file mode 100644 index 0000000..7e3fcc3 --- /dev/null +++ b/src/utils/address-type-checker.ts @@ -0,0 +1,60 @@ +/** + * Helper functions to determine if a string is a valid web address, + * and what type of address it is: URL, IPv4, IPv6 or none of those. + */ + +export type AddressType = 'ipV4' | 'ipV6' | 'url' | 'err' | 'empt'; + +/* Checks if a given string looks like a URL */ +const isUrl = (value: string):boolean => { + const urlRegex= new RegExp('' + + /(?:(?:(https?|ftp):)?\/\/)/.source + + /(?:([^:\n\r]+):([^@\n\r]+)@)?/.source + + /(?:(?:www\.)?([^/\n\r]+))/.source + + /(\/[^?\n\r]+)?/.source + + /(\?[^#\n\r]*)?/.source + + /(#?[^\n\r]*)?/.source + ); + return urlRegex.test(value); +}; + +/* Checks if a given string looks like an IP Version 4 Address */ +const isIpV4 = (value: string): boolean => { + const ipPart = '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'; + const ipV4Regex = new RegExp(`^${ipPart}.${ipPart}.${ipPart}.${ipPart}$`); + return ipV4Regex.test(value); +}; + +/* Checks if a given string looks like an IP Version 6 Address */ +const isIPv6 = (value: string): boolean => { + const components = value.split(':'); + + if ((components.length < 2 || components.length > 8) || + ((components[0] !== '' || components[1] !== '') + && !components[0].match(/^[\da-f]{1,4}/i)) + ) return false; + + let numberOfZeroCompressions = 0; + for (let i = 1; i < components.length; ++i) { + if (components[i] === '') { + ++numberOfZeroCompressions; + if (numberOfZeroCompressions > 1) return false; + continue; + } + if (!components[i].match(/^[\da-f]{1,4}/i)) return false; + } + return true; +}; + +const isShort = (value: string): boolean => { + return (!value || value.length <=3); +}; + +/* Returns the address type for a given address */ +export const determineAddressType = (address: string): AddressType => { + if (isShort(address)) return 'empt'; + if (isUrl(address)) return 'url'; + if (isIpV4(address)) return 'ipV4'; + if (isIPv6(address)) return 'ipV6'; + return 'err'; +};