diff --git a/express/mgmt/add-user.ts b/express/mgmt/add-user.ts new file mode 100644 index 0000000..892787f --- /dev/null +++ b/express/mgmt/add-user.ts @@ -0,0 +1,67 @@ +// add-user.ts +// Management command to create users from the command line + +import { pool, PostgresAuthStore } from "../database"; +import { hashPassword } from "../auth/password"; + +async function main(): Promise { + const args = process.argv.slice(2); + + if (args.length < 2) { + console.error( + "Usage: ./mgmt add-user [--display-name ] [--active]", + ); + process.exit(1); + } + + const email = args[0]; + const password = args[1]; + + // Parse optional flags + let displayName: string | undefined; + let makeActive = false; + + for (let i = 2; i < args.length; i++) { + if (args[i] === "--display-name" && args[i + 1]) { + displayName = args[i + 1]; + i++; + } else if (args[i] === "--active") { + makeActive = true; + } + } + + try { + const store = new PostgresAuthStore(); + + // Check if user already exists + const existing = await store.getUserByEmail(email); + if (existing) { + console.error(`Error: User with email '${email}' already exists`); + process.exit(1); + } + + // Hash password and create user + const passwordHash = await hashPassword(password); + const user = await store.createUser({ + email, + passwordHash, + displayName, + }); + + // Optionally activate user immediately + if (makeActive) { + await store.updateUserEmailVerified(user.id); + console.log(`Created and activated user: ${user.email} (${user.id})`); + } else { + console.log(`Created user: ${user.email} (${user.id})`); + console.log(" Status: pending (use --active to create as active)"); + } + } finally { + await pool.end(); + } +} + +main().catch((err) => { + console.error("Failed to create user:", err.message); + process.exit(1); +}); diff --git a/framework/mgmt.d/add-user b/framework/mgmt.d/add-user new file mode 100755 index 0000000..c3c71bd --- /dev/null +++ b/framework/mgmt.d/add-user @@ -0,0 +1,9 @@ +#!/bin/bash + +set -eu + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$DIR/../.." + +cd "$ROOT/express" +"$DIR"/../cmd.d/tsx mgmt/add-user.ts "$@" diff --git a/mgmt b/mgmt new file mode 100755 index 0000000..58fc7d0 --- /dev/null +++ b/mgmt @@ -0,0 +1,25 @@ +#!/bin/bash + +# Management command runner - parallel to ./cmd for operational tasks +# Usage: ./mgmt [args...] + +set -eu + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +if [ $# -lt 1 ]; then + echo "Usage: ./mgmt [args...]" + echo "" + echo "Available commands:" + for cmd in "$DIR"/framework/mgmt.d/*; do + if [ -x "$cmd" ]; then + basename "$cmd" + fi + done + exit 1 +fi + +subcmd="$1" +shift + +exec "$DIR"/framework/mgmt.d/"$subcmd" "$@"