mirror of
https://github.com/home-assistant/frontend.git
synced 2026-08-14 09:02:35 +01:00
Accept hostnames in HTTP config listen addresses and localize number validation
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { HOSTNAME_PATTERN } from "../../../src/common/string/is_hostname";
|
|
import { IP_ADDRESS_PATTERN } from "../../../src/common/string/is_ip_address";
|
|
|
|
const HOSTNAMES = [
|
|
"localhost",
|
|
"homeassistant.lan",
|
|
"home-assistant.local",
|
|
"3com.com",
|
|
"sub.domain.example.com",
|
|
"a".repeat(63),
|
|
];
|
|
|
|
const INVALID = [
|
|
"",
|
|
"foo bar",
|
|
"foo_bar",
|
|
"-foo.lan",
|
|
"foo-.lan",
|
|
"foo..lan",
|
|
"héllo.lan",
|
|
"host:8123",
|
|
"http://host",
|
|
"a".repeat(64),
|
|
// All-numeric final label: a mistyped IP address, not a hostname.
|
|
"123",
|
|
"foo.123",
|
|
"300.1.1.1",
|
|
"999.999.999.999",
|
|
];
|
|
|
|
// The browser anchors a `pattern` attribute as `^(?:…)$` and compiles it with
|
|
// the `v` flag. A pattern that fails to compile under `v` is silently ignored,
|
|
// disabling validation entirely, so compile it exactly the same way here.
|
|
const patternRegexp = (pattern: string): RegExp =>
|
|
new RegExp(`^(?:${pattern})$`, "v");
|
|
|
|
describe("HOSTNAME_PATTERN", () => {
|
|
it("compiles as an HTML pattern attribute", () => {
|
|
expect(() => patternRegexp(HOSTNAME_PATTERN)).not.toThrow();
|
|
});
|
|
it("accepts hostnames", () => {
|
|
const regexp = patternRegexp(HOSTNAME_PATTERN);
|
|
for (const value of HOSTNAMES) {
|
|
expect(regexp.test(value), value).toBe(true);
|
|
}
|
|
});
|
|
it("rejects malformed hostnames", () => {
|
|
const regexp = patternRegexp(HOSTNAME_PATTERN);
|
|
for (const value of INVALID) {
|
|
expect(regexp.test(value), value).toBe(false);
|
|
}
|
|
});
|
|
});
|
|
|
|
// How ha-config-http-form validates its listen addresses.
|
|
describe("IP address or hostname pattern", () => {
|
|
const composed = `${IP_ADDRESS_PATTERN}|${HOSTNAME_PATTERN}`;
|
|
|
|
it("compiles as an HTML pattern attribute", () => {
|
|
expect(() => patternRegexp(composed)).not.toThrow();
|
|
});
|
|
it("accepts hostnames and IP addresses", () => {
|
|
const regexp = patternRegexp(composed);
|
|
for (const value of [
|
|
...HOSTNAMES,
|
|
"192.168.1.10",
|
|
"0.0.0.0",
|
|
"255.255.255.255",
|
|
"fe80::1",
|
|
"::1",
|
|
]) {
|
|
expect(regexp.test(value), value).toBe(true);
|
|
}
|
|
});
|
|
it("rejects malformed addresses", () => {
|
|
const regexp = patternRegexp(composed);
|
|
for (const value of INVALID) {
|
|
expect(regexp.test(value), value).toBe(false);
|
|
}
|
|
});
|
|
});
|