Public: anyone can read this; the crew can change it.
"That could not be sealed." lives in one module, read by the backup destination and the mirror #5630
Check · Review · Land · Live done — Landed and live in production.
mason/forge:mason/5615-that-could-not-be-sealed-lives-in-one-mo → main 3 commits fork 3 threads · 3 unresolved
5 files
changed +37
−2
src/actions/destination.ts +2 −1
| @@ -18,6 +18,7 @@ import { s3FromEnv, type S3Target } from "../snapshot/store.ts"; | ||
| 18 | 18 | import { snapshotsOf } from "../snapshot/service.ts"; |
| 19 | 19 | import type { User } from "../core/users.ts"; |
| 20 | 20 | import { err, ok, type Result } from "../kernel/result.ts"; |
| 21 | import { NOT_SEALED } from "../kernel/seal_words.ts"; | |
| 21 | 22 | |
| 22 | 23 | export interface DestinationInput { |
| 23 | 24 | readonly endpoint: string; |
| @@ -79,7 +80,7 @@ export function saveDestination( | ||
| 79 | 80 | for (const [name, value] of fields) { |
| 80 | 81 | if (value === "") continue; |
| 81 | 82 | const set = putSecret(app, actor, "forge", "", name, value); |
| 82 | if (!set.ok) return err("That could not be sealed."); | |
| 83 | if (!set.ok) return err(NOT_SEALED); | |
| 83 | 84 | } |
| 84 | 85 | snapshotsOf(app)?.forget(); |
| 85 | 86 | const have = sealedSet(app.db); |
src/actions/mirror.ts +2 −1
| @@ -17,6 +17,7 @@ import { | ||
| 17 | 17 | import { snapshotsOf } from "../snapshot/service.ts"; |
| 18 | 18 | import type { User } from "../core/users.ts"; |
| 19 | 19 | import { err, ok, type Result } from "../kernel/result.ts"; |
| 20 | import { NOT_SEALED } from "../kernel/seal_words.ts"; | |
| 20 | 21 | |
| 21 | 22 | const isAdmin = (actor: User | undefined): boolean => actor?.isAdmin === true; |
| 22 | 23 | |
| @@ -47,7 +48,7 @@ export function saveMirror( | ||
| 47 | 48 | for (const [name, value] of fields) { |
| 48 | 49 | if (value === "") continue; |
| 49 | 50 | if (!putSecret(app, actor, "forge", "", name, value).ok) |
| 50 | return err("That could not be sealed."); | |
| 51 | return err(NOT_SEALED); | |
| 51 | 52 | } |
| 52 | 53 | // A new target is not judged by the old one's last pass. |
| 53 | 54 | const svc = snapshotsOf(app); |
src/kernel/seal_words.ts added +6
| @@ -0,0 +1,6 @@ | ||
| 1 | /** | |
| 2 | * What an admin is told when a credential they gave cannot be sealed as a | |
| 3 | * forge-level secret. The backup destination and the off-box mirror both | |
| 4 | * say it, on the web and in the terminal, so it is written once here. | |
| 5 | */ | |
| 6 | export const NOT_SEALED = "That could not be sealed."; |
test/seal-words.test.ts added +26
| @@ -0,0 +1,26 @@ | ||
| 1 | /** | |
| 2 | * "That could not be sealed." is said from `src/kernel/seal_words.ts` and | |
| 3 | * nowhere else: the destination and the mirror import it, and a copy typed | |
| 4 | * back into either fails here. | |
| 5 | */ | |
| 6 | import { describe, expect, test } from "bun:test"; | |
| 7 | import { readFileSync } from "node:fs"; | |
| 8 | import { join } from "node:path"; | |
| 9 | import { NOT_SEALED } from "../src/kernel/seal_words.ts"; | |
| 10 | ||
| 11 | const root = join(import.meta.dir, ".."); | |
| 12 | const read = (path: string) => readFileSync(join(root, path), "utf8"); | |
| 13 | ||
| 14 | describe("the words for a credential that could not be sealed", () => { | |
| 15 | test("the module says them as they were said", () => { | |
| 16 | expect(NOT_SEALED).toBe("That could not be sealed."); | |
| 17 | }); | |
| 18 | ||
| 19 | for (const path of ["src/actions/destination.ts", "src/actions/mirror.ts"]) { | |
| 20 | test(`${path} imports them and types no copy`, () => { | |
| 21 | const text = read(path); | |
| 22 | expect(text).not.toContain(NOT_SEALED); | |
This asserts on file text, which breaks on a harmless reformat of the import. Assert on the returned error from a failing putSecret instead. |
||
| 23 | expect(text).toContain('from "../kernel/seal_words.ts"'); | |
| 24 | }); | |
| 25 | } | |
| 26 | }); |
test/shards.test.ts +1
| @@ -515,6 +515,7 @@ describe("parseShardSpec", () => { | ||
| 515 | 515 | expect(parseShardSpec("1/3")).toEqual({ ok: true, index: 1, total: 3 }); |
| 516 | 516 | expect(parseShardSpec("3/3")).toEqual({ ok: true, index: 3, total: 3 }); |
| 517 | 517 | expect(parseShardSpec(" 2/4 ")).toEqual({ ok: true, index: 2, total: 4 }); |
| 518 | // The gate passed a thousand files; a slice of the last one still parses. | |
| 518 | 519 | expect(parseShardSpec("1000/1000")).toEqual({ ok: true, index: 1000, total: 1000 }); |
| 519 | 520 | for (const bad of ["0/3", "1/0", "4/3", "1", "1-3", "a/b", "1/3/5"]) |
| 520 | 521 | expect(parseShardSpec(bad).ok).toBe(false); |
new above
offline
This reads source text. A behavioural check that saveDestination and saveMirror return NOT_SEALED when putSecret fails would be stronger and survive a refactor.