Portal ticket access
Customers can submit, view, and reply to tickets through the client portal. Internal notes are never visible to portal users.
For customers
When the Helpdesk module is active, a Tickets link appears in the portal navigation. Customers can:
View their tickets: a list of all tickets associated with their contact record or company
Submit new tickets: with subject, description, and priority
Reply to tickets: add public replies to open tickets
Track status: see the current status and reply count
Portal users see only public replies. Internal notes added by staff are excluded from the portal view.
Company-scoped access
If a portal contact belongs to a company, they can see all tickets for that company, not just their own. This is useful for account managers who need visibility across their organisation's support requests.
Hiding tickets from the portal
If you want to offer the portal without ticket access, add tickets to the hidden navigation items in Settings > Portal > Hidden nav items.
Ticket creation from the portal
When a customer submits a ticket through the portal, the ticket is created with:
created_viaset to "portal"contact_idlinked to the authenticated portal contactcompany_idlinked to the contact's company (if applicable)Default priority of "medium" unless the customer selects otherwise
The ticket is automatically assigned to the default queue and its default assignee, following the same routing logic as web-created tickets.
Rich-text replies
Reply boxes on the customer portal now support rich text (bold, italic, lists, links, code, blockquotes, headings (H2/H3/H4)) through the same Tiptap editor staff use. Type a reply, format it, hit Send.
Customer-submitted HTML is sanitised on the server with HTMLPurifier using the strict ticket_reply profile before persistence. Allowed elements: p, br, strong, em, b, i, u, s, ul/ol/li, blockquote, code, pre, h2/h3/h4, a (with href, title, rel, target only). Stripped on the way in: <script>, <style>, <iframe>, <object>, <embed>, <form>, <img>, every event handler (onclick/onerror/…), javascript: URLs, AND inline style attributes / class attributes / CSS properties: no formatting overrides, no tracking-pixel surface, no remote-resource leak. Every link is force-rewritten with rel="nofollow noopener noreferrer" and target="_blank".
Plain-text replies still work: older portal clients (mobile, legacy webview) can keep submitting a plain body and the server treats it as the canonical text. The plain-text body column is derived from the sanitised HTML when only the rich form is submitted, so timeline rendering and email notifications always have a clean text fallback.
The trust posture differs from staff replies (where the author is an authenticated employee) because customers are external. We also closed an NBSP-only bypass: <p> </p> no longer slips past the empty-content check.