import assert from "node:assert/strict"; import { readFile, readdir } from "node:fs/promises"; import { PGlite } from "../.data/sql-verification/node_modules/@electric-sql/pglite/dist/index.js"; const db = new PGlite(); const owner = "00000000-0000-4000-8000-000000000001", moderator = "00000000-0000-4000-8000-000000000002", player = "00000000-0000-4000-8000-000000000003"; const oldHash = "a".repeat(64), newHash = "b".repeat(64); try { await db.exec(`create role anon; create role authenticated; create role service_role bypassrls; create schema auth; create table auth.users(id uuid primary key); create function auth.uid() returns uuid language sql as $$ select null::uuid $$; create schema storage; create table storage.buckets(id text primary key,name text,public boolean,file_size_limit bigint);`); for (const file of (await readdir("supabase/migrations")) .filter((f) => f.endsWith(".sql")) .sort()) await db.exec(await readFile(`supabase/migrations/${file}`, "utf8")); // Supabase's default service_role table grants are not installed in PGlite. await db.exec( "grant select,insert,update,delete on all tables in schema public to service_role;", ); await db.query("insert into auth.users values($1),($2),($3)", [ owner, moderator, player, ]); await db.query( "insert into public.profiles(id,role) values($1,'admin'),($2,'moderator'),($3,'contributor')", [owner, moderator, player], ); const dataset = ( await db.query( `insert into public.datasets(owner_id,name,source,bounds,state,panorama_count) values($1,'Private map title','plugin','{}','published',7) returning id`, [owner], ) ).rows[0].id; const revision = ( await db.query( `insert into public.revisions(dataset_id,manifest,asset_root) values($1,'{}','private-root') returning id`, [dataset], ) ).rows[0].id; await db.query( `insert into public.game_sessions(revision_id,access_hash,difficulty,current_round,created_at) values($1,'test','easy',5,now()),($1,'test','hard',0,now()-interval '2 days')`, [revision], ); const rpc = async (sql, args = []) => (await db.query(sql, args)).rows[0].value; for (const role of ["anon", "authenticated"]) { await db.exec(`set role ${role}`); for (const sql of [ "select token_hash from public.prometheus_settings", `select public.prometheus_status('${owner}')`, `select public.configure_prometheus('${owner}','${oldHash}')`, `select public.read_prometheus_metrics('${oldHash}')`, ]) await assert.rejects(db.query(sql), /permission denied/); await db.exec("reset role"); } await db.exec("set role service_role"); for (const actor of [moderator, player, null]) { await assert.rejects( db.query("select public.prometheus_status($1)", [actor]), /Admin permission required/, ); await assert.rejects( db.query("select public.configure_prometheus($1,$2)", [actor, oldHash]), /Admin permission required/, ); } assert.equal( (await rpc("select public.prometheus_status($1) value", [owner])).enabled, false, ); assert.equal( await rpc("select public.read_prometheus_metrics($1) value", [oldHash]), null, ); await rpc("select public.configure_prometheus($1,$2) value", [ owner, oldHash, ]); const snapshot = await rpc( "select public.read_prometheus_metrics($1) value", [oldHash], ); assert.equal(snapshot.length, 43); assert.equal(snapshot.find((s) => s.metric === "minegeo_accounts").value, 3); assert.equal( snapshot.find( (s) => s.metric === "minegeo_maps" && s.labels.state === "published", ).value, 1, ); assert.equal( snapshot.find((s) => s.metric === "minegeo_published_panoramas").value, 7, ); assert.equal( snapshot.find((s) => s.metric === "minegeo_games_started_24h").value, 1, ); assert.equal( snapshot.find( (s) => s.metric === "minegeo_games" && s.labels.difficulty === "easy" && s.labels.status === "complete", ).value, 1, ); assert.equal( snapshot.find( (s) => s.metric === "minegeo_games" && s.labels.difficulty === "hard" && s.labels.status === "incomplete", ).value, 1, ); assert.ok(!JSON.stringify(snapshot).includes("Private map title")); assert.ok( snapshot.every( (s) => Object.keys(s).sort().join(",") === "labels,metric,value", ), ); assert.ok(!JSON.stringify(snapshot).includes(owner)); assert.ok( (await rpc("select public.prometheus_status($1) value", [owner])) .lastScrapedAt, ); // Cache is shared by scrapes rather than tied to a serverless process. await db.query( "update public.profiles set display_name='Private name' where id=$1", [player], ); assert.deepEqual( await rpc("select public.read_prometheus_metrics($1) value", [oldHash]), snapshot, ); await db.query("update public.datasets set state='unpublished' where id=$1", [ dataset, ]); assert.deepEqual( await rpc("select public.read_prometheus_metrics($1) value", [oldHash]), snapshot, ); await db.exec( "update public.prometheus_settings set snapshot_at=now()-interval '1 minute'", ); const refreshed = await rpc( "select public.read_prometheus_metrics($1) value", [oldHash], ); assert.equal( refreshed.find( (s) => s.metric === "minegeo_maps" && s.labels.state === "published", ).value, 0, ); await rpc("select public.configure_prometheus($1,$2) value", [ owner, newHash, ]); assert.equal( await rpc("select public.read_prometheus_metrics($1) value", [oldHash]), null, ); assert.ok( await rpc("select public.read_prometheus_metrics($1) value", [newHash]), ); await db.query("update public.profiles set role='contributor' where id=$1", [ owner, ]); assert.equal( await rpc("select public.read_prometheus_metrics($1) value", [newHash]), null, ); await db.query("update public.profiles set role='admin' where id=$1", [ owner, ]); await rpc("select public.configure_prometheus($1,null) value", [owner]); assert.equal( await rpc("select public.read_prometheus_metrics($1) value", [newHash]), null, ); console.log( "Prometheus SQL passed: Admin-only setup, private table/RPCs, disabled default, bounded aggregates, cache, rotation, disable, and issuer demotion.", ); } finally { await db.close(); }