Spaces:
Sleeping
Sleeping
| const Admin = require('../models/Admin'); | |
| const AuditLog = require('../models/AuditLog'); | |
| exports.list = async () => { | |
| return Admin.find().populate('assignedMarkets', 'name code').sort('profile.firstName'); | |
| }; | |
| exports.create = async ({ email, password, role, profile, assignedMarkets }, actorId, ip) => { | |
| if (!email || !password || !role) throw Object.assign(new Error('Email, password, and role are required.'), { statusCode: 400 }); | |
| if (password.length < 12) throw Object.assign(new Error('Password must be at least 12 characters.'), { statusCode: 400 }); | |
| const admin = await Admin.create({ | |
| email, | |
| passwordHash: password, | |
| role, | |
| profile, | |
| assignedMarkets: assignedMarkets || [], | |
| }); | |
| await admin.populate('assignedMarkets', 'name code'); | |
| await AuditLog.create({ action: 'admin_user_created', actor: actorId, targetType: 'admin', targetId: admin._id, details: { role, email }, ipAddress: ip }); | |
| return admin; | |
| }; | |
| exports.update = async (id, { role, profile, assignedMarkets, password }, actorId, ip) => { | |
| const admin = await Admin.findById(id); | |
| if (!admin) throw Object.assign(new Error('Admin user not found.'), { statusCode: 404 }); | |
| if (role) admin.role = role; | |
| if (profile) admin.profile = { ...admin.profile.toObject?.() || admin.profile, ...profile }; | |
| if (assignedMarkets) admin.assignedMarkets = assignedMarkets; | |
| if (password) { | |
| if (password.length < 12) throw Object.assign(new Error('Password must be at least 12 characters.'), { statusCode: 400 }); | |
| admin.passwordHash = password; | |
| } | |
| await admin.save(); | |
| await admin.populate('assignedMarkets', 'name code'); | |
| await AuditLog.create({ action: 'admin_user_updated', actor: actorId, targetType: 'admin', targetId: admin._id, details: { updatedFields: Object.keys({ role, profile, assignedMarkets, password }).filter(k => arguments[1][k]) }, ipAddress: ip }); | |
| return admin; | |
| }; | |
| exports.deactivate = async (id, actorId, ip) => { | |
| const admin = await Admin.findById(id); | |
| if (!admin) throw Object.assign(new Error('Admin user not found.'), { statusCode: 404 }); | |
| if (admin._id.toString() === actorId.toString()) { | |
| throw Object.assign(new Error('You cannot deactivate your own account.'), { statusCode: 400 }); | |
| } | |
| admin.accountStatus = 'deactivated'; | |
| admin.refreshToken = null; | |
| await admin.save({ validateModifiedOnly: true }); | |
| await AuditLog.create({ action: 'admin_user_deactivated', actor: actorId, targetType: 'admin', targetId: admin._id, ipAddress: ip }); | |
| }; | |
| exports.getAuditLog = async (id) => { | |
| const admin = await Admin.findById(id).select('email profile loginAudit'); | |
| if (!admin) throw Object.assign(new Error('Admin user not found.'), { statusCode: 404 }); | |
| const auditEntries = await AuditLog.find({ actor: id }).sort({ timestamp: -1 }).limit(100); | |
| return { admin: { email: admin.email, profile: admin.profile }, loginAudit: admin.loginAudit.slice(-20), auditEntries }; | |
| }; | |