import { describe, expect, it } from "@effect/vitest"; import { Effect } from "effect"; import { collectTables, createExecutor, type Executor } from "./executor"; import { createSqliteTestFumaDb, type SqliteTestFumaDb } from "./sqlite-test-db"; import { Subject, Tenant } from "./ids"; import { resetSubjectTouchCache, touchSubject } from "./subject-registry"; // The platform view: `executor.admin`, an OPT-IN read-only surface that reads // across every subject in the tenant. Written against the real SQLite bring-up // so the tenant-reach policy, the bigint `last_seen_at` round-trip, and the // field allowlist are all live. const TENANT = "t1"; const OTHER_TENANT = "t2"; const SUBJECT_A = "user_a"; const SUBJECT_B = "user_b"; /** Every column on `connection` that could resolve, or help resolve, a * credential. NONE of these may appear on an admin shape — enumerated so a * future column addition has to be argued with this list. */ const FORBIDDEN_CONNECTION_FIELDS = [ "item_ids", "itemIds", "refresh_item_id", "refreshItemId", "provider", "provider_state", "providerState", "oauth_token_url", "oauthTokenUrl", "template", "client_secret", "clientSecret", "secret", "token", ] as const; const withDb = (body: (db: SqliteTestFumaDb) => Effect.Effect): Effect.Effect => Effect.acquireUseRelease( Effect.promise(() => createSqliteTestFumaDb({ tables: collectTables() })), body, (db) => Effect.promise(() => db.close()), ); const insertConnection = ( db: SqliteTestFumaDb, row: { readonly rowId: string; readonly tenant: string; readonly owner: string; readonly subject: string; readonly integration: string; readonly name: string; readonly oauthScope?: string | null; }, ): Effect.Effect => Effect.promise(async () => { await db.client.execute({ sql: `INSERT INTO connection ( row_id, tenant, owner, subject, integration, name, template, provider, item_ids, refresh_item_id, oauth_scope, last_health, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, args: [ row.rowId, row.tenant, row.owner, row.subject, row.integration, row.name, "oauth2", "memory", // Deliberately secret-bearing: the assertions below prove these never // leave the storage layer. JSON.stringify({ token: `SECRET-item-${row.rowId}` }), `SECRET-refresh-${row.rowId}`, row.oauthScope ?? null, JSON.stringify({ status: "healthy", checkedAt: 1_700_000_000_000 }), Date.now(), Date.now(), ], }); }); /** Seed two users and an org connection under `t1`, plus an untouchable other * tenant. Subjects go in through `touchSubject` (the only legitimate writer); * connections go in raw, because no single bound executor could have written * another subject's rows. */ const seed = (db: SqliteTestFumaDb): Effect.Effect => Effect.gen(function* () { // `touchSubject` keeps a process-local memory of principals it already // filed, so a second seed against a FRESH database would be skipped as a // repeat sighting and leave the table empty. Each seed is a new world. resetSubjectTouchCache(); yield* touchSubject(db.db, { tenant: TENANT, externalId: SUBJECT_A }); yield* touchSubject(db.db, { tenant: TENANT, externalId: SUBJECT_B }); yield* touchSubject(db.db, { tenant: OTHER_TENANT, externalId: "user_elsewhere" }); yield* insertConnection(db, { rowId: "c-a1", tenant: TENANT, owner: "user", subject: SUBJECT_A, integration: "github", name: "personal", oauthScope: "repo read:user", }); yield* insertConnection(db, { rowId: "c-a2", tenant: TENANT, owner: "user", subject: SUBJECT_A, integration: "linear", name: "work", }); yield* insertConnection(db, { rowId: "c-b1", tenant: TENANT, owner: "user", subject: SUBJECT_B, integration: "github", name: "b-personal", oauthScope: "repo", }); yield* insertConnection(db, { rowId: "c-org", tenant: TENANT, owner: "org", subject: "", integration: "stripe", name: "shared", }); yield* insertConnection(db, { rowId: "c-other", tenant: OTHER_TENANT, owner: "user", subject: SUBJECT_A, integration: "github", name: "other-tenant", }); }); const makePlatformExecutor = ( db: SqliteTestFumaDb, options?: { readonly platformView?: boolean; readonly subject?: string | null }, ): Effect.Effect => createExecutor({ tenant: Tenant.make(TENANT), ...(options?.subject === null ? {} : { subject: Subject.make(options?.subject ?? SUBJECT_A) }), db: db.db, onElicitation: "accept-all", ...(options?.platformView === false ? {} : { platformView: true }), }).pipe(Effect.orDie); const requireAdmin = (executor: Executor) => { const admin = executor.admin; if (!admin) return Effect.die("expected the platform view to be enabled"); return Effect.succeed(admin); }; describe("platform view — admin.listSubjects", () => { it.effect("lists every subject in the tenant and no other tenant's", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const subjects = yield* admin.listSubjects(); // `user_elsewhere` lives under t2 — invisible at any reach. expect(subjects.map((entry) => entry.externalId).sort()).toEqual([SUBJECT_A, SUBJECT_B]); }), ), ); it.effect("returns created_at and the bigint last_seen_at through the ORM", () => withDb((db) => Effect.gen(function* () { const before = Date.now(); yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const subjects = yield* admin.listSubjects(); const entry = subjects.find((row) => row.externalId === SUBJECT_A); expect(entry?.createdAt).toBeInstanceOf(Date); // A raw SQL read would hand back an unusable blob here. expect(typeof entry?.lastSeenAt).toBe("number"); expect(entry?.lastSeenAt ?? 0).toBeGreaterThanOrEqual(before); expect(entry?.status).toBeNull(); }), ), ); it.effect("pages with a stable order", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const all = yield* admin.listSubjects(); const first = yield* admin.listSubjects({ limit: 1 }); const second = yield* admin.listSubjects({ limit: 1, offset: 1 }); expect(all).toHaveLength(2); expect(first.map((entry) => entry.externalId)).toEqual([all[0]?.externalId]); expect(second.map((entry) => entry.externalId)).toEqual([all[1]?.externalId]); }), ), ); }); describe("platform view — admin.listSubjectConnections", () => { it.effect("lists another subject's connections across the tenant", () => withDb((db) => Effect.gen(function* () { yield* seed(db); // Bound to A; reading B is exactly what the product view cannot do. const executor = yield* makePlatformExecutor(db, { subject: SUBJECT_A }); const admin = yield* requireAdmin(executor); const connections = yield* admin.listSubjectConnections(SUBJECT_B); expect(connections.map((entry) => entry.name)).toEqual(["b-personal"]); expect(connections[0]?.integration).toBe("github"); expect(connections[0]?.owner).toBe("user"); expect(connections[0]?.subject).toBe(SUBJECT_B); expect(connections[0]?.oauthScope).toBe("repo"); expect(connections[0]?.lastHealth?.status).toBe("healthy"); }), ), ); it.effect("does not attribute org-owned connections to a user", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const forA = yield* admin.listSubjectConnections(SUBJECT_A); // The org's `stripe/shared` belongs to the tenant, not to A. expect(forA.map((entry) => entry.integration).sort()).toEqual(["github", "linear"]); expect(forA.every((entry) => entry.owner === "user")).toBe(true); }), ), ); it.effect("never returns credential-bearing fields", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const connections = yield* admin.listSubjectConnections(SUBJECT_A); expect(connections.length).toBeGreaterThan(0); for (const connection of connections) { const keys = Object.keys(connection); for (const forbidden of FORBIDDEN_CONNECTION_FIELDS) { expect(keys).not.toContain(forbidden); } // Belt and braces: no seeded secret value appears anywhere in the // serialized shape, whatever it is keyed under. expect(JSON.stringify(connection)).not.toContain("SECRET-"); } }), ), ); }); describe("platform view — admin.listSubjectsWithConnections", () => { it.effect("joins each subject to its own connections", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const rows = yield* admin.listSubjectsWithConnections(); const byId = new Map(rows.map((row) => [row.externalId, row])); expect(rows.map((row) => row.externalId).sort()).toEqual([SUBJECT_A, SUBJECT_B]); expect( byId .get(SUBJECT_A) ?.connections.map((c) => c.name) .sort(), ).toEqual(["personal", "work"]); expect(byId.get(SUBJECT_B)?.connections.map((c) => c.name)).toEqual(["b-personal"]); }), ), ); it.effect("never returns credential-bearing fields", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db); const admin = yield* requireAdmin(executor); const rows = yield* admin.listSubjectsWithConnections(); for (const row of rows) { for (const connection of row.connections) { const keys = Object.keys(connection); for (const forbidden of FORBIDDEN_CONNECTION_FIELDS) { expect(keys).not.toContain(forbidden); } } } expect(JSON.stringify(rows)).not.toContain("SECRET-"); }), ), ); it.effect("works for a pure-org executor with no bound subject", () => withDb((db) => Effect.gen(function* () { yield* seed(db); // The shape an org-level API key produces: platform view on, no // subject bound at all. const executor = yield* makePlatformExecutor(db, { subject: null }); const admin = yield* requireAdmin(executor); const rows = yield* admin.listSubjectsWithConnections(); expect(rows.map((row) => row.externalId).sort()).toEqual([SUBJECT_A, SUBJECT_B]); expect(rows.flatMap((row) => row.connections)).toHaveLength(3); }), ), ); }); describe("platform view — default off", () => { it.effect("an executor without the opt-in has no admin surface", () => withDb((db) => Effect.gen(function* () { yield* seed(db); const executor = yield* makePlatformExecutor(db, { platformView: false }); expect(executor.admin).toBeUndefined(); }), ), ); it.effect("the product view still reads only the bound subject when the opt-in is on", () => withDb((db) => Effect.gen(function* () { yield* seed(db); // Enabling the platform view must not widen ANY existing surface. const executor = yield* makePlatformExecutor(db, { subject: SUBJECT_A }); const connections = yield* executor.connections.list().pipe(Effect.orDie); expect(connections.map((entry) => entry.name).sort()).toEqual([ "personal", "shared", "work", ]); }), ), ); });