Fix visibility enforcement and register missing API routes

Security fixes:
- add_comment.php: verify canUserAccessTicket() before allowing comment creation
- assign_ticket.php: use canUserAccessTicket() to prevent info leakage via 403 vs 404
- check_duplicates.php: apply getVisibilityFilter() so confidential ticket titles are not exposed in duplicate search results
- ticket_dependencies.php: verify ticket access on GET before returning dependency data

Route registration:
- Register 7 previously missing API endpoints in index.php: custom_fields, saved_filters, audit_log, user_preferences, download_attachment, clone_ticket, health

Frontend:
- ticket.js: fill empty catch block and empty else block in addComment() with proper error toasts

Documentation:
- README.md: document all API endpoints and update project structure listing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 21:39:02 -04:00
parent ce95e555d5
commit 164c2d231a
7 changed files with 90 additions and 6 deletions

View File

@@ -67,6 +67,7 @@ require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/helpers/Database.php';
require_once dirname(__DIR__) . '/models/DependencyModel.php';
require_once dirname(__DIR__) . '/models/AuditLogModel.php';
require_once dirname(__DIR__) . '/models/TicketModel.php';
require_once dirname(__DIR__) . '/helpers/ResponseHelper.php';
header('Content-Type: application/json');
@@ -77,6 +78,7 @@ if (!isset($_SESSION['user']) || !isset($_SESSION['user']['user_id'])) {
}
$userId = $_SESSION['user']['user_id'];
$currentUser = $_SESSION['user'];
// CSRF Protection for POST/DELETE
if ($_SERVER['REQUEST_METHOD'] === 'POST' || $_SERVER['REQUEST_METHOD'] === 'DELETE') {
@@ -99,6 +101,7 @@ if ($tableCheck->num_rows === 0) {
try {
$dependencyModel = new DependencyModel($conn);
$auditLog = new AuditLogModel($conn);
$ticketModel = new TicketModel($conn);
} catch (Exception $e) {
error_log('Failed to initialize models in ticket_dependencies.php: ' . $e->getMessage());
ResponseHelper::serverError('Failed to initialize required components');
@@ -116,6 +119,12 @@ switch ($method) {
ResponseHelper::error('Ticket ID required');
}
// Verify user can access this ticket
$ticket = $ticketModel->getTicketById((int)$ticketId);
if (!$ticket || !$ticketModel->canUserAccessTicket($ticket, $currentUser)) {
ResponseHelper::notFound('Ticket not found');
}
try {
$dependencies = $dependencyModel->getDependencies($ticketId);
$dependents = $dependencyModel->getDependentTickets($ticketId);