import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; import { spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; import test from "node:test"; import { closeLocalPostgresDataPool, createLocalPostgresDataClient } from "../src/lib/db/local-postgres-client-core.ts"; import { loadReportWorkerProfile } from "../src/lib/personal-report-worker-subject.ts"; import { CHART_SUBJECT_SELECT } from "../src/lib/subject-birth.ts"; import { startPostgresFixture, type PostgresFixture } from "./helpers/postgres-fixture.ts"; // BUG-1063: the report worker reads another person's archive through // service_role. Fictional rows only. const runner = fileURLToPath(new URL("../scripts/db-migrate.mjs", import.meta.url)); const docker = spawnSync("docker", ["version", "--format", "{{.Server.Version}}"], { stdio: "ignore" }).status === 0; const SERVICE_URL_ROLE = ["service_runtime", "service-runtime-test-password"] as const; function applyMigrations(fixture: PostgresFixture): void { const result = spawnSync(process.execPath, [runner], { encoding: "utf8", env: { ...process.env, SCHEMA_DATABASE_URL: fixture.connectionUrl("schema_owner", "schema-owner-test-password"), }, }); assert.equal(result.status, 0, result.stderr || result.stdout); } test("service_role can read another person's chart profile for a report", { skip: docker ? false : "docker unavailable", }, async () => { const fixture = startPostgresFixture(); const serviceUrl = fixture.connectionUrl(...SERVICE_URL_ROLE); try { applyMigrations(fixture); const owner = randomUUID(); const subjectId = randomUUID(); fixture.psql(`insert into identity.users (id, name, email, email_verified, email_verified_at) values ('${owner}', 'Fictional owner', '${owner}@example.invalid', true, now());`); fixture.psql(`insert into public.chart_profiles ( id, user_id, role, profile, updated_at, name, birth_date, reported_birth_time, birth_time_source, latitude, longitude, timezone_id, timezone_offset, birth_place_label, ayanamsa, birth_time_status ) values ( '${subjectId}', '${owner}', 'other', '{"name":"虚构乙"}'::jsonb, now(), '虚构乙', '1990-01-01', '08:00', 'family_exact', 22.3, 114.1, 'Asia/Shanghai', 8, '虚构港', 'lahiri', 'reported' );`); const admin = createLocalPostgresDataClient(serviceUrl, null, "service_role"); const probe = await admin .from("chart_profiles") .select(CHART_SUBJECT_SELECT) .eq("id", subjectId) .maybeSingle(); assert.equal(probe.error, null, probe.error?.message ?? "chart_profiles select failed"); const loaded = await loadReportWorkerProfile(admin, owner, subjectId) as { name?: string }; assert.equal(loaded.name, "虚构乙"); for (const column of CHART_SUBJECT_SELECT.split(",")) { assert.equal( fixture.psql(`select has_column_privilege('service_role', 'public.chart_profiles', '${column}', 'select')`), "t", column, ); } for (const privilege of ["insert", "update", "delete"]) { assert.equal( fixture.psql(`select has_table_privilege('service_role', 'public.chart_profiles', '${privilege}')`), "f", privilege, ); } assert.equal( fixture.psql("select has_table_privilege('authenticated', 'public.chart_profiles', 'select')"), "t", ); } finally { await closeLocalPostgresDataPool(serviceUrl); fixture.stop(); } });