Fix JS SyntaxError breaking tabs, textarea scrolling, and XSS escaping
Bug fixes: - ticket.js: Remove duplicate const textarea declaration inside showMentionSuggestions() (was redeclaring a parameter, causing SyntaxError that broke all tab switching) - ticket.css: Add overflow:hidden + resize:none to disabled textarea so description shows full height without internal scrollbar (page scrolls instead) - ticket.js: Trigger height recalculation when entering edit mode on description XSS/escaping fixes: - TicketView.php: htmlspecialchars() on description textarea content (closes </textarea> injection risk) - TicketView.php: htmlspecialchars() on ticket status and workflow transition status strings - DashboardView.php: htmlspecialchars() on $cat/$type in input value= attributes - RecurringTicketsView.php: htmlspecialchars() on composed schedule string Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -584,6 +584,8 @@ textarea.editable {
|
|||||||
background: var(--bg-secondary);
|
background: var(--bg-secondary);
|
||||||
cursor: default;
|
cursor: default;
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
|
overflow: hidden;
|
||||||
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Button Styles */
|
/* Button Styles */
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ function toggleEditMode() {
|
|||||||
// Enable description (textarea)
|
// Enable description (textarea)
|
||||||
if (descriptionField) {
|
if (descriptionField) {
|
||||||
descriptionField.disabled = false;
|
descriptionField.disabled = false;
|
||||||
|
descriptionField.style.height = 'auto';
|
||||||
|
descriptionField.style.height = descriptionField.scrollHeight + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable metadata fields (priority, category, type)
|
// Enable metadata fields (priority, category, type)
|
||||||
@@ -1036,7 +1038,6 @@ function showMentionSuggestions(query, textarea) {
|
|||||||
|
|
||||||
mentionAutocomplete.innerHTML = html;
|
mentionAutocomplete.innerHTML = html;
|
||||||
mentionAutocomplete.classList.add('active');
|
mentionAutocomplete.classList.add('active');
|
||||||
const textarea = document.getElementById('newComment');
|
|
||||||
if (textarea) textarea.setAttribute('aria-expanded', 'true');
|
if (textarea) textarea.setAttribute('aria-expanded', 'true');
|
||||||
selectedMentionIndex = 0;
|
selectedMentionIndex = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
|
|||||||
<label>
|
<label>
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
name="category"
|
name="category"
|
||||||
value="<?php echo $cat; ?>"
|
value="<?php echo htmlspecialchars($cat); ?>"
|
||||||
<?php echo in_array($cat, $currentCategories) ? 'checked' : ''; ?>>
|
<?php echo in_array($cat, $currentCategories) ? 'checked' : ''; ?>>
|
||||||
<?php echo htmlspecialchars($cat); ?>
|
<?php echo htmlspecialchars($cat); ?>
|
||||||
</label>
|
</label>
|
||||||
@@ -161,7 +161,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
|
|||||||
<label>
|
<label>
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
name="type"
|
name="type"
|
||||||
value="<?php echo $type; ?>"
|
value="<?php echo htmlspecialchars($type); ?>"
|
||||||
<?php echo in_array($type, $currentTypes) ? 'checked' : ''; ?>>
|
<?php echo in_array($type, $currentTypes) ? 'checked' : ''; ?>>
|
||||||
<?php echo htmlspecialchars($type); ?>
|
<?php echo htmlspecialchars($type); ?>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -246,14 +246,14 @@ $nonce = SecurityHeadersMiddleware::getNonce();
|
|||||||
<div class="header-controls">
|
<div class="header-controls">
|
||||||
<div class="status-priority-group">
|
<div class="status-priority-group">
|
||||||
<select id="statusSelect" class="editable status-select status-<?php echo str_replace(' ', '-', strtolower($ticket["status"])); ?>" data-field="status" data-action="update-ticket-status" aria-label="Change ticket status">
|
<select id="statusSelect" class="editable status-select status-<?php echo str_replace(' ', '-', strtolower($ticket["status"])); ?>" data-field="status" data-action="update-ticket-status" aria-label="Change ticket status">
|
||||||
<option value="<?php echo $ticket['status']; ?>" selected>
|
<option value="<?php echo htmlspecialchars($ticket['status']); ?>" selected>
|
||||||
<?php echo $ticket['status']; ?> (current)
|
<?php echo htmlspecialchars($ticket['status']); ?> (current)
|
||||||
</option>
|
</option>
|
||||||
<?php foreach ($allowedTransitions as $transition): ?>
|
<?php foreach ($allowedTransitions as $transition): ?>
|
||||||
<option value="<?php echo $transition['to_status']; ?>"
|
<option value="<?php echo htmlspecialchars($transition['to_status']); ?>"
|
||||||
data-requires-comment="<?php echo $transition['requires_comment'] ? '1' : '0'; ?>"
|
data-requires-comment="<?php echo $transition['requires_comment'] ? '1' : '0'; ?>"
|
||||||
data-requires-admin="<?php echo $transition['requires_admin'] ? '1' : '0'; ?>">
|
data-requires-admin="<?php echo $transition['requires_admin'] ? '1' : '0'; ?>">
|
||||||
<?php echo $transition['to_status']; ?>
|
<?php echo htmlspecialchars($transition['to_status']); ?>
|
||||||
<?php if ($transition['requires_comment']): ?> *<?php endif; ?>
|
<?php if ($transition['requires_comment']): ?> *<?php endif; ?>
|
||||||
<?php if ($transition['requires_admin']): ?> (Admin)<?php endif; ?>
|
<?php if ($transition['requires_admin']): ?> (Admin)<?php endif; ?>
|
||||||
</option>
|
</option>
|
||||||
@@ -295,7 +295,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
|
|||||||
<div class="ascii-subsection-header">Description</div>
|
<div class="ascii-subsection-header">Description</div>
|
||||||
<div class="detail-group full-width">
|
<div class="detail-group full-width">
|
||||||
<label>Description</label>
|
<label>Description</label>
|
||||||
<textarea class="editable" data-field="description" disabled><?php echo $ticket["description"]; ?></textarea>
|
<textarea class="editable" data-field="description" disabled><?php echo htmlspecialchars($ticket["description"] ?? ''); ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
|
|||||||
$schedule .= ' (Day ' . $rt['schedule_day'] . ')';
|
$schedule .= ' (Day ' . $rt['schedule_day'] . ')';
|
||||||
}
|
}
|
||||||
$schedule .= ' @ ' . substr($rt['schedule_time'], 0, 5);
|
$schedule .= ' @ ' . substr($rt['schedule_time'], 0, 5);
|
||||||
echo $schedule;
|
echo htmlspecialchars($schedule);
|
||||||
?>
|
?>
|
||||||
</td>
|
</td>
|
||||||
<td><?php echo htmlspecialchars($rt['category']); ?></td>
|
<td><?php echo htmlspecialchars($rt['category']); ?></td>
|
||||||
|
|||||||
Reference in New Issue
Block a user