// Proof: the /plumbing read API only ever hands out an artifact to a caller who // may see the structure it BELONGS TO — including via the id-only endpoints the // live editor uses, and even when a private db is aliased into a public one. // // It mounts the REAL plumbing.js router on a throwaway express app (temp db), // with a tiny middleware that fakes a logged-in session from an ?as= query, and // makes real HTTP requests. So the assertions exercise the shipped access logic. const fs = require("fs"); const os = require("os"); const path = require("path"); const express = require("express"); const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "bliss-plumbing-")); fs.mkdirSync(path.join(tmp, "dbs")); process.chdir(tmp); const PROJECT = "/home/happy/code/bliss"; const model = require(path.join(PROJECT, "db.js")); model.applyMigrations(); // ---- scenario ------------------------------------------------------------ const alice = model.createUser("alice", "x"); // member of the private structure const bob = model.createUser("bob", "x"); // outsider // PRIVATE structure owned by alice: its own route, template, and db. const priv = model.createStructure("private-vault", alice); const privRoute = model.createRoute("GET", "/secret", priv, "handler(){}"); const privTemplate = model.createTemplate(priv, "secret_tpl", "top secret", ""); const secretsDbId = model.createDb(priv, "secrets"); model.setStructurePrivacy(priv, true, alice); // PUBLIC structure owned by bob that ALIASES alice's private db under "secrets". const pub = model.createStructure("public-front", bob); model.attachDb(pub, secretsDbId, "secrets"); // ---- app: real plumbing router, faked session from ?as= ------------------ const app = express(); app.use((req, _res, next) => { const as = req.query.as; req.session = { userId: as === "alice" ? alice : as === "bob" ? bob : null }; next(); }); app.use("/plumbing", require(path.join(PROJECT, "plumbing.js"))); const server = app.listen(0); const port = server.address().port; async function get(url) { const res = await fetch(`http://127.0.0.1:${port}${url}`); return res.status; } function expect(label, actual, wanted) { const ok = actual === wanted; console.log(` ${ok ? "PASS" : "FAIL"} | ${label} (got ${actual}, want ${wanted})`); return ok; } (async () => { const results = []; console.log("\nid-only endpoints (what the live editor calls):"); results.push(expect("alice reads her private route ", await get(`/plumbing/routes/${privRoute}?as=alice`), 200)); results.push(expect("bob reads alice's private route ", await get(`/plumbing/routes/${privRoute}?as=bob`), 404)); results.push(expect("anon reads alice's private route ", await get(`/plumbing/routes/${privRoute}`), 404)); results.push(expect("alice reads her private template ", await get(`/plumbing/templates/${privTemplate}?as=alice`), 200)); results.push(expect("bob reads alice's private template", await get(`/plumbing/templates/${privTemplate}?as=bob`), 404)); console.log("\nstructure-scoped endpoints reject id-laundering:"); // bob CAN see his public structure, but the route id belongs to the private one. results.push(expect("bob: pub structure + private routeId", await get(`/plumbing/structures/${pub}/routes/${privRoute}?as=bob`), 404)); console.log("\naliased private db is not leaked through a public structure:"); results.push(expect("bob reads aliased private db ", await get(`/plumbing/structures/${pub}/dbs/${secretsDbId}?as=bob`), 404)); results.push(expect("alice reads that db via her structure", await get(`/plumbing/structures/${priv}/dbs/${secretsDbId}?as=alice`), 200)); const pass = results.every(Boolean); console.log(`\n${pass ? "PROVEN" : "FAILED"}: plumbing gates every artifact against its own structure's access rules.`); server.close(); fs.rmSync(tmp, { recursive: true, force: true }); process.exit(pass ? 0 : 1); })();