initial commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
const USERS_PATH = process.env.USERS_PATH || path.join(__dirname, '..', 'users.json');
|
||||
|
||||
function load() {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(USERS_PATH, 'utf8'));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function save(users) {
|
||||
fs.writeFileSync(USERS_PATH, JSON.stringify(users, null, 2), 'utf8');
|
||||
}
|
||||
|
||||
/**
|
||||
* On first run, create a default admin user if no users exist.
|
||||
* Prints a warning to remind the user to change the password.
|
||||
*/
|
||||
function ensureDefaultAdmin() {
|
||||
const users = load();
|
||||
if (users.length === 0) {
|
||||
const hash = bcrypt.hashSync('admin', 10);
|
||||
save([{ id: '1', username: 'admin', passwordHash: hash, createdAt: new Date().toISOString() }]);
|
||||
console.warn('⚠️ No users found — created default admin account.');
|
||||
console.warn('⚠️ Username: admin Password: admin');
|
||||
console.warn('⚠️ Change this password immediately in Settings → Users.');
|
||||
}
|
||||
}
|
||||
|
||||
function getAll() {
|
||||
return load().map(({ passwordHash, ...u }) => u); // strip hash from output
|
||||
}
|
||||
|
||||
function findByUsername(username) {
|
||||
return load().find(u => u.username.toLowerCase() === username.toLowerCase()) ?? null;
|
||||
}
|
||||
|
||||
function findById(id) {
|
||||
return load().find(u => u.id === id) ?? null;
|
||||
}
|
||||
|
||||
function create(username, password) {
|
||||
const users = load();
|
||||
if (users.find(u => u.username.toLowerCase() === username.toLowerCase())) {
|
||||
throw new Error('Username already exists');
|
||||
}
|
||||
const hash = bcrypt.hashSync(password, 10);
|
||||
const user = {
|
||||
id: Date.now().toString(),
|
||||
username,
|
||||
passwordHash: hash,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
users.push(user);
|
||||
save(users);
|
||||
const { passwordHash, ...safe } = user;
|
||||
return safe;
|
||||
}
|
||||
|
||||
function updatePassword(id, newPassword) {
|
||||
const users = load();
|
||||
const idx = users.findIndex(u => u.id === id);
|
||||
if (idx === -1) throw new Error('User not found');
|
||||
users[idx].passwordHash = bcrypt.hashSync(newPassword, 10);
|
||||
save(users);
|
||||
}
|
||||
|
||||
function remove(id) {
|
||||
const users = load();
|
||||
if (users.length === 1) throw new Error('Cannot delete the last user');
|
||||
const filtered = users.filter(u => u.id !== id);
|
||||
if (filtered.length === users.length) throw new Error('User not found');
|
||||
save(filtered);
|
||||
}
|
||||
|
||||
function verifyPassword(user, password) {
|
||||
return bcrypt.compareSync(password, user.passwordHash);
|
||||
}
|
||||
|
||||
module.exports = { ensureDefaultAdmin, getAll, findByUsername, findById, create, updatePassword, remove, verifyPassword };
|
||||
Reference in New Issue
Block a user