deckhearth/scripts/create-test-users.js

75 lines
2.6 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
/**
* Create Test Users Script
*
* Seeds the alice + bob test-user fixtures used by the manual QA flows
* in TESTING_GUIDE.md. Both users share a single password supplied via
* the TEST_USERS_PASSWORD environment variable this is a test-fixture
* helper, not a prod auth surface, so per-user env vars would be
* unnecessary sprawl.
*
* Required env (in .env.local):
* POSTGRES_URL Neon connection string
* TEST_USERS_PASSWORD strong password applied to every test user
* (generate with `openssl rand -base64 24`)
*
* Mirrors the post-`drop-public-setup` shape of `setup-neon-db.js`
* (commit b63b509) and the post-`fix-reset-db-script` shape of
* `reset-db.js` (commit 3ab9bf8) same ESM imports, same fail-loud
* env-var check, same no-password-echo convention. Convoy:
* `purge-weak-creds-from-helpers` (2026-05-26).
*/
import { config } from 'dotenv';
import { sql } from '@vercel/postgres';
import bcrypt from 'bcryptjs';
config({ path: '.env.local' });
async function createTestUsers() {
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
const testUsersPassword = process.env.TEST_USERS_PASSWORD;
if (!testUsersPassword || !testUsersPassword.trim()) {
console.error(
'❌ TEST_USERS_PASSWORD environment variable is not set.\n' +
'\n' +
' Set it in .env.local before running `node scripts/create-test-users.js`.\n' +
' Generate a strong password with: openssl rand -base64 24\n' +
' See README.md → "First-time admin setup" for the env-var pattern.\n'
);
process.exit(1);
}
try {
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
console.log('👥 Creating test users...\n');
const hashedPassword = await bcrypt.hash(testUsersPassword, 12);
await sql`
INSERT INTO users (email, password, role)
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
VALUES ('alice@deckhearth.com', ${hashedPassword}, 'user')
ON CONFLICT (email) DO NOTHING
`;
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
console.log('✅ Created Alice (alice@deckhearth.com)');
await sql`
INSERT INTO users (email, password, role)
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
VALUES ('bob@deckhearth.com', ${hashedPassword}, 'user')
ON CONFLICT (email) DO NOTHING
`;
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
console.log('✅ Created Bob (bob@deckhearth.com)');
console.log('\n🎉 Test users created successfully!');
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27) `scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)` + `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test Accounts table documented the same `admin123` / `alice123` / `bob123` trio. These were the last two weak-credential surfaces left in the helper-script + manual-QA-doc tree after `drop-public-setup` (commits `ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`, PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the umbrella `purge-weak-creds-from-helpers` queued follow-up. The fix mirrors the post-`drop-public-setup` `setup-neon-db.js` pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one deliberate simplification: a single `TEST_USERS_PASSWORD` env var covers both alice + bob rather than per-user env vars (risk R2 in the convoy file argues this — these are fixture users for the collaboration demo flow, not independent identities, and per-user sprawl would double the env-var contract for zero security benefit). `createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the top of the function body and exits with code 1 BEFORE opening any DB connection if the var is unset or whitespace-only, with the same helpful-error wording template the other two scripts use (names the var, points at `.env.local`, suggests `openssl rand -base64 24`, references README's "First-time admin setup" section). All four password-echo `console.log` lines are deleted; the new summary documents *where* the password comes from without ever printing it. `TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password source per user instead of the literal value; the two inline `Password: alice123` / `Password: bob123` workflow snippets are replaced with placeholder text. Unlike the previous two convoys, no CJS→ESM conversion was needed — `create-test-users.js` was already top-level ESM. Verification (all static — script is destructive and not live-tested): `node --check scripts/create-test-users.js` exit 0; `npm run lint` 128 problems (baseline preserved, no regression); `npm run test:run` 21/21 pass; grep `scripts/ TESTING_GUIDE.md` for `admin123|password123|test123|alice123|bob123` → 0 hits; `TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc). Operator caveat: anyone running `node scripts/create-test-users.js` post-merge must add `TEST_USERS_PASSWORD=<value>` to their `.env.local` first; existing alice + bob rows in already-seeded environments are NOT rotated by re-running this script (`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same caveat that applies to the `drop-public-setup` admin row. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
console.log('\n👥 Available Test Accounts (passwords from TEST_USERS_PASSWORD):');
console.log(' 1. admin@deckhearth.com (Admin — seeded by setup-neon-db.js)');
console.log(' 2. alice@deckhearth.com (User)');
console.log(' 3. bob@deckhearth.com (User)');
} catch (error) {
console.error('❌ Failed to create test users:', error.message);
process.exit(1);
}
}
createTestUsers();