Use canUserAccessTicket() in clone_ticket.php; fix README bootstrap entry

- clone_ticket.php: replace custom visibility check with centralized canUserAccessTicket(); return 404 (not 403) for inaccessible tickets
- README.md: remove bootstrap.php from the API endpoints table (it's a shared include, not a public endpoint); correct its project structure description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 21:47:03 -04:00
parent 06b7a8f59b
commit a403e49537
2 changed files with 6 additions and 9 deletions

View File

@@ -225,7 +225,6 @@ Access all admin pages via the **Admin dropdown** in the dashboard header.
| `/api/saved_filters.php` | CRUD | Saved filter combinations | | `/api/saved_filters.php` | CRUD | Saved filter combinations |
| `/api/user_preferences.php` | GET/POST | User preferences | | `/api/user_preferences.php` | GET/POST | User preferences |
| `/api/audit_log.php` | GET | Audit log entries (admin) | | `/api/audit_log.php` | GET | Audit log entries (admin) |
| `/api/bootstrap.php` | GET | Bootstrap config/user data for front-end |
| `/api/health.php` | GET | Health check | | `/api/health.php` | GET | Health check |
## Project Structure ## Project Structure
@@ -236,7 +235,7 @@ tinker_tickets/
│ ├── add_comment.php # POST: Add comment │ ├── add_comment.php # POST: Add comment
│ ├── assign_ticket.php # POST: Assign ticket to user │ ├── assign_ticket.php # POST: Assign ticket to user
│ ├── audit_log.php # GET: Audit log entries (admin) │ ├── audit_log.php # GET: Audit log entries (admin)
│ ├── bootstrap.php # GET: Bootstrap data (config/user for front-end) │ ├── bootstrap.php # Shared auth/setup include (not a public endpoint)
│ ├── bulk_operation.php # POST: Bulk operations (admin only) │ ├── bulk_operation.php # POST: Bulk operations (admin only)
│ ├── check_duplicates.php # GET: Check for duplicate tickets │ ├── check_duplicates.php # GET: Check for duplicate tickets
│ ├── clone_ticket.php # POST: Clone an existing ticket │ ├── clone_ticket.php # POST: Clone an existing ticket

View File

@@ -74,13 +74,11 @@ try {
exit; exit;
} }
// Authorization: non-admins cannot clone internal tickets unless they created/are assigned // Verify the user can access this ticket using centralized visibility logic
if (!$isAdmin && ($sourceTicket['visibility'] ?? 'public') === 'internal') { if (!$ticketModel->canUserAccessTicket($sourceTicket, $_SESSION['user'])) {
if ($sourceTicket['created_by'] != $userId && $sourceTicket['assigned_to'] != $userId) { http_response_code(404);
http_response_code(403); echo json_encode(['success' => false, 'error' => 'Source ticket not found']);
echo json_encode(['success' => false, 'error' => 'Permission denied']); exit;
exit;
}
} }
// Prepare cloned ticket data // Prepare cloned ticket data