Genesis
This commit is contained in:
195
manage-users.js
Normal file
195
manage-users.js
Normal file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env node
|
||||
import { input, password, select, confirm } from '@inquirer/prompts';
|
||||
import Database from 'better-sqlite3';
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
const DB_FILE = 'ac_data.db';
|
||||
|
||||
const db = new Database(DB_FILE);
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'user',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
|
||||
const insertUser = db.prepare('INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)');
|
||||
const getAllUsers = db.prepare('SELECT id, username, role, created_at FROM users ORDER BY id');
|
||||
const getUserById = db.prepare('SELECT * FROM users WHERE id = ?');
|
||||
const updateUserRole = db.prepare('UPDATE users SET role = ? WHERE id = ?');
|
||||
const updateUserPassword = db.prepare('UPDATE users SET password_hash = ? WHERE id = ?');
|
||||
const deleteUser = db.prepare('DELETE FROM users WHERE id = ?');
|
||||
|
||||
console.log('\n╔════════════════════════════════════╗');
|
||||
console.log('║ 🔐 User Manager - AC Dashboard ║');
|
||||
console.log('╚════════════════════════════════════╝\n');
|
||||
|
||||
async function listUsers() {
|
||||
const users = getAllUsers.all();
|
||||
if (users.length === 0) {
|
||||
console.log(' No users found.\n');
|
||||
return;
|
||||
}
|
||||
console.log(' ID │ Username │ Role │ Created');
|
||||
console.log(' ────┼────────────────┼────────┼─────────────────────');
|
||||
users.forEach(u => {
|
||||
const id = String(u.id).padStart(3);
|
||||
const name = u.username.padEnd(14);
|
||||
const role = u.role.padEnd(6);
|
||||
const date = u.created_at?.slice(0, 16) || 'N/A';
|
||||
const roleColor = u.role === 'admin' ? '\x1b[35m' : '\x1b[33m';
|
||||
console.log(` ${id} │ ${name} │ ${roleColor}${role}\x1b[0m │ ${date}`);
|
||||
});
|
||||
console.log('');
|
||||
}
|
||||
|
||||
async function createUser() {
|
||||
const username = await input({
|
||||
message: 'Username:',
|
||||
validate: v => v.length >= 3 || 'Min 3 characters'
|
||||
});
|
||||
|
||||
const pwd = await password({
|
||||
message: 'Password:',
|
||||
mask: '*',
|
||||
validate: v => v.length >= 4 || 'Min 4 characters'
|
||||
});
|
||||
|
||||
const role = await select({
|
||||
message: 'Role:',
|
||||
choices: [
|
||||
{ name: '👤 user', value: 'user' },
|
||||
{ name: '👑 admin', value: 'admin' }
|
||||
]
|
||||
});
|
||||
|
||||
try {
|
||||
const hash = await bcrypt.hash(pwd, 10);
|
||||
insertUser.run(username, hash, role);
|
||||
console.log(`\n✅ User "${username}" created as ${role}\n`);
|
||||
} catch (e) {
|
||||
if (e.code === 'SQLITE_CONSTRAINT_UNIQUE') {
|
||||
console.log(`\n❌ User "${username}" already exists\n`);
|
||||
} else throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async function editUser() {
|
||||
const users = getAllUsers.all();
|
||||
if (users.length === 0) {
|
||||
console.log(' No users to edit.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = await select({
|
||||
message: 'Select user to edit:',
|
||||
choices: users.map(u => ({
|
||||
name: `${u.username} (${u.role})`,
|
||||
value: u.id
|
||||
}))
|
||||
});
|
||||
|
||||
const action = await select({
|
||||
message: 'What to change?',
|
||||
choices: [
|
||||
{ name: '🔑 Change password', value: 'password' },
|
||||
{ name: '👤 Change role', value: 'role' },
|
||||
{ name: '← Back', value: 'back' }
|
||||
]
|
||||
});
|
||||
|
||||
if (action === 'back') return;
|
||||
|
||||
if (action === 'password') {
|
||||
const pwd = await password({
|
||||
message: 'New password:',
|
||||
mask: '*',
|
||||
validate: v => v.length >= 4 || 'Min 4 characters'
|
||||
});
|
||||
const hash = await bcrypt.hash(pwd, 10);
|
||||
updateUserPassword.run(hash, userId);
|
||||
console.log('\n✅ Password updated\n');
|
||||
}
|
||||
|
||||
if (action === 'role') {
|
||||
const user = getUserById.get(userId);
|
||||
const newRole = await select({
|
||||
message: 'New role:',
|
||||
choices: [
|
||||
{ name: '👤 user', value: 'user' },
|
||||
{ name: '👑 admin', value: 'admin' }
|
||||
],
|
||||
default: user.role
|
||||
});
|
||||
updateUserRole.run(newRole, userId);
|
||||
console.log(`\n✅ Role changed to ${newRole}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
async function removeUser() {
|
||||
const users = getAllUsers.all();
|
||||
if (users.length === 0) {
|
||||
console.log(' No users to delete.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = await select({
|
||||
message: 'Select user to delete:',
|
||||
choices: users.map(u => ({
|
||||
name: `${u.username} (${u.role})`,
|
||||
value: u.id
|
||||
}))
|
||||
});
|
||||
|
||||
const user = getUserById.get(userId);
|
||||
const confirmed = await confirm({
|
||||
message: `Delete user "${user.username}"?`,
|
||||
default: false
|
||||
});
|
||||
|
||||
if (confirmed) {
|
||||
deleteUser.run(userId);
|
||||
console.log(`\n✅ User "${user.username}" deleted\n`);
|
||||
} else {
|
||||
console.log('\n❌ Cancelled\n');
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
while (true) {
|
||||
try {
|
||||
const action = await select({
|
||||
message: 'What would you like to do?',
|
||||
choices: [
|
||||
{ name: '📋 List users', value: 'list' },
|
||||
{ name: '➕ Create user', value: 'create' },
|
||||
{ name: '✏️ Edit user', value: 'edit' },
|
||||
{ name: '🗑️ Delete user', value: 'delete' },
|
||||
{ name: '🚪 Exit', value: 'exit' }
|
||||
]
|
||||
});
|
||||
|
||||
if (action === 'exit') {
|
||||
console.log('Bye!\n');
|
||||
break;
|
||||
}
|
||||
|
||||
if (action === 'list') await listUsers();
|
||||
if (action === 'create') await createUser();
|
||||
if (action === 'edit') await editUser();
|
||||
if (action === 'delete') await removeUser();
|
||||
|
||||
} catch (e) {
|
||||
if (e.name === 'ExitPromptError') {
|
||||
console.log('\nBye!\n');
|
||||
break;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user