[object Object]

← back to Norma

scripts: restore-admin-hash helper (revert a tier_credentials hash from a saved restore file)

159c3e5bb60ad745209eb9fbd33ff3b78174263e · 2026-08-28 07:33:45 -0700 · Steve Abrams

Files touched

Diff

commit 159c3e5bb60ad745209eb9fbd33ff3b78174263e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Aug 28 07:33:45 2026 -0700

    scripts: restore-admin-hash helper (revert a tier_credentials hash from a saved restore file)
---
 scripts/restore-admin-hash.mjs | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/scripts/restore-admin-hash.mjs b/scripts/restore-admin-hash.mjs
new file mode 100644
index 0000000..36cc4cc
--- /dev/null
+++ b/scripts/restore-admin-hash.mjs
@@ -0,0 +1,20 @@
+#!/usr/bin/env node
+// Restore a tier_credentials password_hash from a saved password-restore JSON.
+//   RESTORE_FILE=scripts/password-restore/<file>.json node scripts/restore-admin-hash.mjs
+import fs from 'node:fs';
+import pg from 'pg';
+const file = process.env.RESTORE_FILE;
+if (!file) { console.error('FATAL: set RESTORE_FILE'); process.exit(2); }
+const rows = JSON.parse(fs.readFileSync(file, 'utf8'));
+const dsn = process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/sdcc';
+const c = new pg.Client({ connectionString: dsn });
+await c.connect();
+try { const u = new URL(dsn); console.log(`DB: ${u.hostname}:${u.port || 5432}${u.pathname}`); } catch {}
+for (const r of rows) {
+  const res = await c.query(
+    'UPDATE tier_credentials SET password_hash = $1 WHERE username = $2 RETURNING username',
+    [r.password_hash, r.username],
+  );
+  console.log(`restored ${res.rowCount} row(s) for ${r.username} → ${r.password_hash.slice(0, 14)}…`);
+}
+await c.end();

← db0ecc2 feat(set-admin-password): NEW_PW_B64 input to survive shell  ·  back to Norma  ·  auto-data-snapshot: 2026-08-28T07:45:44 (1 data files) — scr 4b4bb89 →