divan/api/src/admin-cli.ts
Anas Rashid acf7767495 Admin panel: users, password reset on request, disable, roles, delete, audit log (#27)
- API (api/src/admin.ts, admins only): user list and search; password reset generates a temporary
  password shown once and ends the user's sessions; disable/enable (ends sessions, blocks sign-in);
  roles reader/admin; delete; an admin cannot disable, demote or delete themself. Every action is
  written to audit_log (kept when users are deleted).
- First admin from the server: npm run make-admin -- <email> (after signing up).
- Site: /admin (users) and /admin/audit; 'ایڈمن' link in the header for admins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:08:19 +02:00

19 lines
832 B
TypeScript

// Make an existing account an admin, from the server (the first admin cannot be made from the site).
// The person signs up on the site first, then:
// node src/admin-cli.ts admin@example.com
import { pool } from './db.ts';
import { audit } from './admin.ts';
const email = (process.argv[2] ?? '').trim().toLowerCase();
if (!email) {
console.error('usage: node src/admin-cli.ts <email of an existing account>');
process.exit(1);
}
const { rows } = await pool.query(`UPDATE users SET role = 'admin', disabled_at = NULL WHERE email = $1 RETURNING id, email`, [email]);
if (rows[0]) {
await audit(null, 'promote', rows[0], { to: 'admin', via: 'server' });
console.log(`${email} is now an admin`);
} else console.error(`no account with ${email}; sign up on the site first`);
await pool.end();
process.exit(rows[0] ? 0 : 1);