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("refuses a leftover [bucket.write]: the one [bucket] key reads and writes", () => {34 expect(() =>35 parseConfig(`${s3}[bucket.write]\naccess_key_id = "SCWWRITE"\nsecret_access_key = "w"\n`),36 ).toThrow("[bucket.write] is no longer used");37});3839test("parses a folder source", () => {40 const text = `domain = "d"\ndata_dir = "data"\nadmin_password_hash = "${hash}"\n[bucket]\nfolder = "/tmp/b"\n`;41 expect(parseConfig(text).bucket).toEqual({ kind: "folder", path: "/tmp/b" });42});4344test("fails loudly, naming the problem", () => {45 expect(() => parseConfig("domain = ")).toThrow("not valid TOML");46 expect(() => parseConfig(s3.replace('domain = "kepr.example"', ""))).toThrow(47 "domain is required",48 );49 expect(() => parseConfig(s3.replace(/\[bucket\][\s\S]*/, ""))).toThrow("[bucket] is missing");50 expect(() => parseConfig(s3.replace('region = "fr-par"', ""))).toThrow(51 "[bucket] region is required",52 );53 expect(() => parseConfig(s3.replace(hash, "plaintext"))).toThrow("Argon2id");54 expect(() => parseConfig(`${s3}folder = "/tmp/b"\n`)).toThrow("cannot be combined");55 expect(() => parseConfig(s3.replace("https://s3.fr-par.scw.cloud", "nope"))).toThrow(56 "must be a URL",57 );58});5960test("refuses a domain that is not a bare hostname, since install.sh embeds it as is", () => {61 for (const domain of ["kepr.example:8443", "kepr.example:65535", "localhost", "a-b.c1.example"]) {62 expect(parseConfig(s3.replace("kepr.example", domain)).domain).toBe(domain);63 }64 for (const domain of [65 "kepr.example/x",66 "https://kepr.example",67 "kepr.example$(id)",68 "kepr.example; rm x",69 "kepr.example\\nx",70 "-kepr.example",71 "kepr..example",72 "kepr.example:",73 "kepr.example:0",74 "kepr.example:65536",75 "kepr.example:99999",76 "[email protected]",77 ]) {78 expect(() => parseConfig(s3.replace("kepr.example", domain))).toThrow("bare hostname");79 }80});