workign comments strucuture

This commit is contained in:
Mark Gregory
2026-06-17 10:09:42 +01:00
parent 878f383f7a
commit fe05ef8104
13 changed files with 575 additions and 104 deletions
@@ -9,6 +9,7 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Modules\Helpdesk\Models\CannedResponse;
use Modules\Helpdesk\Models\Ticket;
@@ -56,6 +57,8 @@ final class TicketCommentStoreController extends Controller
$body = trim($renderer->render($response->body, $ticket, $user));
}
$body = $this->normaliseHtmlBody($body);
validator(['commentBody' => $body], [
'commentBody' => ['required', 'string', 'min:2'],
])->validate();
@@ -67,7 +70,7 @@ final class TicketCommentStoreController extends Controller
ticket: $ticket,
user: $user,
body: $body,
internal: (bool) ($validated['internal'] ?? false),
internal: (bool) ($validated['internal'] ?? false) && $this->userCanCreateInternalNote($user),
files: $uploadedFiles,
parentId: filled($validated['parent_id'] ?? null) ? (int) $validated['parent_id'] : null,
);
@@ -76,4 +79,31 @@ final class TicketCommentStoreController extends Controller
->route('helpdesk.tickets.show', $ticket)
->with('ticket-comment-added', filled($validated['parent_id'] ?? null) ? 'Reply posted.' : 'Comment posted.');
}
/**
* Keep supported formatting tags but strip scripts and unsafe inline handlers.
*/
private function normaliseHtmlBody(string $body): string
{
$body = preg_replace('/<\s*(script|style)[^>]*>.*?<\s*\/\s*\1\s*>/is', '', $body) ?: '';
$body = preg_replace('/\s+on[a-z]+\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $body) ?: '';
$body = preg_replace('/javascript\s*:/i', '', $body) ?: '';
return trim(strip_tags($body, '<p><br><strong><b><em><i><u><ul><ol><li><blockquote><pre><code><a>'));
}
/**
* Internal notes are restricted to MPBA/core-company users.
*/
private function userCanCreateInternalNote(mixed $user): bool
{
$company = $user?->company;
if ($company === null) {
return false;
}
return (bool) ($company->is_system_company ?? false)
|| Str::lower((string) ($company->slug ?? '')) === 'mpba-limited'
|| Str::contains(Str::lower((string) ($company->name ?? '')), 'mpba');
}
}