Your commit message here
This commit is contained in:
125
src/lib/userManagement.js
Normal file
125
src/lib/userManagement.js
Normal file
@@ -0,0 +1,125 @@
|
||||
import db from "./db.js"
|
||||
import bcrypt from "bcryptjs"
|
||||
import { randomBytes } from "crypto"
|
||||
|
||||
// Create a new user
|
||||
export async function createUser({ name, email, password, role = 'user' }) {
|
||||
const existingUser = db.prepare("SELECT id FROM users WHERE email = ?").get(email)
|
||||
if (existingUser) {
|
||||
throw new Error("User with this email already exists")
|
||||
}
|
||||
|
||||
const passwordHash = await bcrypt.hash(password, 12)
|
||||
const userId = randomBytes(16).toString('hex')
|
||||
|
||||
const result = db.prepare(`
|
||||
INSERT INTO users (id, name, email, password_hash, role)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
`).run(userId, name, email, passwordHash, role)
|
||||
|
||||
return { id: userId, name, email, role }
|
||||
}
|
||||
|
||||
// Get user by ID
|
||||
export function getUserById(id) {
|
||||
return db.prepare(`
|
||||
SELECT id, name, email, role, created_at, last_login, is_active
|
||||
FROM users WHERE id = ?
|
||||
`).get(id)
|
||||
}
|
||||
|
||||
// Get user by email
|
||||
export function getUserByEmail(email) {
|
||||
return db.prepare(`
|
||||
SELECT id, name, email, role, created_at, last_login, is_active
|
||||
FROM users WHERE email = ?
|
||||
`).get(email)
|
||||
}
|
||||
|
||||
// Get all users (for admin)
|
||||
export function getAllUsers() {
|
||||
return db.prepare(`
|
||||
SELECT id, name, email, role, created_at, last_login, is_active,
|
||||
failed_login_attempts, locked_until
|
||||
FROM users
|
||||
ORDER BY created_at DESC
|
||||
`).all()
|
||||
}
|
||||
|
||||
// Update user role
|
||||
export function updateUserRole(userId, role) {
|
||||
const validRoles = ['admin', 'project_manager', 'user', 'read_only']
|
||||
if (!validRoles.includes(role)) {
|
||||
throw new Error("Invalid role")
|
||||
}
|
||||
|
||||
const result = db.prepare(`
|
||||
UPDATE users SET role = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`).run(role, userId)
|
||||
|
||||
return result.changes > 0
|
||||
}
|
||||
|
||||
// Activate/deactivate user
|
||||
export function setUserActive(userId, isActive) {
|
||||
const result = db.prepare(`
|
||||
UPDATE users SET is_active = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
`).run(isActive ? 1 : 0, userId)
|
||||
|
||||
return result.changes > 0
|
||||
}
|
||||
|
||||
// Change user password
|
||||
export async function changeUserPassword(userId, newPassword) {
|
||||
const passwordHash = await bcrypt.hash(newPassword, 12)
|
||||
|
||||
const result = db.prepare(`
|
||||
UPDATE users
|
||||
SET password_hash = ?, updated_at = CURRENT_TIMESTAMP,
|
||||
failed_login_attempts = 0, locked_until = NULL
|
||||
WHERE id = ?
|
||||
`).run(passwordHash, userId)
|
||||
|
||||
return result.changes > 0
|
||||
}
|
||||
|
||||
// Clean up expired sessions
|
||||
export function cleanupExpiredSessions() {
|
||||
const result = db.prepare(`
|
||||
DELETE FROM sessions WHERE expires < datetime('now')
|
||||
`).run()
|
||||
|
||||
return result.changes
|
||||
}
|
||||
|
||||
// Get user sessions
|
||||
export function getUserSessions(userId) {
|
||||
return db.prepare(`
|
||||
SELECT id, session_token, expires, created_at
|
||||
FROM sessions
|
||||
WHERE user_id = ? AND expires > datetime('now')
|
||||
ORDER BY created_at DESC
|
||||
`).all(userId)
|
||||
}
|
||||
|
||||
// Revoke user session
|
||||
export function revokeSession(sessionToken) {
|
||||
const result = db.prepare(`
|
||||
DELETE FROM sessions WHERE session_token = ?
|
||||
`).run(sessionToken)
|
||||
|
||||
return result.changes > 0
|
||||
}
|
||||
|
||||
// Get audit logs for user
|
||||
export function getUserAuditLogs(userId, limit = 50) {
|
||||
return db.prepare(`
|
||||
SELECT action, resource_type, resource_id, ip_address, timestamp, details
|
||||
FROM audit_logs
|
||||
WHERE user_id = ?
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT ?
|
||||
`).all(userId, limit)
|
||||
}
|
||||
Reference in New Issue
Block a user