config.test.ts

2.9 KB · raw

1import { expect, test } from "bun:test";2import { parseConfig } from "../src/server/config.ts";34const hash = "$argon2id$v=19$m=65536,t=2,p=1$c2FsdA$aGFzaA";5const s3 = `6domain = "kepr.example"7data_dir = "data"8admin_password_hash = "${hash}"910[bucket]11endpoint = "https://s3.fr-par.scw.cloud"12name = "koh"13region = "fr-par"14access_key_id = "SCWREAD"15secret_access_key = "secret"16`;1718test("parses the §19 keys with an S3 bucket", () => {19	expect(parseConfig(s3)).toEqual({20		domain: "kepr.example",21		dataDir: "data",22		adminPasswordHash: hash,23		bucket: {24			kind: "s3",25			endpoint: "https://s3.fr-par.scw.cloud",26			name: "koh",27			region: "fr-par",28			accessKeyId: "SCWREAD",29			secretAccessKey: "secret",30		},31	});32});33test("parses optional S3 write keys", () => {34	const config = parseConfig(35		`${s3}[bucket.write]\naccess_key_id = "SCWWRITE"\nsecret_access_key = "wsecret"\n`,36	);37	expect(config.bucket).toMatchObject({38		write: { accessKeyId: "SCWWRITE", secretAccessKey: "wsecret" },39	});40	expect(() =>41		parseConfig(`${s3}[bucket.write]\naccess_key_id = ""\nsecret_access_key = "x"\n`),42	).toThrow("access_key_id is required");43	expect(() =>44		parseConfig(45			`domain = "d"\ndata_dir = "data"\nadmin_password_hash = "${hash}"\n[bucket]\nfolder = "/tmp/b"\n[bucket.write]\naccess_key_id = "x"\nsecret_access_key = "y"\n`,46		),47	).toThrow("cannot be combined");48});4950test("parses a folder source", () => {51	const text = `domain = "d"\ndata_dir = "data"\nadmin_password_hash = "${hash}"\n[bucket]\nfolder = "/tmp/b"\n`;52	expect(parseConfig(text).bucket).toEqual({ kind: "folder", path: "/tmp/b" });53});5455test("fails loudly, naming the problem", () => {56	expect(() => parseConfig("domain = ")).toThrow("not valid TOML");57	expect(() => parseConfig(s3.replace('domain = "kepr.example"', ""))).toThrow(58		"domain is required",59	);60	expect(() => parseConfig(s3.replace(/\[bucket\][\s\S]*/, ""))).toThrow("[bucket] is missing");61	expect(() => parseConfig(s3.replace('region = "fr-par"', ""))).toThrow(62		"[bucket] region is required",63	);64	expect(() => parseConfig(s3.replace(hash, "plaintext"))).toThrow("Argon2id");65	expect(() => parseConfig(`${s3}folder = "/tmp/b"\n`)).toThrow("cannot be combined");66	expect(() => parseConfig(s3.replace("https://s3.fr-par.scw.cloud", "nope"))).toThrow(67		"must be a URL",68	);69});7071test("refuses a domain that is not a bare hostname, since install.sh embeds it as is", () => {72	for (const domain of ["kepr.example:8443", "kepr.example:65535", "localhost", "a-b.c1.example"]) {73		expect(parseConfig(s3.replace("kepr.example", domain)).domain).toBe(domain);74	}75	for (const domain of [76		"kepr.example/x",77		"https://kepr.example",78		"kepr.example$(id)",79		"kepr.example; rm x",80		"kepr.example\\nx",81		"-kepr.example",82		"kepr..example",83		"kepr.example:",84		"kepr.example:0",85		"kepr.example:65536",86		"kepr.example:99999",87		"[email protected]",88	]) {89		expect(() => parseConfig(s3.replace("kepr.example", domain))).toThrow("bare hostname");90	}91});