Commit Graph

10 Commits

Author SHA1 Message Date
27075a62ee Fix bracket buttons rendering below text + UI/security improvements
CSS fixes:
- Fix [ ] brackets appearing below button text by replacing display:inline-flex
  with display:inline-block + white-space:nowrap on .btn — removes cross-browser
  flex pseudo-element inconsistency as root cause
- Remove conflicting .btn::before ripple block (position:absolute was overriding
  bracket content positioning)
- Remove overflow:hidden from .btn which was clipping bracket content
- Fix body::after duplicate rule causing GPU layer blink (second position:fixed
  rule re-created compositor layer, overriding display:none suppression)
- Replace all transition:all with scoped property transitions in dashboard.css,
  ticket.css, base.css (prevents full CSS property evaluation on every hover)
- Convert pulse-warning/pulse-critical keyframes from box-shadow to opacity
  animation (GPU-composited, eliminates CPU repaints at 60fps)
- Fix mobile *::before/*::after blanket content:none rule — now targets only
  decorative frame glyphs, preserving button brackets and status indicators
- Remove --terminal-green-dim override that broke .lt-btn hover backgrounds

JS fixes:
- Fix all lt.lt.toast.* double-prefix instances in dashboard.js
- Add null guard before .appendChild() on bulkAssignUser select
- Replace all remaining emoji with terminal bracket notation (dashboard.js,
  ticket.js, markdown.js)
- Migrate all toast.*() shim calls to lt.toast.* across all JS files

View fixes:
- Remove hardcoded [ ] brackets from .btn buttons (CSS now adds them)
- Replace all emoji with terminal bracket notation in all views and admin views
- Add missing CSP nonces to AuditLogView.php and UserActivityView.php script tags
- Bump CSS version strings to ?v=20260319b for cache busting

Security fixes:
- update_ticket.php: add authorization check (non-admins can only edit their own
  or assigned tickets)
- add_comment.php: validate and cast ticket_id to integer with 400 response
- clone_ticket.php: fix unconditional session_start(), add ticket ID validation,
  add internal ticket access check
- bulk_operation.php: add HTTP 401/403 status codes on auth failures
- upload_attachment.php: fix missing $conn arg in AttachmentModel constructor
- assign_ticket.php: add ticket existence check and permission verification

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:20:43 -04:00
4a838b68ca Move base.js/base.css into assets to fix auth proxy 404
/web_template/ path was being intercepted by the auth proxy at
t.lotusguild.org returning HTML instead of the actual files. Moving
base.js and base.css into /assets/js/ and /assets/css/ where static
assets are already served correctly. Updated all 10 view files and
deploy.sh accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 23:44:46 -04:00
8bb43c14db Guard lt.* calls when base.js unavailable to prevent crash
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>
2026-03-17 23:34:59 -04:00
89a685a502 Integrate web_template design system and fix security/quality issues
Security fixes:
- Add HTTP method validation to delete_comment.php (block CSRF via GET)
- Remove $_GET fallback in comment deletion (was CSRF bypass vector)
- Guard session_start() with session_status() check across API files
- Escape json_encode() data attributes with htmlspecialchars in views
- Escape inline APP_TIMEZONE config values in DashboardView/TicketView
- Validate timezone param against DateTimeZone::listIdentifiers() in index.php
- Remove Database::escape() (was using real_escape_string, not safe)
- Fix AttachmentModel hardcoded connection; inject via constructor

Backend fixes:
- Fix CommentModel bind_param type for ticket_id (s→i)
- Fix buildCommentThread orphan parent guard
- Fix StatsModel JOIN→LEFT JOIN so unassigned tickets aren't excluded
- Add ticket ID validation in BulkOperationsModel before implode()
- Add duplicate key retry in TicketModel::createTicket() for race conditions
- Wrap SavedFiltersModel default filter changes in transactions
- Add null result guards in WorkflowModel query methods

Frontend JS:
- Rewrite toast.js as lt.toast shim (base.js dependency)
- Delegate escapeHtml() to lt.escHtml()
- Rewrite keyboard-shortcuts.js using lt.keys.on()
- Migrate settings.js to lt.api.* and lt.modal.open/close()
- Migrate advanced-search.js to lt.api.* and lt.modal.open/close()
- Migrate dashboard.js fetch calls to lt.api.*; update all dynamic
  modals (bulk ops, quick actions, confirm/input) to lt-modal structure
- Migrate ticket.js fetchMentionUsers to lt.api.get()
- Remove console.log/error/warn calls from JS files

Views:
- Add /web_template/base.css and base.js to all 10 view files
- Call lt.keys.initDefaults() in DashboardView, TicketView, admin views
- Migrate all modal HTML from settings-modal/settings-content to
  lt-modal-overlay/lt-modal/lt-modal-header/lt-modal-body/lt-modal-footer
- Replace style="display:none" with aria-hidden="true" on all modals
- Replace modal open/close style.display with lt.modal.open/close()
- Update modal buttons to lt-btn lt-btn-primary/lt-btn-ghost classes
- Remove manual ESC keydown handlers (replaced by lt.keys.initDefaults)
- Fix unescaped timezone values in TicketView inline script

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 23:22:24 -04:00
c3f7593f3c Harden CSP by removing unsafe-inline for scripts
Refactored all inline event handlers (onclick, onchange, onsubmit) to use
addEventListener with data-action attributes and event delegation pattern.

Changes:
- views/*.php: Replaced inline handlers with data-action attributes
- views/admin/*.php: Same refactoring for all admin views
- assets/js/dashboard.js: Added event delegation for bulk/quick action modals
- assets/js/ticket.js: Added event delegation for dynamic elements
- assets/js/markdown.js: Refactored toolbar button handlers
- assets/js/keyboard-shortcuts.js: Refactored modal close button
- SecurityHeadersMiddleware.php: Enabled strict CSP with nonces

The CSP now uses script-src 'self' 'nonce-{nonce}' instead of 'unsafe-inline',
significantly improving XSS protection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:15:55 -05:00
fa40010287 Security hardening and performance improvements
- Add visibility check to attachment downloads (prevents unauthorized access)
- Fix ticket ID collision with uniqueness verification loop
- Harden CSP: replace unsafe-inline with nonce-based script execution
- Add IP-based rate limiting (supplements session-based)
- Add visibility checks to bulk operations
- Validate internal visibility requires groups
- Optimize user activity query (JOINs vs subqueries)
- Update documentation with design decisions and security info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 20:27:15 -05:00
a08390a500 added close modal keybinds for admin menu 2026-01-26 11:41:33 -05:00
2be85b6f58 Fix admin form layout - add compact setting-row class for grid layouts
- Added .setting-row-compact class for stacked label/input layout
- Updated TemplatesView.php grid to use compact rows (3 columns)
- Updated RecurringTicketsView.php grid to use compact rows (2 columns)
- Removed inline style="width: 100%" (handled by CSS now)
- Labels now stack above inputs in grid context for clarity
- Updated cache version to 20260126b

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 11:30:46 -05:00
0046721fde feat: Add admin navigation, fix modals, clickable stats, update docs
- Add admin dropdown menu in dashboard header with links to all admin pages
- Fix template modal: larger size (800px), responsive grid, type/priority dropdowns
- Fix recurring tickets modal: add Type and Assign To fields, larger size
- Make dashboard stat cards clickable for quick filtering
- Fix user-activity query (remove is_active requirement)
- Add table existence check in ticket_dependencies API
- Fix table overflow on dashboard
- Update Claude.md and README.md with current project status
- Remove migrations directory (all migrations completed)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 21:11:49 -05:00
be505b7312 Implement comprehensive improvement plan (Phases 1-6)
Security (Phase 1-2):
- Add SecurityHeadersMiddleware with CSP, X-Frame-Options, etc.
- Add RateLimitMiddleware for API rate limiting
- Add security event logging to AuditLogModel
- Add ResponseHelper for standardized API responses
- Update config.php with security constants

Database (Phase 3):
- Add migration 014 for additional indexes
- Add migration 015 for ticket dependencies
- Add migration 016 for ticket attachments
- Add migration 017 for recurring tickets
- Add migration 018 for custom fields

Features (Phase 4-5):
- Add ticket dependencies with DependencyModel and API
- Add duplicate detection with check_duplicates API
- Add file attachments with AttachmentModel and upload/download APIs
- Add @mentions with autocomplete and highlighting
- Add quick actions on dashboard rows

Collaboration (Phase 5):
- Add mention extraction in CommentModel
- Add mention autocomplete dropdown in ticket.js
- Add mention highlighting CSS styles

Admin & Export (Phase 6):
- Add StatsModel for dashboard widgets
- Add dashboard stats cards (open, critical, unassigned, etc.)
- Add CSV/JSON export via export_tickets API
- Add rich text editor toolbar in markdown.js
- Add RecurringTicketModel with cron job
- Add CustomFieldModel for per-category fields
- Add admin views: RecurringTickets, CustomFields, Workflow,
  Templates, AuditLog, UserActivity
- Add admin APIs: manage_workflows, manage_templates,
  manage_recurring, custom_fields, get_users
- Add admin routes in index.php

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:55:01 -05:00