From ac7a0c0aa88a41834afac98d0ec6e522cd42a8c4 Mon Sep 17 00:00:00 2001 From: Hosteroid Date: Mon, 20 Oct 2025 21:08:09 +0300 Subject: [PATCH] Refactor routes and controllers for RESTful resource access Updated controllers and routes to use RESTful resource-based URLs and parameter passing for groups, users, and notification channels. Added user isolation checks for domain and group access, ensuring proper data filtering based on isolation mode. Adjusted views to match new route structure and improved security and maintainability by removing reliance on query parameters for resource identification. --- app/Controllers/DomainController.php | 92 ++++++++++-- .../NotificationGroupController.php | 131 +++++++++++++----- app/Controllers/SearchController.php | 7 +- app/Controllers/UserController.php | 28 ++-- app/Models/Domain.php | 51 +++++-- app/Models/NotificationGroup.php | 5 +- app/Views/groups/edit.php | 12 +- app/Views/groups/index.php | 8 +- app/Views/users/index.php | 6 +- routes/web.php | 20 +-- 10 files changed, 266 insertions(+), 94 deletions(-) diff --git a/app/Controllers/DomainController.php b/app/Controllers/DomainController.php index 50be45f..f3915bb 100644 --- a/app/Controllers/DomainController.php +++ b/app/Controllers/DomainController.php @@ -20,6 +20,22 @@ class DomainController extends Controller $this->whoisService = new WhoisService(); } + /** + * Check domain access based on isolation mode + */ + private function checkDomainAccess(int $id): ?array + { + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + + if ($isolationMode === 'isolated') { + return $this->domainModel->findWithIsolation($id, $userId); + } else { + return $this->domainModel->find($id); + } + } + public function index() { // Get current user and isolation mode @@ -221,7 +237,7 @@ class DomainController extends Controller public function edit($params = []) { $id = $params['id'] ?? 0; - $domain = $this->domainModel->find($id); + $domain = $this->checkDomainAccess($id); if (!$domain) { $_SESSION['error'] = 'Domain not found'; @@ -258,7 +274,7 @@ class DomainController extends Controller $this->verifyCsrf('/domains'); $id = (int)($params['id'] ?? 0); - $domain = $this->domainModel->find($id); + $domain = $this->checkDomainAccess($id); if (!$domain) { $_SESSION['error'] = 'Domain not found'; @@ -269,7 +285,6 @@ class DomainController extends Controller $groupId = !empty($_POST['notification_group_id']) ? (int)$_POST['notification_group_id'] : null; $isActive = isset($_POST['is_active']) ? 1 : 0; $tagsInput = trim($_POST['tags'] ?? ''); - $userId = \Core\Auth::id(); // Validate tags $tagValidation = \App\Helpers\InputValidator::validateTags($tagsInput); @@ -350,7 +365,7 @@ class DomainController extends Controller public function refresh($params = []) { $id = $params['id'] ?? 0; - $domain = $this->domainModel->find($id); + $domain = $this->checkDomainAccess($id); if (!$domain) { $_SESSION['error'] = 'Domain not found'; @@ -402,7 +417,7 @@ class DomainController extends Controller public function delete($params = []) { $id = $params['id'] ?? 0; - $domain = $this->domainModel->find($id); + $domain = $this->checkDomainAccess($id); if (!$domain) { $_SESSION['error'] = 'Domain not found'; @@ -418,7 +433,18 @@ class DomainController extends Controller public function show($params = []) { $id = $params['id'] ?? 0; - $domain = $this->domainModel->getWithChannels($id); + + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + + // Check domain access based on isolation mode + if ($isolationMode === 'isolated') { + $domain = $this->domainModel->getWithChannels($id, $userId); + } else { + $domain = $this->domainModel->getWithChannels($id); + } if (!$domain) { $_SESSION['error'] = 'Domain not found'; @@ -618,11 +644,21 @@ class DomainController extends Controller return; } + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + $refreshed = 0; $failed = 0; foreach ($domainIds as $id) { - $domain = $this->domainModel->find($id); + // Check domain access based on isolation mode + if ($isolationMode === 'isolated') { + $domain = $this->domainModel->findWithIsolation($id, $userId); + } else { + $domain = $this->domainModel->find($id); + } if (!$domain) continue; $whoisData = $this->whoisService->getDomainInfo($domain['domain_name']); @@ -770,9 +806,21 @@ class DomainController extends Controller return; } + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + $updated = 0; foreach ($domainIds as $id) { - if ($this->domainModel->update($id, ['is_active' => $isActive])) { + // Check domain access based on isolation mode + if ($isolationMode === 'isolated') { + $domain = $this->domainModel->findWithIsolation($id, $userId); + } else { + $domain = $this->domainModel->find($id); + } + + if ($domain && $this->domainModel->update($id, ['is_active' => $isActive])) { $updated++; } } @@ -793,7 +841,7 @@ class DomainController extends Controller $this->verifyCsrf('/domains'); $id = (int)($params['id'] ?? 0); - $domain = $this->domainModel->find($id); + $domain = $this->checkDomainAccess($id); if (!$domain) { $_SESSION['error'] = 'Domain not found'; @@ -845,9 +893,19 @@ class DomainController extends Controller return; } + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + $updated = 0; foreach ($domainIds as $id) { - $domain = $this->domainModel->find($id); + // Check domain access based on isolation mode + if ($isolationMode === 'isolated') { + $domain = $this->domainModel->findWithIsolation($id, $userId); + } else { + $domain = $this->domainModel->find($id); + } if (!$domain) continue; // Get existing tags @@ -886,9 +944,21 @@ class DomainController extends Controller return; } + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + $updated = 0; foreach ($domainIds as $id) { - if ($this->domainModel->update($id, ['tags' => ''])) { + // Check domain access based on isolation mode + if ($isolationMode === 'isolated') { + $domain = $this->domainModel->findWithIsolation($id, $userId); + } else { + $domain = $this->domainModel->find($id); + } + + if ($domain && $this->domainModel->update($id, ['tags' => ''])) { $updated++; } } diff --git a/app/Controllers/NotificationGroupController.php b/app/Controllers/NotificationGroupController.php index d3e9938..067979d 100644 --- a/app/Controllers/NotificationGroupController.php +++ b/app/Controllers/NotificationGroupController.php @@ -17,6 +17,22 @@ class NotificationGroupController extends Controller $this->channelModel = new NotificationChannel(); } + /** + * Check group access based on isolation mode + */ + private function checkGroupAccess(int $id): ?array + { + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + + if ($isolationMode === 'isolated') { + return $this->groupModel->getWithDetails($id, $userId); + } else { + return $this->groupModel->getWithDetails($id); + } + } + public function index() { // Get current user and isolation mode @@ -114,7 +130,7 @@ class NotificationGroupController extends Controller ]); $_SESSION['success'] = "Group '$name' created successfully"; - $this->redirect("/groups/edit?id=$id"); + $this->redirect("/groups/$id/edit"); } catch (\Exception $e) { // Log the error using the ErrorHandler service $errorHandler = new \App\Services\ErrorHandler(); @@ -125,10 +141,10 @@ class NotificationGroupController extends Controller } } - public function edit() + public function edit($params = []) { - $id = (int)($_GET['id'] ?? 0); - $group = $this->groupModel->getWithDetails($id); + $id = $params['id'] ?? 0; + $group = $this->checkGroupAccess($id); if (!$group) { $_SESSION['error'] = 'Group not found'; @@ -142,7 +158,7 @@ class NotificationGroupController extends Controller ]); } - public function update() + public function update($params = []) { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->redirect('/groups'); @@ -152,13 +168,21 @@ class NotificationGroupController extends Controller // CSRF Protection $this->verifyCsrf('/groups'); - $id = (int)$_POST['id']; + $id = $params['id'] ?? 0; + $group = $this->checkGroupAccess($id); + + if (!$group) { + $_SESSION['error'] = 'Group not found'; + $this->redirect('/groups'); + return; + } + $name = trim($_POST['name'] ?? ''); $description = trim($_POST['description'] ?? ''); if (empty($name)) { $_SESSION['error'] = 'Group name is required'; - $this->redirect("/groups/edit?id=$id"); + $this->redirect("/groups/$id/edit"); return; } @@ -166,14 +190,14 @@ class NotificationGroupController extends Controller $nameError = \App\Helpers\InputValidator::validateLength($name, 255, 'Group name'); if ($nameError) { $_SESSION['error'] = $nameError; - $this->redirect("/groups/edit?id=$id"); + $this->redirect("/groups/$id/edit"); return; } $descError = \App\Helpers\InputValidator::validateLength($description, 1000, 'Description'); if ($descError) { $_SESSION['error'] = $descError; - $this->redirect("/groups/edit?id=$id"); + $this->redirect("/groups/$id/edit"); return; } @@ -192,21 +216,21 @@ class NotificationGroupController extends Controller ]); $_SESSION['success'] = 'Group updated successfully'; - $this->redirect("/groups/edit?id=$id"); + $this->redirect("/groups/$id/edit"); } catch (\Exception $e) { // Log the error using the ErrorHandler service $errorHandler = new \App\Services\ErrorHandler(); $errorHandler->handleException($e); $_SESSION['error'] = 'Failed to update notification group. Please try again.'; - $this->redirect("/groups/edit?id=$id"); + $this->redirect("/groups/$id/edit"); } } - public function delete() + public function delete($params = []) { - $id = (int)($_GET['id'] ?? 0); - $group = $this->groupModel->find($id); + $id = $params['id'] ?? 0; + $group = $this->checkGroupAccess($id); if (!$group) { $_SESSION['error'] = 'Group not found'; @@ -236,7 +260,7 @@ class NotificationGroupController extends Controller } } - public function addChannel() + public function addChannel($params = []) { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->redirect('/groups'); @@ -246,13 +270,22 @@ class NotificationGroupController extends Controller // CSRF Protection $this->verifyCsrf('/groups'); - $groupId = (int)$_POST['group_id']; + $groupId = $params['group_id'] ?? 0; + + // Check group access + $group = $this->checkGroupAccess($groupId); + if (!$group) { + $_SESSION['error'] = 'Group not found'; + $this->redirect('/groups'); + return; + } + $channelType = $_POST['channel_type'] ?? ''; // Validate channel type if (empty($channelType)) { $_SESSION['error'] = 'Please select a channel type'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); return; } @@ -275,59 +308,75 @@ class NotificationGroupController extends Controller } $_SESSION['error'] = "Invalid channel configuration: Missing {$missingField}"; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); return; } try { $this->channelModel->createChannel($groupId, $channelType, $config); $_SESSION['success'] = 'Channel added successfully'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } catch (\Exception $e) { // Log the error using the ErrorHandler service $errorHandler = new \App\Services\ErrorHandler(); $errorHandler->handleException($e); $_SESSION['error'] = 'Failed to add notification channel. Please try again.'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } } - public function deleteChannel() + public function deleteChannel($params = []) { - $id = (int)($_GET['id'] ?? 0); - $groupId = (int)($_GET['group_id'] ?? 0); + $id = $params['id'] ?? 0; + $groupId = $params['group_id'] ?? 0; + + // Check group access + $group = $this->checkGroupAccess($groupId); + if (!$group) { + $_SESSION['error'] = 'Group not found'; + $this->redirect('/groups'); + return; + } try { $this->channelModel->delete($id); $_SESSION['success'] = 'Channel deleted successfully'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } catch (\Exception $e) { // Log the error using the ErrorHandler service $errorHandler = new \App\Services\ErrorHandler(); $errorHandler->handleException($e); $_SESSION['error'] = 'Failed to delete notification channel. Please try again.'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } } - public function toggleChannel() + public function toggleChannel($params = []) { - $id = (int)($_GET['id'] ?? 0); - $groupId = (int)($_GET['group_id'] ?? 0); + $id = $params['id'] ?? 0; + $groupId = $params['group_id'] ?? 0; + + // Check group access + $group = $this->checkGroupAccess($groupId); + if (!$group) { + $_SESSION['error'] = 'Group not found'; + $this->redirect('/groups'); + return; + } try { $this->channelModel->toggleActive($id); $_SESSION['success'] = 'Channel status updated'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } catch (\Exception $e) { // Log the error using the ErrorHandler service $errorHandler = new \App\Services\ErrorHandler(); $errorHandler->handleException($e); $_SESSION['error'] = 'Failed to update channel status. Please try again.'; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } } @@ -355,7 +404,7 @@ class NotificationGroupController extends Controller } else { $_SESSION['error'] = 'Invalid channel configuration for testing'; $groupId = $_POST['group_id'] ?? 0; - $this->redirect($groupId ? "/groups/edit?id=$groupId" : '/groups'); + $this->redirect($groupId ? "/groups/$groupId/edit" : '/groups'); return; } } @@ -404,7 +453,7 @@ class NotificationGroupController extends Controller // Only redirect if not AJAX if (!$isAjax) { $groupId = $_POST['group_id'] ?? 0; - $this->redirect("/groups/edit?id=$groupId"); + $this->redirect("/groups/$groupId/edit"); } } @@ -520,13 +569,27 @@ class NotificationGroupController extends Controller return; } + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + $deletedCount = 0; $errors = []; foreach ($groupIds as $groupId) { try { - $this->groupModel->deleteWithRelations((int)$groupId); - $deletedCount++; + // Check group access based on isolation mode + if ($isolationMode === 'isolated') { + $group = $this->groupModel->getWithDetails((int)$groupId, $userId); + } else { + $group = $this->groupModel->getWithDetails((int)$groupId); + } + + if ($group) { + $this->groupModel->deleteWithRelations((int)$groupId); + $deletedCount++; + } } catch (\Exception $e) { // Log individual errors but continue processing $errorHandler = new \App\Services\ErrorHandler(); diff --git a/app/Controllers/SearchController.php b/app/Controllers/SearchController.php index a73b766..c0e1fe2 100644 --- a/app/Controllers/SearchController.php +++ b/app/Controllers/SearchController.php @@ -98,8 +98,13 @@ class SearchController extends Controller exit; } + // Get current user and isolation mode + $userId = \Core\Auth::id(); + $settingModel = new \App\Models\Setting(); + $isolationMode = $settingModel->getValue('user_isolation_mode', 'shared'); + // Search existing domains (limit to 5 for quick results) - $results = $this->domainModel->searchSuggestions($query, 5); + $results = $this->domainModel->searchSuggestions($query, 5, $isolationMode === 'isolated' ? $userId : null); // Calculate days left for each domain foreach ($results as &$domain) { diff --git a/app/Controllers/UserController.php b/app/Controllers/UserController.php index 2bfb495..3fa3bf8 100644 --- a/app/Controllers/UserController.php +++ b/app/Controllers/UserController.php @@ -194,9 +194,9 @@ class UserController extends Controller /** * Show edit user form */ - public function edit() + public function edit($params = []) { - $userId = (int)($_GET['id'] ?? 0); + $userId = $params['id'] ?? 0; $user = $this->userModel->find($userId); if (!$user) { @@ -214,7 +214,7 @@ class UserController extends Controller /** * Update user */ - public function update() + public function update($params = []) { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->redirect('/users'); @@ -224,7 +224,7 @@ class UserController extends Controller // CSRF Protection $this->verifyCsrf('/users'); - $userId = (int)($_POST['id'] ?? 0); + $userId = $params['id'] ?? 0; $user = $this->userModel->find($userId); if (!$user) { @@ -242,13 +242,13 @@ class UserController extends Controller // Validation if (empty($email) || empty($fullName)) { $_SESSION['error'] = 'Email and full name are required'; - $this->redirect('/users/edit?id=' . $userId); + $this->redirect("/users/$userId/edit"); return; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $_SESSION['error'] = 'Invalid email address'; - $this->redirect('/users/edit?id=' . $userId); + $this->redirect("/users/$userId/edit"); return; } @@ -256,7 +256,7 @@ class UserController extends Controller $nameError = \App\Helpers\InputValidator::validateLength($fullName, 255, 'Full name'); if ($nameError) { $_SESSION['error'] = $nameError; - $this->redirect('/users/edit?id=' . $userId); + $this->redirect("/users/$userId/edit"); return; } @@ -264,7 +264,7 @@ class UserController extends Controller $existingUsers = $this->userModel->where('email', $email); if (!empty($existingUsers) && $existingUsers[0]['id'] != $userId) { $_SESSION['error'] = 'Email already in use by another user'; - $this->redirect('/users/edit?id=' . $userId); + $this->redirect("/users/$userId/edit"); return; } @@ -282,7 +282,7 @@ class UserController extends Controller if (!empty($password)) { if (strlen($password) < 8) { $_SESSION['error'] = 'Password must be at least 8 characters'; - $this->redirect('/users/edit?id=' . $userId); + $this->redirect("/users/$userId/edit"); return; } $this->userModel->changePassword($userId, $password); @@ -293,16 +293,16 @@ class UserController extends Controller } catch (\Exception $e) { $_SESSION['error'] = 'Failed to update user: ' . $e->getMessage(); - $this->redirect('/users/edit?id=' . $userId); + $this->redirect("/users/$userId/edit"); } } /** * Delete user */ - public function delete() + public function delete($params = []) { - $userId = (int)($_GET['id'] ?? 0); + $userId = $params['id'] ?? 0; $user = $this->userModel->find($userId); if (!$user) { @@ -342,9 +342,9 @@ class UserController extends Controller /** * Toggle user active status */ - public function toggleStatus() + public function toggleStatus($params = []) { - $userId = (int)($_GET['id'] ?? 0); + $userId = $params['id'] ?? 0; $user = $this->userModel->find($userId); if (!$user) { diff --git a/app/Models/Domain.php b/app/Models/Domain.php index d519087..f6c4e53 100644 --- a/app/Models/Domain.php +++ b/app/Models/Domain.php @@ -91,15 +91,22 @@ class Domain extends Model /** * Get domain with notification channels */ - public function getWithChannels(int $id): ?array + public function getWithChannels(int $id, ?int $userId = null): ?array { $sql = "SELECT d.*, ng.name as group_name, ng.id as group_id FROM domains d LEFT JOIN notification_groups ng ON d.notification_group_id = ng.id WHERE d.id = ?"; + + $params = [$id]; + + if ($userId) { + $sql .= " AND d.user_id = ?"; + $params[] = $userId; + } $stmt = $this->db->prepare($sql); - $stmt->execute([$id]); + $stmt->execute($params); $domain = $stmt->fetch(); if (!$domain) { @@ -117,6 +124,25 @@ class Domain extends Model return $domain; } + /** + * Find domain by ID with user isolation support + */ + public function findWithIsolation(int $id, ?int $userId = null): ?array + { + $sql = "SELECT * FROM domains WHERE id = ?"; + $params = [$id]; + + if ($userId) { + $sql .= " AND user_id = ?"; + $params[] = $userId; + } + + $stmt = $this->db->prepare($sql); + $stmt->execute($params); + $result = $stmt->fetch(); + return $result ?: null; + } + /** * Check if domain exists */ @@ -362,19 +388,26 @@ class Domain extends Model /** * Search domains for suggestions (quick search) */ - public function searchSuggestions(string $query, int $limit = 5): array + public function searchSuggestions(string $query, int $limit = 5, ?int $userId = null): array { $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 ?"; + WHERE (d.domain_name LIKE ? + OR d.registrar LIKE ?)"; + + $params = ['%' . $query . '%', '%' . $query . '%']; + + if ($userId) { + $sql .= " AND d.user_id = ?"; + $params[] = $userId; + } + + $sql .= " ORDER BY d.domain_name ASC LIMIT ?"; + $params[] = $limit; - $searchTerm = '%' . $query . '%'; $stmt = $this->db->prepare($sql); - $stmt->execute([$searchTerm, $searchTerm, $limit]); + $stmt->execute($params); return $stmt->fetchAll(); } diff --git a/app/Models/NotificationGroup.php b/app/Models/NotificationGroup.php index 9403e62..57124be 100644 --- a/app/Models/NotificationGroup.php +++ b/app/Models/NotificationGroup.php @@ -63,7 +63,10 @@ class NotificationGroup extends Model // Get domains (filtered by user if needed) $domainModel = new Domain(); if ($userId) { - $group['domains'] = $domainModel->where('notification_group_id', $id, $userId); + $sql = "SELECT * FROM domains WHERE notification_group_id = ? AND user_id = ?"; + $stmt = $this->db->prepare($sql); + $stmt->execute([$id, $userId]); + $group['domains'] = $stmt->fetchAll(); } else { $group['domains'] = $domainModel->where('notification_group_id', $id); } diff --git a/app/Views/groups/edit.php b/app/Views/groups/edit.php index 424e2d3..3a5aa3d 100644 --- a/app/Views/groups/edit.php +++ b/app/Views/groups/edit.php @@ -17,9 +17,8 @@ ob_start();
-
+ -
@@ -112,12 +111,12 @@ ob_start(); Test - - @@ -136,9 +135,8 @@ ob_start(); Add New Channel - + -
@@ -388,7 +386,7 @@ function toggleChannelFields() { } // Form validation before submit -const addChannelForm = document.querySelector('form[action="/channels/add"]'); +const addChannelForm = document.querySelector('form[action="/groups//channels"]'); if (addChannelForm) { addChannelForm.addEventListener('submit', function(e) { const channelType = document.getElementById('channel_type').value; diff --git a/app/Views/groups/index.php b/app/Views/groups/index.php index dfd50be..49d82d5 100644 --- a/app/Views/groups/index.php +++ b/app/Views/groups/index.php @@ -110,7 +110,7 @@ ob_start();
- + @@ -120,7 +120,7 @@ ob_start(); - @@ -162,10 +162,10 @@ ob_start();
- + Manage - Delete diff --git a/app/Views/users/index.php b/app/Views/users/index.php index 530f19f..22f3977 100644 --- a/app/Views/users/index.php +++ b/app/Views/users/index.php @@ -258,16 +258,16 @@ $pagination = $pagination ?? [
- + - - diff --git a/routes/web.php b/routes/web.php index c5ae5fd..87479c7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -84,17 +84,17 @@ $router->post('/domains/{id}/delete', [DomainController::class, 'delete']); $router->get('/groups', [NotificationGroupController::class, 'index']); $router->get('/groups/create', [NotificationGroupController::class, 'create']); $router->post('/groups/store', [NotificationGroupController::class, 'store']); -$router->get('/groups/edit', [NotificationGroupController::class, 'edit']); -$router->post('/groups/update', [NotificationGroupController::class, 'update']); -$router->get('/groups/delete', [NotificationGroupController::class, 'delete']); +$router->get('/groups/{id}/edit', [NotificationGroupController::class, 'edit']); +$router->post('/groups/{id}/update', [NotificationGroupController::class, 'update']); +$router->post('/groups/{id}/delete', [NotificationGroupController::class, 'delete']); $router->post('/groups/bulk-delete', [NotificationGroupController::class, 'bulkDelete']); $router->post('/groups/transfer', [NotificationGroupController::class, 'transfer']); $router->post('/groups/bulk-transfer', [NotificationGroupController::class, 'bulkTransfer']); // Notification Channels -$router->post('/channels/add', [NotificationGroupController::class, 'addChannel']); -$router->get('/channels/delete', [NotificationGroupController::class, 'deleteChannel']); -$router->get('/channels/toggle', [NotificationGroupController::class, 'toggleChannel']); +$router->post('/groups/{group_id}/channels', [NotificationGroupController::class, 'addChannel']); +$router->post('/groups/{group_id}/channels/{id}/delete', [NotificationGroupController::class, 'deleteChannel']); +$router->post('/groups/{group_id}/channels/{id}/toggle', [NotificationGroupController::class, 'toggleChannel']); $router->post('/channels/test', [NotificationGroupController::class, 'testChannel']); // TLD Registry @@ -155,10 +155,10 @@ $router->get('/api/notifications/recent', [NotificationController::class, 'getRe $router->get('/users', [UserController::class, 'index']); $router->get('/users/create', [UserController::class, 'create']); $router->post('/users/store', [UserController::class, 'store']); -$router->get('/users/edit', [UserController::class, 'edit']); -$router->post('/users/update', [UserController::class, 'update']); -$router->get('/users/delete', [UserController::class, 'delete']); -$router->get('/users/toggle-status', [UserController::class, 'toggleStatus']); +$router->get('/users/{id}/edit', [UserController::class, 'edit']); +$router->post('/users/{id}/update', [UserController::class, 'update']); +$router->post('/users/{id}/delete', [UserController::class, 'delete']); +$router->post('/users/{id}/toggle-status', [UserController::class, 'toggleStatus']); $router->post('/users/bulk-toggle-status', [UserController::class, 'bulkToggleStatus']); $router->post('/users/bulk-delete', [UserController::class, 'bulkDelete']);