false, 'message' => 'User ID required'], 400); } updateUser($id); break; case 'DELETE': if (!$id) { jsonResponse(['success' => false, 'message' => 'ID required'], 400); } deleteUser($id); break; default: jsonResponse(['success' => false, 'message' => 'Method not allowed'], 405); } function getUsers() { global $db; $users = $db->getAll('users'); // Remove sensitive data foreach ($users as &$user) { unset($user['password']); } jsonResponse(['success' => true, 'data' => array_values($users)]); } function getUser($id) { global $db; $user = $db->get('users', $id); if (!$user) jsonResponse(['success' => false, 'message' => 'Not found'], 404); unset($user['password']); jsonResponse(['success' => true, 'data' => $user]); } function createUser() { global $db; $data = !empty($_POST) ? $_POST : getRequestBody(); if (empty($data['username']) || empty($data['password']) || empty($data['email'])) { jsonResponse(['success' => false, 'message' => 'Username, Email and Password required'], 400); } // Enforce minimum password strength if (strlen($data['password']) < 12) { jsonResponse(['success' => false, 'message' => 'Password must be at least 12 characters'], 400); } // Check if username exists $existing = $db->query('users', ['username' => $data['username']]); if (!empty($existing)) { jsonResponse(['success' => false, 'message' => 'Username already exists'], 400); } // Check if email exists $existingEmail = $db->query('users', ['email' => $data['email']]); if (!empty($existingEmail)) { jsonResponse(['success' => false, 'message' => 'Email already in use'], 400); } // Validate email format if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { jsonResponse(['success' => false, 'message' => 'Invalid email address'], 400); } // Whitelist allowed roles and statuses $allowedRoles = ['admin', 'editor']; $role = in_array($data['role'] ?? 'editor', $allowedRoles, true) ? $data['role'] : 'editor'; $allowedStatuses = ['active', 'inactive']; $status = in_array($data['status'] ?? 'active', $allowedStatuses, true) ? $data['status'] : 'active'; $user = [ 'name' => sanitize($data['name'] ?? ''), 'username' => sanitize($data['username']), 'email' => sanitize($data['email']), 'role' => $role, 'status' => $status, 'password' => password_hash($data['password'], PASSWORD_DEFAULT), 'last_login' => null ]; $created = $db->insert('users', $user); unset($created['password']); jsonResponse(['success' => true, 'message' => 'User created', 'data' => $created]); } function updateUser($id) { global $db; $existing = $db->get('users', $id); if (!$existing) jsonResponse(['success' => false, 'message' => 'Not found'], 404); $data = !empty($_POST) ? $_POST : getRequestBody(); $updateData = []; if (!empty($data['name'])) $updateData['name'] = sanitize($data['name']); if (!empty($data['email'])) { if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { jsonResponse(['success' => false, 'message' => 'Invalid email address'], 400); } $updateData['email'] = sanitize($data['email']); } if (!empty($data['role'])) { $allowedRoles = ['admin', 'editor']; $updateData['role'] = in_array($data['role'], $allowedRoles, true) ? $data['role'] : ($existing['role'] ?? 'editor'); } if (!empty($data['status'])) { $allowedStatuses = ['active', 'inactive']; $updateData['status'] = in_array($data['status'], $allowedStatuses, true) ? $data['status'] : ($existing['status'] ?? 'active'); } // Password update if (!empty($data['password'])) { if (strlen($data['password']) < 12) { jsonResponse(['success' => false, 'message' => 'Password must be at least 12 characters'], 400); } $updateData['password'] = password_hash($data['password'], PASSWORD_DEFAULT); } $updated = $db->update('users', $id, $updateData); unset($updated['password']); jsonResponse(['success' => true, 'message' => 'User updated', 'data' => $updated]); } function deleteUser($id) { global $db; global $currentUser; // Prevent deleting self (simplistic check) if ($currentUser['user_id'] === $id) { jsonResponse(['success' => false, 'message' => 'Cannot delete yourself'], 400); } $db->delete('users', $id); jsonResponse(['success' => true, 'message' => 'User deleted']); } function requireAdminRole($user) { if (($user['role'] ?? '') !== 'admin') { jsonResponse(['success' => false, 'message' => 'Forbidden'], 403); } }