diff --git a/notifiers/common/stringUtils.ts b/notifiers/common/stringUtils.ts index 22abc34..4f95444 100644 --- a/notifiers/common/stringUtils.ts +++ b/notifiers/common/stringUtils.ts @@ -3,6 +3,8 @@ import normalizeUrl from "npm:normalize-url@8.0.1"; import { URLData } from "./atomic.ts"; const QUOTES_UNWRAP_REGEX: RegExp = new RegExp(/^"(.*)"$/); +// domain:port/path (:port is optional) +const NON_PROTOCOL_DOMAIN_REGEX: RegExp = new RegExp(/^[a-zA-Z0-9-]+(:[0-9]+)?(\/[^\/].*)?$/); export const normalizeWebAddress = (val: string): URLData => { let cleanUserUrl = val.trim(); @@ -10,6 +12,12 @@ export const normalizeWebAddress = (val: string): URLData => { if (results !== undefined && results.groups && results.groups.length > 0) { cleanUserUrl = results.groups[0]; } + const nonProto = parseRegexSingle(NON_PROTOCOL_DOMAIN_REGEX, cleanUserUrl); + if(nonProto !== undefined) { + // url does not have protocol or TLD, need to add protocol so URL constructor doesn't try to use domain as protocol + // correct protocol should be determined by code below + cleanUserUrl = `http://${cleanUserUrl}`; + } let normal = normalizeUrl(cleanUserUrl, {removeTrailingSlash: true}); const u = new URL(normal); diff --git a/notifiers/tests/utils.test.ts b/notifiers/tests/utils.test.ts new file mode 100644 index 0000000..9a5df4a --- /dev/null +++ b/notifiers/tests/utils.test.ts @@ -0,0 +1,45 @@ +import { expect } from "jsr:@std/expect"; +import { normalizeWebAddress } from "../common/stringUtils.ts"; + +Deno.test({ + name: "Expects fully qualified address to be the same", + fn() { + expect(normalizeWebAddress('https://example.com').normal).toBe('https://example.com'); + expect(normalizeWebAddress('http://example.com').normal).toBe('http://example.com'); + }, +}); + +Deno.test({ + name: "Expects address without protocol to be http", + fn() { + const addr = normalizeWebAddress('example.com'); + expect(addr.normal).toBe('http://example.com'); + expect(addr.url.hostname).toBe('example.com'); + expect(addr.port).toBe(80); + }, + }); + +Deno.test({ +name: "Expects address without protocol but port 443 to be https", +fn() { + expect(normalizeWebAddress('example.com:443').url.protocol).toBe('https:'); +}, +}); + +Deno.test({ +name: "Expects hostname without extension to be detected", +fn() { + expect(normalizeWebAddress('example:8080').url.protocol).toBe('http:'); + expect(normalizeWebAddress('example:443').url.protocol).toBe('https:'); + + const web = normalizeWebAddress('example:8000/test'); + expect(web.url.protocol).toBe('http:'); + expect(web.url.port).toBe('8000'); + expect(web.url.pathname).toBe('/test'); + expect(web.url.hostname).toBe('example'); + + const hostonly = normalizeWebAddress('example'); + expect(hostonly.url.protocol).toBe('http:'); + expect(hostonly.port).toBe(80); +}, +}); \ No newline at end of file