import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { DatabaseSync } from "node:sqlite"; import vm from "node:vm"; import worker from "../dist/server/index.js"; const sqlite = new DatabaseSync(":memory:"); sqlite.exec("PRAGMA foreign_keys = ON"); sqlite.exec(readFileSync(new URL("../drizzle/0000_lifeos_cloud_state.sql", import.meta.url), "utf8")); sqlite.exec(readFileSync(new URL("../drizzle/0001_lifeos_records.sql", import.meta.url), "utf8")); sqlite.exec(readFileSync(new URL("../drizzle/0002_lifeos_db_admin.sql", import.meta.url), "utf8")); const db = { prepare(sql) { return { bind(...args) { const statement = sqlite.prepare(sql); return { first: async () => statement.get(...args) ?? null, all: async () => ({ results: statement.all(...args) }), run: async () => ({ meta: { changes: statement.run(...args).changes } }) }; } }; }, async batch(statements) { sqlite.exec("BEGIN"); try { const result = []; for (const statement of statements) result.push(await statement.run()); sqlite.exec("COMMIT"); return result; } catch (error) { sqlite.exec("ROLLBACK"); throw error; } } }; const headers = { "oai-authenticated-user-id": "alice" }; async function call(path, method = "GET", data, as = headers) { const response = await worker.fetch(new Request("https://life-os.test" + path, { method, headers: { ...as, "content-type": "application/json" }, body: data === undefined ? undefined : JSON.stringify(data) }), { DB: db, LIFEOS_DB_ADMIN_PASSWORD: "local test password with 28 chars" }); return { status: response.status, body: await response.json() }; } const legacy = { profile: { name: "Alice" }, settings: { theme: "dark" }, memories: [{ id: "m1", date: "2026-09-28", title: "Lab", tags: ["school", "lab"], text: "Notes" }], museum: [{ id: "f1", memoryId: "m1", preservedAt: "2026-09-28" }], system: { schemaVersion: 2, tasksBoard: { goals: [{ id: "g1", title: "Study", targetDate: "2026-12-12" }], tasks: [{ id: "t1", goalId: "g1", title: "Review", done: false }] } } }; sqlite.prepare("INSERT INTO lifeos_states VALUES (?, ?, ?, ?, ?, ?, ?)").run( "alice", JSON.stringify(legacy.profile), JSON.stringify(legacy.memories), JSON.stringify(legacy.museum), JSON.stringify(legacy.settings), JSON.stringify(legacy.system), "2026-09-28" ); let result = await call("/api/lifeos-state"); assert.equal(result.status, 200); assert.deepEqual(result.body.state.memories, legacy.memories); assert.deepEqual(result.body.state.system.tasksBoard, legacy.system.tasksBoard); assert.deepEqual(result.body.state.museum, legacy.museum); assert.equal(result.body.versions.memories.m1, 1); assert.deepEqual(sqlite.prepare("SELECT tag FROM lifeos_memory_tags ORDER BY tag").all().map(row => row.tag), ["lab", "school"]); assert.equal(sqlite.prepare("SELECT COUNT(*) AS count FROM lifeos_states").get().count, 1, "legacy backup remains intact"); result = await call("/api/lifeos-sync", "POST", { kind: "memories", id: "m1", baseVersion: 1, value: { ...legacy.memories[0], tags: ["new"] } }); assert.equal(result.body.version, 2); assert.deepEqual(sqlite.prepare("SELECT tag FROM lifeos_memory_tags").all().map(row => row.tag), ["new"]); result = await call("/api/lifeos-sync", "POST", { kind: "memories", id: "m1", baseVersion: 1, value: legacy.memories[0] }); assert.equal(result.status, 409, "stale client cannot overwrite a record"); result = await call("/api/lifeos-sync", "POST", { kind: "tasks", id: "t2", baseVersion: 0, value: { id: "t2", title: "New task", done: false } }); assert.equal(result.status, 200); result = await call("/api/lifeos-sync", "POST", { kind: "memories", id: "m1", baseVersion: 2, value: null }); assert.equal(result.body.version, 3); assert.equal(sqlite.prepare("SELECT COUNT(*) AS count FROM lifeos_memory_tags").get().count, 0); assert.equal((await call("/api/lifeos-state")).body.state.memories.length, 0); assert.equal((await call("/api/lifeos-state", "GET", undefined, { "oai-authenticated-user-id": "bob" })).body.state, null); assert.equal((await call("/api/lifeos-state", "PUT", { state: legacy })).status, 426, "old whole-document writes are rejected"); result = await call("/api/lifeos-initialize", "POST", { state: legacy }, { "oai-authenticated-user-id": "bob" }); assert.equal(result.status, 200); assert.equal(result.body.state.system.tasksBoard.tasks.length, 1); assert.equal((await call("/api/lifeos-initialize", "POST", { state: legacy }, { "oai-authenticated-user-id": "bob" })).status, 409); const addons = readFileSync(new URL("../public/addons.js", import.meta.url), "utf8"); const syncCode = addons.slice(addons.indexOf(" const CLOUD_KEYS ="), addons.indexOf(" const originalSetItem =")); assert.ok(syncCode.includes("function changes(")); const values = new Map(); const storage = { getItem: key => values.get(key) ?? null, setItem: (key, value) => values.set(key, String(value)) }; const client = vm.createContext({ localStorage: storage, window: {}, fetch: async (path, options = {}) => worker.fetch( new Request("https://life-os.test" + path, { ...options, headers: { ...options.headers, ...headers } }), { DB: db }), clearTimeout, setTimeout, confirm: () => false, t: key => key, toast: () => {}, document: { createElement() {}, body: { append() {} } } }); vm.runInContext(syncCode + "\nwindow.CloudTest = { ready(state, revisions) { baseline = clone(state); versions = revisions; cloudReady = true; }, changes, snapshot: cloudSnapshot, sync: uploadCloudState };", client); const snapshot = (await call("/api/lifeos-state")).body; for (const [kind, key] of Object.entries({ profile: "lifeos_profile", memories: "lifeos_memories", museum: "lifeos_museum", settings: "lifeos_settings", system: "lifeos_system" })) storage.setItem(key, JSON.stringify(snapshot.state[kind])); client.window.CloudTest.ready(snapshot.state, snapshot.versions); const system = JSON.parse(storage.getItem("lifeos_system")); system.tasksBoard.tasks[0].done = true; storage.setItem("lifeos_system", JSON.stringify(system)); const pending = client.window.CloudTest.changes(snapshot.state, client.window.CloudTest.snapshot()); assert.deepEqual(Array.from(pending, item => item.kind), ["tasks"], "editing a task only writes one record"); await client.window.CloudTest.sync(); assert.equal((await call("/api/lifeos-state")).body.state.system.tasksBoard.tasks[0].done, true); assert.equal((await call("/api/db-admin/tables/tasks/rows")).status, 401); assert.equal((await call("/api/db-admin/login", "POST", { username: "lifeos-admin", password: "bad", acknowledged: true })).status, 401); const login = await call("/api/db-admin/login", "POST", { username: "lifeos-admin", password: "local test password with 28 chars", acknowledged: true }); assert.equal(login.status, 200); const auth = { ...headers, "x-lifeos-admin-session": login.body.token }; assert.equal((await call("/api/db-admin/tables/tasks/rows", "GET", undefined, { ...auth, origin: "https://evil.example" })).status, 403); let admin = await call("/api/db-admin/tables/tasks/rows", "GET", undefined, auth); assert.equal(admin.status, 200); assert.equal(admin.body.total, 2); assert.equal((await call("/api/db-admin/tables/tasks/rows", "GET", undefined, { ...auth, "oai-authenticated-user-id": "bob" })).status, 401, "admin session is tied to one user"); admin = await call("/api/db-admin/tables/tasks/rows/t3", "POST", { baseVersion: 0, value: { id: "t3", title: "From database" } }, auth); assert.equal(admin.body.version, 1); admin = await call("/api/db-admin/tables/tasks/rows/t3", "PATCH", { baseVersion: 1, value: { id: "t3", title: "Edited" } }, auth); assert.equal(admin.body.version, 2); assert.equal((await call("/api/db-admin/tables/tasks/rows/t3", "PATCH", { baseVersion: 1, value: { id: "t3", title: "Stale" } }, auth)).status, 409); assert.equal((await call("/api/db-admin/tables/tasks/rows/t3?version=2", "DELETE", undefined, auth)).status, 200); assert.equal((await call("/api/db-admin/logout", "POST", {}, auth)).status, 200); assert.equal((await call("/api/db-admin/tables/tasks/rows", "GET", undefined, auth)).status, 401); console.log("Life OS record migration, sync conflict, tags, and user isolation valid");