Wraps all lt.keys.initDefaults() calls in `if (window.lt)` guards across
6 view files. Adds `if (!window.lt) return` bail-out in keyboard-shortcuts.js
and `if (window.lt)` guard in settings.js DOMContentLoaded handler.
This prevents TypeError crashes when /web_template/base.js returns 404,
which was causing the admin menu click delegation to never register.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Security:
- Fix IDOR in delete/update comment (add ticket visibility check)
- XSS defense-in-depth in DashboardView active filters
- Replace innerHTML with DOM construction in toast.js
- Remove redundant real_escape_string in check_duplicates
- Add rate limiting to get_template, download_attachment, audit_log,
saved_filters, user_preferences endpoints
Bug fixes:
- Session timeout now reads from config instead of hardcoded 18000
- TicketController uses $GLOBALS['config'] instead of duplicate .env parsing
- Add DISCORD_WEBHOOK_URL to centralized config
- Cleanup script uses hashmap for O(1) ticket ID lookups
Dead code removal (~100 lines):
- Remove dead getTicketComments() from TicketModel (wrong bind_param type)
- Remove dead getCategories()/getTypes() from DashboardController
- Remove ~80 lines dead Discord webhook code from update_ticket API
Consolidation:
- Create api/bootstrap.php for shared API setup (auth, CSRF, rate limit)
- Convert 6 API endpoints to use bootstrap
- Extract escapeHtml/getTicketIdFromUrl into shared utils.js
- Batch save for user preferences (1 request instead of 7)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add comment threading/reply functionality with nested display
- Database migration for parent_comment_id and thread_depth columns
- Recursive comment rendering with depth-based indentation
- Reply form with inline UI and smooth animations
- Thread collapse/expand capability
- Max thread depth of 3 levels
- Fix 401 authentication errors on API calls
- Add credentials: 'same-origin' to all fetch calls
- Affects settings.js, ticket.js, dashboard.js, advanced-search.js
- Ensures session cookies are sent with requests
- Enhanced comment styling
- Thread connector lines for visual hierarchy
- Reply button on comments (up to depth 3)
- Quote block styling for replies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix fatal PHP error in UserModel::getAllGroups() - typo 'setCache'
should be 'setCached', was causing ticket page to fail to render
- Fix settings.js null reference errors when timezone element missing
on ticket page (only exists on dashboard)
- Fix ESC key detection for settings modal (checked 'block' but modal
uses 'flex' display)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add timezone dropdown to settings modal with common timezones
- Save/load timezone preference per user
- Apply user's timezone preference after authentication
- Override system default with user preference if set
- Make dashboard logo clickable (returns to default filters)
- Show current timezone in settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Security improvements across all JavaScript files:
CSRF Protection:
- assets/js/ticket.js - Added X-CSRF-Token header to 5 fetch calls
(update_ticket.php x3, add_comment.php, assign_ticket.php)
- assets/js/dashboard.js - Added X-CSRF-Token to 8 fetch calls
(update_ticket.php x2, bulk_operation.php x6)
- assets/js/settings.js - Added X-CSRF-Token to user preferences save
- assets/js/advanced-search.js - Added X-CSRF-Token to filter save/delete
XSS Prevention:
- assets/js/ticket.js:183-209 - Replaced insertAdjacentHTML() with safe
DOM API (createElement/textContent) to prevent script injection in
comment rendering. User-supplied data (user_name, created_at) now
auto-escaped via textContent.
All state-changing operations now include CSRF token validation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>