- Real email/password login backed by SQLite (better-sqlite3) - HttpOnly cookie sessions with 8h sliding TTL - Admin role: invite users via Mailgun magic-link, manage roles/status - Per-user One2Edit username mapping for job filtering - Self-service forgot-password / reset-password via email - Admin console (admin.html) with user table, invite modal, row actions - New pages: change-password, forgot-password, reset-password, accept-invite - Gated /api proxy: requires valid session, anti-hijack sessionId check - Bootstrap initial admins from INITIAL_ADMINS env var on first boot - Remove Oliver login button, SSO buttons, and legacy api.js/login.js - deploy.sh: add build-essential (for native module), npm install, data dir Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
48 lines
1.6 KiB
JavaScript
48 lines
1.6 KiB
JavaScript
#!/usr/bin/env node
|
|
// Emergency CLI: create or reset an admin user directly in the database.
|
|
// Usage: node scripts/create-admin.js
|
|
|
|
'use strict';
|
|
|
|
require('dotenv').config({ path: require('path').join(__dirname, '..', '.env') });
|
|
|
|
const readline = require('readline');
|
|
const { createUser, getUserByEmail, setPassword } = require('../lib/db');
|
|
const { hash } = require('../lib/password');
|
|
|
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
const ask = (q) => new Promise(res => rl.question(q, res));
|
|
|
|
async function main() {
|
|
console.log('\n3M Portal — create/reset admin\n');
|
|
|
|
const email = (await ask('Email: ')).trim();
|
|
const o2eUser = (await ask('One2Edit username: ')).trim();
|
|
const password = (await ask('Password: ')).trim();
|
|
|
|
if (!email || !o2eUser || !password) {
|
|
console.error('All fields required.'); process.exit(1);
|
|
}
|
|
if (password.length < 10) {
|
|
console.error('Password must be at least 10 characters.'); process.exit(1);
|
|
}
|
|
|
|
const existing = getUserByEmail(email);
|
|
if (existing) {
|
|
setPassword(existing.id, hash(password), 0);
|
|
console.log(`\nUpdated password for existing user: ${email}`);
|
|
} else {
|
|
createUser({
|
|
email,
|
|
one2editUsername: o2eUser,
|
|
passwordHash: hash(password),
|
|
role: 'admin',
|
|
mustChangePassword: 0,
|
|
});
|
|
console.log(`\nCreated admin: ${email}`);
|
|
}
|
|
|
|
rl.close();
|
|
}
|
|
|
|
main().catch(err => { console.error(err.message); process.exit(1); });
|