04ca0a8299
- Users and sessions tables (Argon2 password hashing, SHA-256 session tokens) - Server hooks validate session cookie on every request - (app) routes redirect to /login if not authenticated - Login page with email/password, styled matching budget app - Logout via POST form action (invalidates session) - User display name and sign out button in header - create-user CLI script: npm run create-user <email> <password> [name] - 30-day sessions with auto-refresh after 15 days Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
1.3 KiB
TypeScript
55 lines
1.3 KiB
TypeScript
/**
|
|
* Create a user for buildfor_life_repair.
|
|
*
|
|
* Usage:
|
|
* npx tsx scripts/create-user.ts <email> <password> [displayName]
|
|
*
|
|
* Example:
|
|
* npx tsx scripts/create-user.ts admin@b4l.co.th mypassword "Admin"
|
|
*/
|
|
|
|
import 'dotenv/config';
|
|
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
import pg from 'pg';
|
|
import { users } from '../src/lib/server/db/schema.js';
|
|
import { hash } from '@node-rs/argon2';
|
|
import { encodeBase32LowerCaseNoPadding } from '@oslojs/encoding';
|
|
|
|
const args = process.argv.slice(2);
|
|
|
|
if (args.length < 2) {
|
|
console.error('Usage: npx tsx scripts/create-user.ts <email> <password> [displayName]');
|
|
process.exit(1);
|
|
}
|
|
|
|
const [email, password, displayName] = args;
|
|
|
|
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
const db = drizzle(pool);
|
|
|
|
async function main() {
|
|
const id = encodeBase32LowerCaseNoPadding(crypto.getRandomValues(new Uint8Array(15)));
|
|
|
|
const passwordHash = await hash(password!, {
|
|
memoryCost: 19456,
|
|
timeCost: 2,
|
|
outputLen: 32,
|
|
parallelism: 1
|
|
});
|
|
|
|
await db.insert(users).values({
|
|
id,
|
|
email: email!.toLowerCase().trim(),
|
|
displayName: displayName || null,
|
|
passwordHash
|
|
});
|
|
|
|
console.log(`User created: ${email} (id: ${id})`);
|
|
await pool.end();
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('Failed to create user:', err.message);
|
|
process.exit(1);
|
|
});
|