Add browser-based board CLI auth flow

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta 2026-03-23 07:48:03 -05:00
parent 1376fc8f44
commit 37c2c4acc4
31 changed files with 13299 additions and 19 deletions

View file

@ -3,7 +3,10 @@ import express from "express";
import request from "supertest";
import { boardMutationGuard } from "../middleware/board-mutation-guard.js";
function createApp(actorType: "board" | "agent", boardSource: "session" | "local_implicit" = "session") {
function createApp(
actorType: "board" | "agent",
boardSource: "session" | "local_implicit" | "board_key" = "session",
) {
const app = express();
app.use(express.json());
app.use((req, _res, next) => {
@ -29,11 +32,26 @@ describe("boardMutationGuard", () => {
expect(res.status).toBe(204);
});
it("blocks board mutations without trusted origin", async () => {
const app = createApp("board");
const res = await request(app).post("/mutate").send({ ok: true });
expect(res.status).toBe(403);
expect(res.body).toEqual({ error: "Board mutation requires trusted browser origin" });
it("blocks board mutations without trusted origin", () => {
const middleware = boardMutationGuard();
const req = {
method: "POST",
actor: { type: "board", userId: "board", source: "session" },
header: () => undefined,
} as any;
const res = {
status: vi.fn().mockReturnThis(),
json: vi.fn(),
} as any;
const next = vi.fn();
middleware(req, res, next);
expect(next).not.toHaveBeenCalled();
expect(res.status).toHaveBeenCalledWith(403);
expect(res.json).toHaveBeenCalledWith({
error: "Board mutation requires trusted browser origin",
});
});
it("allows local implicit board mutations without origin", async () => {
@ -42,6 +60,12 @@ describe("boardMutationGuard", () => {
expect(res.status).toBe(204);
});
it("allows board bearer-key mutations without origin", async () => {
const app = createApp("board", "board_key");
const res = await request(app).post("/mutate").send({ ok: true });
expect(res.status).toBe(204);
});
it("allows board mutations from trusted origin", async () => {
const app = createApp("board");
const res = await request(app)