fix(fusion_helpdesk): render message bodies as HTML, not escaped text
The OWL dialog used <t t-out="m.body"/> on message bodies, but t-out escapes plain strings — it only renders raw when the value is a Markup instance. Bodies arrive over JSON-RPC as plain strings (Markup is a client-side type, doesn't cross the wire), so the customer was seeing literal "<p>This has been fixed.</p>" in the thread instead of the rendered HTML. Wrap incoming bodies in `markup()` at the boundary (openTicket + sendReply call sites) so the template renders them as the sanitised HTML the central chatter already produced. Trust is fine — the body is sanitised server-side by mail.thread before it ever leaves nexa. Bumps fusion_helpdesk to 19.0.1.7.1.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
{
|
||||
'name': 'Fusion Helpdesk Reporter',
|
||||
'version': '19.0.1.7.0',
|
||||
'version': '19.0.1.7.1',
|
||||
'category': 'Productivity',
|
||||
'summary': 'One-click in-app bug reporting & feature requesting — '
|
||||
'auto-creates a helpdesk.ticket on a central Odoo Helpdesk.',
|
||||
|
||||
@@ -11,13 +11,25 @@
|
||||
// Tickets are NOT copied locally — every list/thread/reply is a live call
|
||||
// to the central Helpdesk, scoped server-side to the logged-in user.
|
||||
|
||||
import { Component, useState, onWillStart } from "@odoo/owl";
|
||||
import { Component, markup, useState, onWillStart } from "@odoo/owl";
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
import { rpc } from "@web/core/network/rpc";
|
||||
import { user } from "@web/core/user";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
// Wrap message bodies in `markup()` so the OWL template's `t-out` renders them
|
||||
// as HTML instead of escaping `<p>…</p>` literally. Bodies come from central as
|
||||
// plain JSON strings (Markup doesn't survive JSON-RPC) but are already sanitised
|
||||
// server-side by Odoo's mail.thread, so we trust them. Mutates the list in place
|
||||
// because that's what the existing call sites assign straight to state.
|
||||
function _markupBodies(messages) {
|
||||
for (const m of messages || []) {
|
||||
m.body = markup(m.body || "");
|
||||
}
|
||||
return messages || [];
|
||||
}
|
||||
|
||||
const MAX_BYTES_PER_FILE = 10 * 1024 * 1024; // 10 MB hard cap per file
|
||||
|
||||
export class FusionHelpdeskDialog extends Component {
|
||||
@@ -193,6 +205,7 @@ export class FusionHelpdeskDialog extends Component {
|
||||
this.state.threadError = res.message || _t("Could not open this ticket.");
|
||||
return;
|
||||
}
|
||||
_markupBodies(res.ticket.messages);
|
||||
this.state.current = res.ticket;
|
||||
this.state.tab = "thread";
|
||||
// The ticket is now seen server-side; clear its unread flag locally.
|
||||
@@ -227,7 +240,7 @@ export class FusionHelpdeskDialog extends Component {
|
||||
if (!res.ok) {
|
||||
this.state.threadError = res.message || _t("Could not send your reply.");
|
||||
} else {
|
||||
this.state.current.messages = res.messages || this.state.current.messages;
|
||||
this.state.current.messages = _markupBodies(res.messages) || this.state.current.messages;
|
||||
this.state.replyBody = "";
|
||||
this.notification.add(_t("Reply sent."), { type: "success" });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user