Refactor admin/user isolation logic and model methods
Moved admin/user isolation checks and related methods from Domain and NotificationGroup models to User model for better separation of concerns. Replaced direct database queries in controllers and services with new model methods. Added methods for assigning unassigned domains/groups, searching domains, and clearing old notification logs. Updated views for improved UI consistency.
This commit is contained in:
@@ -380,10 +380,7 @@ class AuthController extends Controller
|
||||
$this->logger->warning("No user found with verification token: " . substr($token, 0, 10) . "...");
|
||||
|
||||
// Debug: Check if any user has this token (regardless of verification status)
|
||||
$pdo = \Core\Database::getConnection();
|
||||
$stmt = $pdo->prepare("SELECT id, email, email_verified, email_verification_token FROM users WHERE email_verification_token = ?");
|
||||
$stmt->execute([$token]);
|
||||
$debugUser = $stmt->fetch();
|
||||
$debugUser = $this->userModel->findByVerificationTokenDebug($token);
|
||||
if ($debugUser) {
|
||||
$this->logger->info("Debug: Found user with token - ID: {$debugUser['id']}, Email: {$debugUser['email']}, Verified: {$debugUser['email_verified']}");
|
||||
} else {
|
||||
|
||||
@@ -37,7 +37,7 @@ class SearchController extends Controller
|
||||
$perPage = max(10, min(100, (int)($_GET['per_page'] ?? 25)));
|
||||
|
||||
// Search existing domains in database
|
||||
$allResults = $this->searchDomains($query, $isolationMode === 'isolated' ? $userId : null);
|
||||
$allResults = $this->domainModel->searchDomains($query, $isolationMode === 'isolated' ? $userId : null);
|
||||
$totalResults = count($allResults);
|
||||
|
||||
// Calculate pagination
|
||||
@@ -99,19 +99,7 @@ class SearchController extends Controller
|
||||
}
|
||||
|
||||
// Search existing domains (limit to 5 for quick results)
|
||||
$db = \Core\Database::getConnection();
|
||||
$sql = "SELECT d.id, d.domain_name, d.registrar, d.expiration_date, d.status, ng.name as group_name
|
||||
FROM domains d
|
||||
LEFT JOIN notification_groups ng ON d.notification_group_id = ng.id
|
||||
WHERE d.domain_name LIKE ?
|
||||
OR d.registrar LIKE ?
|
||||
ORDER BY d.domain_name ASC
|
||||
LIMIT 5";
|
||||
|
||||
$searchTerm = '%' . $query . '%';
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->execute([$searchTerm, $searchTerm]);
|
||||
$results = $stmt->fetchAll();
|
||||
$results = $this->domainModel->searchSuggestions($query, 5);
|
||||
|
||||
// Calculate days left for each domain
|
||||
foreach ($results as &$domain) {
|
||||
@@ -146,49 +134,6 @@ class SearchController extends Controller
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search domains in database
|
||||
*/
|
||||
private function searchDomains(string $query, ?int $userId = null): array
|
||||
{
|
||||
$db = \Core\Database::getConnection();
|
||||
$sql = "SELECT d.*, ng.name as group_name
|
||||
FROM domains d
|
||||
LEFT JOIN notification_groups ng ON d.notification_group_id = ng.id
|
||||
WHERE (d.domain_name LIKE ?
|
||||
OR d.registrar LIKE ?
|
||||
OR ng.name LIKE ?)";
|
||||
|
||||
$params = ['%' . $query . '%', '%' . $query . '%', '%' . $query . '%'];
|
||||
|
||||
if ($userId && !$this->isAdmin($userId)) {
|
||||
$sql .= " AND d.user_id = ?";
|
||||
$params[] = $userId;
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY d.domain_name ASC LIMIT 50";
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is admin
|
||||
*/
|
||||
private function isAdmin(?int $userId): bool
|
||||
{
|
||||
if (!$userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = \Core\Database::getConnection();
|
||||
$stmt = $db->prepare("SELECT role FROM users WHERE id = ?");
|
||||
$stmt->execute([$userId]);
|
||||
$user = $stmt->fetch();
|
||||
return $user && $user['role'] === 'admin';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string looks like a domain name
|
||||
|
||||
@@ -174,11 +174,7 @@ class SettingsController extends Controller
|
||||
|
||||
try {
|
||||
// Clear notification logs older than 30 days
|
||||
$stmt = $this->settingModel->db->prepare(
|
||||
"DELETE FROM notification_logs WHERE sent_at < DATE_SUB(NOW(), INTERVAL 30 DAY)"
|
||||
);
|
||||
$stmt->execute();
|
||||
$deleted = $stmt->rowCount();
|
||||
$deleted = $this->settingModel->clearOldNotificationLogs(30);
|
||||
|
||||
$_SESSION['success'] = "Cleared $deleted old notification log(s)";
|
||||
$this->redirect('/settings#maintenance');
|
||||
@@ -521,8 +517,8 @@ class SettingsController extends Controller
|
||||
try {
|
||||
if ($newMode === 'isolated') {
|
||||
// Check if we have any admin users
|
||||
$domainModel = new \App\Models\Domain();
|
||||
$adminUser = $domainModel->getFirstAdminUser();
|
||||
$userModel = new \App\Models\User();
|
||||
$adminUser = $userModel->getFirstAdminUser();
|
||||
if (!$adminUser) {
|
||||
$_SESSION['error'] = 'No admin users found. Please create an admin user first.';
|
||||
$this->redirect('/settings#isolation');
|
||||
@@ -559,8 +555,8 @@ class SettingsController extends Controller
|
||||
{
|
||||
try {
|
||||
// Get the first admin user
|
||||
$domainModel = new \App\Models\Domain();
|
||||
$adminUser = $domainModel->getFirstAdminUser();
|
||||
$userModel = new \App\Models\User();
|
||||
$adminUser = $userModel->getFirstAdminUser();
|
||||
|
||||
if (!$adminUser) {
|
||||
throw new \Exception('No admin user found. Please create an admin user first.');
|
||||
@@ -569,14 +565,12 @@ class SettingsController extends Controller
|
||||
$adminId = $adminUser['id'];
|
||||
|
||||
// Assign all domains to admin
|
||||
$domainStmt = $this->settingModel->db->prepare("UPDATE domains SET user_id = ? WHERE user_id IS NULL");
|
||||
$domainStmt->execute([$adminId]);
|
||||
$domainCount = $domainStmt->rowCount();
|
||||
$domainModel = new \App\Models\Domain();
|
||||
$domainCount = $domainModel->assignUnassignedDomainsToUser($adminId);
|
||||
|
||||
// Assign all groups to admin
|
||||
$groupStmt = $this->settingModel->db->prepare("UPDATE notification_groups SET user_id = ? WHERE user_id IS NULL");
|
||||
$groupStmt->execute([$adminId]);
|
||||
$groupCount = $groupStmt->rowCount();
|
||||
$groupModel = new \App\Models\NotificationGroup();
|
||||
$groupCount = $groupModel->assignUnassignedGroupsToUser($adminId);
|
||||
|
||||
// Set isolation mode
|
||||
$this->settingModel->setValue('user_isolation_mode', 'isolated');
|
||||
|
||||
@@ -320,7 +320,7 @@ class UserController extends Controller
|
||||
|
||||
// Prevent deleting the last admin
|
||||
if ($user['role'] === 'admin') {
|
||||
$allAdmins = $this->userModel->where('role', 'admin');
|
||||
$allAdmins = $this->userModel->getAllAdmins();
|
||||
if (count($allAdmins) <= 1) {
|
||||
$_SESSION['error'] = 'Cannot delete the last admin user';
|
||||
$this->redirect('/users');
|
||||
@@ -457,7 +457,7 @@ class UserController extends Controller
|
||||
// Prevent deleting if this is the last admin
|
||||
$user = $this->userModel->find((int)$userId);
|
||||
if ($user && $user['role'] === 'admin') {
|
||||
$allAdmins = $this->userModel->where('role', 'admin');
|
||||
$allAdmins = $this->userModel->getAllAdmins();
|
||||
if (count($allAdmins) <= 1) {
|
||||
continue; // Skip - can't delete last admin
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user