Updates
This commit is contained in:
@@ -62,6 +62,8 @@ export function setCookies(response: Response, cookies: CookieOptions[]): void {
|
||||
if (maxAge !== undefined) header += `; Max-Age=${maxAge}`;
|
||||
if (domain) header += `; Domain=${domain}`;
|
||||
|
||||
console.log("header", header);
|
||||
|
||||
response.headers.append("Set-Cookie", header);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import parsePortList from "./parse-port-list";
|
||||
|
||||
describe("parsePortList", () => {
|
||||
test("treats empty as any port", () => {
|
||||
expect(parsePortList({ ports: "" })).toEqual({
|
||||
success: true,
|
||||
ports: [],
|
||||
});
|
||||
expect(parsePortList({})).toEqual({
|
||||
success: true,
|
||||
ports: [],
|
||||
});
|
||||
});
|
||||
|
||||
test("parses singles, lists, and ranges", () => {
|
||||
expect(parsePortList({ ports: "443" }).ports).toEqual(["443"]);
|
||||
expect(parsePortList({ ports: "80, 443" }).ports).toEqual([
|
||||
"80",
|
||||
"443",
|
||||
]);
|
||||
expect(parsePortList({ ports: "8000:8080" }).ports).toEqual([
|
||||
"8000:8080",
|
||||
]);
|
||||
});
|
||||
|
||||
test("rejects invalid ports", () => {
|
||||
expect(parsePortList({ ports: "0" }).success).toBe(false);
|
||||
expect(parsePortList({ ports: "65536" }).success).toBe(false);
|
||||
expect(parsePortList({ ports: "8080:8000" }).success).toBe(false);
|
||||
expect(parsePortList({ ports: "80-443" }).success).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,96 @@
|
||||
type Params = {
|
||||
ports?: string;
|
||||
};
|
||||
|
||||
export type ParsePortListResult = {
|
||||
success: boolean;
|
||||
msg?: string;
|
||||
ports: string[];
|
||||
};
|
||||
|
||||
function isValidPort({ value }: { value: string }) {
|
||||
if (!/^\d{1,5}$/.test(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const port = Number(value);
|
||||
|
||||
return port >= 1 && port <= 65535 && String(port) == value;
|
||||
}
|
||||
|
||||
export default function parsePortList({
|
||||
ports,
|
||||
}: Params): ParsePortListResult {
|
||||
if (!ports || !ports.trim()) {
|
||||
return {
|
||||
success: true,
|
||||
ports: [],
|
||||
};
|
||||
}
|
||||
|
||||
const tokens = ports
|
||||
.split(",")
|
||||
.map((token) => token.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
if (!tokens[0]) {
|
||||
return {
|
||||
success: true,
|
||||
ports: [],
|
||||
};
|
||||
}
|
||||
|
||||
const parsed: string[] = [];
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
|
||||
if (!token) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token.includes(":")) {
|
||||
const [start, end, extra] = token.split(":");
|
||||
|
||||
if (
|
||||
extra ||
|
||||
!start ||
|
||||
!end ||
|
||||
!isValidPort({ value: start }) ||
|
||||
!isValidPort({ value: end })
|
||||
) {
|
||||
return {
|
||||
success: false,
|
||||
msg: `Invalid port range "${token}"`,
|
||||
ports: [],
|
||||
};
|
||||
}
|
||||
|
||||
if (Number(start) > Number(end)) {
|
||||
return {
|
||||
success: false,
|
||||
msg: `Invalid port range "${token}"`,
|
||||
ports: [],
|
||||
};
|
||||
}
|
||||
|
||||
parsed.push(`${start}:${end}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isValidPort({ value: token })) {
|
||||
return {
|
||||
success: false,
|
||||
msg: `Invalid port "${token}"`,
|
||||
ports: [],
|
||||
};
|
||||
}
|
||||
|
||||
parsed.push(token);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
ports: parsed,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import validateIpv4Cidr from "./validate-ipv4-cidr";
|
||||
|
||||
describe("validateIpv4Cidr", () => {
|
||||
test("accepts a bare IPv4 address", () => {
|
||||
expect(validateIpv4Cidr({ value: "10.0.0.2" })).toBe(true);
|
||||
});
|
||||
|
||||
test("accepts CIDR notation", () => {
|
||||
expect(validateIpv4Cidr({ value: "10.0.0.0/24" })).toBe(true);
|
||||
expect(validateIpv4Cidr({ value: "0.0.0.0/0" })).toBe(true);
|
||||
expect(validateIpv4Cidr({ value: "192.168.1.1/32" })).toBe(true);
|
||||
});
|
||||
|
||||
test("rejects invalid values", () => {
|
||||
expect(validateIpv4Cidr({ value: "10.0.0.0/33" })).toBe(false);
|
||||
expect(validateIpv4Cidr({ value: "10.0.0.0/024" })).toBe(false);
|
||||
expect(validateIpv4Cidr({ value: "10.0.0.0/24/24" })).toBe(false);
|
||||
expect(validateIpv4Cidr({ value: "example.com" })).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import validateIpv4 from "./validate-ipv4";
|
||||
|
||||
type Params = {
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export default function validateIpv4Cidr({ value }: Params) {
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [ip, prefix, extra] = value.split("/");
|
||||
|
||||
if (extra) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validateIpv4({ ip })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prefix == undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!/^\d{1,2}$/.test(prefix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const prefix_value = Number(prefix);
|
||||
|
||||
return prefix_value >= 0 && prefix_value <= 32 && String(prefix_value) == prefix;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import validateIpv4 from "./validate-ipv4";
|
||||
|
||||
describe("validateIpv4", () => {
|
||||
test("accepts valid addresses", () => {
|
||||
expect(validateIpv4({ ip: "10.0.0.2" })).toBe(true);
|
||||
expect(validateIpv4({ ip: "0.0.0.0" })).toBe(true);
|
||||
expect(validateIpv4({ ip: "255.255.255.255" })).toBe(true);
|
||||
});
|
||||
|
||||
test("rejects invalid addresses", () => {
|
||||
expect(validateIpv4({ ip: "" })).toBe(false);
|
||||
expect(validateIpv4({})).toBe(false);
|
||||
expect(validateIpv4({ ip: "10.0.0" })).toBe(false);
|
||||
expect(validateIpv4({ ip: "10.0.0.256" })).toBe(false);
|
||||
expect(validateIpv4({ ip: "10.0.0.01" })).toBe(false);
|
||||
expect(validateIpv4({ ip: "10.0.0.2/32" })).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
type Params = {
|
||||
ip?: string;
|
||||
};
|
||||
|
||||
export default function validateIpv4({ ip }: Params) {
|
||||
if (!ip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parts = ip.split(".");
|
||||
|
||||
if (parts.length != 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i];
|
||||
|
||||
if (!part || !/^\d{1,3}$/.test(part)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const value = Number(part);
|
||||
|
||||
if (value < 0 || value > 255) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (String(value) != part) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user