← back to Govarbitrage
set-admin: generate strong random password server-side (no hardcoded default)
bba7207ccedd3fc4458154fdc405d8c67e79b5d1 · 2026-07-12 23:49:50 -0700 · Steve
Files touched
Diff
commit bba7207ccedd3fc4458154fdc405d8c67e79b5d1
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jul 12 23:49:50 2026 -0700
set-admin: generate strong random password server-side (no hardcoded default)
---
scripts/set-admin.ts | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/scripts/set-admin.ts b/scripts/set-admin.ts
index 5256497..8b09170 100644
--- a/scripts/set-admin.ts
+++ b/scripts/set-admin.ts
@@ -1,13 +1,26 @@
// Set/reset the admin login credential without running the full seed.
-// Usage: ADMIN_EMAIL=admin@agentabrams.com ADMIN_PASSWORD='DW2024!' npx tsx scripts/set-admin.ts
-// Defaults to the unified fleet credential.
+// Usage:
+// ADMIN_EMAIL=admin@agentabrams.com ADMIN_PASSWORD='...' npx tsx scripts/set-admin.ts
+// (omit ADMIN_PASSWORD to GENERATE a strong random one and print it once)
+// Never hardcodes a real password.
+import { randomBytes } from "node:crypto";
import { prisma } from "../src/lib/db";
import { hashPassword } from "../src/lib/password";
+// Readable strong password: 3 base32-ish blocks, ~120 bits.
+function generatePassword(): string {
+ const alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // no ambiguous 0/O/1/I
+ const bytes = randomBytes(18);
+ const chars = Array.from(bytes, (b) => alphabet[b % alphabet.length]);
+ return `${chars.slice(0, 6).join("")}-${chars.slice(6, 12).join("")}-${chars.slice(12, 18).join("")}`;
+}
+
async function main() {
const email = process.env.ADMIN_EMAIL || process.argv[2] || "admin@agentabrams.com";
- const password = process.env.ADMIN_PASSWORD || process.argv[3] || "DW2024!";
+ const provided = process.env.ADMIN_PASSWORD || process.argv[3];
+ const generated = !provided;
+ const password = provided || generatePassword();
const hash = hashPassword(password);
const user = await prisma.user.upsert({
where: { email },
@@ -15,6 +28,10 @@ async function main() {
create: { email, name: "Admin", role: "ADMIN", passwordHash: hash },
});
console.log(`Admin credential set: ${user.email} (role ${user.role}).`);
+ if (generated) {
+ // Printed ONCE so the operator can capture it; never stored to disk/git.
+ console.log(`GENERATED_PASSWORD=${password}`);
+ }
await prisma.$disconnect();
}
← deba4c5 seed: never hardcode admin password — set out-of-band via se
·
back to Govarbitrage
·
Honesty Gate: confidence-discounted, capped, disclaimed hot- 1162672 →