49 lines
2.1 KiB
JavaScript
49 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// Local-only convenience wrapper around scripts/provision-rls-roles.mjs.
|
|
//
|
|
// The app-wide RLS cutover migration GRANTs to hivegrid_app / hivegrid_worker /
|
|
// hivegrid_rls_definer, so those roles must exist before `prisma migrate deploy`
|
|
// touches an empty database — otherwise migration 20260713190000 fails halfway
|
|
// and leaves the database in a failed-migration state (P3009).
|
|
//
|
|
// The managed role passwords are external deployment secrets and therefore have
|
|
// no place in .env.example or the config catalog. Locally they are irrelevant:
|
|
// dev runs with RLS_RUNTIME_MODE=off and the app connects as the DATABASE_URL
|
|
// owner, never as one of these roles. So we mint throwaway random passwords here
|
|
// instead of committing any value. Staging and production keep using
|
|
// `pnpm run db:roles:provision` with real, externally managed secrets.
|
|
|
|
import { randomBytes } from "node:crypto";
|
|
|
|
import { provisionRlsRoles, ROLE_PASSWORD_ENV } from "./provision-rls-roles.mjs";
|
|
|
|
if (process.env.NODE_ENV === "production") {
|
|
process.stderr.write("FAIL dev:db:roles is a local helper; use db:roles:provision with managed secrets instead\n");
|
|
process.exit(1);
|
|
}
|
|
|
|
const connectionString = process.env.HIVEGRID_RLS_PROVISION_DATABASE_URL ?? process.env.DIRECT_URL ?? process.env.DATABASE_URL;
|
|
if (!connectionString) {
|
|
process.stderr.write("FAIL no DATABASE_URL (or DIRECT_URL) found — copy .env.example to .env first\n");
|
|
process.exit(1);
|
|
}
|
|
|
|
const env = {
|
|
...process.env,
|
|
HIVEGRID_RLS_PROVISION_DATABASE_URL: connectionString,
|
|
};
|
|
for (const passwordEnvName of Object.values(ROLE_PASSWORD_ENV)) {
|
|
// 48 hex chars, comfortably above the provisioner's 32-character floor and
|
|
// distinct per role (it rejects duplicates).
|
|
env[passwordEnvName] = randomBytes(24).toString("hex");
|
|
}
|
|
|
|
try {
|
|
await provisionRlsRoles({ env });
|
|
process.stdout.write("PASS local RLS roles provisioned (throwaway passwords, not persisted)\n");
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : "role provisioning failed";
|
|
process.stderr.write(`FAIL ${message}\n`);
|
|
process.exit(1);
|
|
}
|