Skip to content

Issue 103 Share With Requester Reached Nobody

Ed Mozley edited this page Aug 25, 2026 · 2 revisions

"Share with Requester" did less than it said (issue #103)

Ticking Share this with the requester on a note made the Attach button vanish with no explanation, and then delivered the note somewhere the requester might never look. Afterwards there was no way to tell, reading the ticket back, which notes had been shared and which had not.

Reported in issue #103 by dschipfel, who described all three and suggested how Zammad handles the last one.

Fixed across 1a48443a…b1103311, released as updates #1201, #1202, #1203 and #1204.

Only one of the three was a bug in the ordinary sense. The other two were things FreeITSM had decided not to do, without ever saying so β€” which is its own kind of fault.


1. What you saw

Add a note. Tick Share this with the requester. The Attach button under Files disappears. Nothing says why.

Write the note and save it. It appears in the ticket history looking exactly like every other note. The requester does not get an email. Come back a week later and nothing on screen tells you whether that note was private or not.


2. The Attach button β€” a rule with no explanation

This one was deliberate. Note attachments arrived knowing the self-service portal had no way to serve a document, so a shared note carrying a file would have promised the requester something they never received. Rather than let that happen, the button hid itself.

The reason was even written down, in a hint beside the button. But:

// before
if (hint) hint.style.display = (isShared && pendingNoteFiles.length) ? '' : 'none';

The explanation only appeared if you had already chosen a file. Tick Share first β€” which is the natural order, since you decide who it is for before you decide what goes on it β€” and the button vanished in silence.

A control that disappears without saying why is indistinguishable from one that is broken. The report is filed under "bug" for exactly that reason, and fairly.

It is not hidden any more at all

Rather than explain the restriction better, the restriction is gone. api/self-service/get_document.php now serves a shared note's files to the requester who raised the ticket, so Attach stays put whether or not the note is shared.

The rule that keeps an internal note's files private is one join, not a separate check:

documents β†’ document_links (parent_type='ticket_note')
          β†’ ticket_notes  (is_internal = 0)
          β†’ tickets       (user_id = this requester)

Internal files are therefore unreachable by construction, rather than by a condition somebody could later reorder or forget.

And when a file IS refused, it now says why

Attaching a file can still fail β€” a .txt whose contents are program code, for instance, which the upload guard refuses deliberately. The message named the file and stopped there, leaving you to guess whether the upload broke, the file was too large, or something about it was not allowed.

The server had said exactly what was wrong all along; the message threw the reason away before showing it. assets/js/documents.js collects it per file, and the shared documents panel in the same file displays it β€” the note path was the copy that dropped it.

That matters more than an ordinary unhelpful message. A note has no per-note file controls, so the file cannot be attached afterwards and the note cannot be un-saved. That one message is the only chance to explain.


3. "The note is not sent" β€” it was never sent

Also by design, and also never said out loud.

A shared note appears in the self-service portal. It is not emailed. For a requester who signs into the portal that is fine; for one who only ever emails you β€” which is most of them, on most service desks β€” "Share with the requester" reached nobody at all.

The word share reads as send. The reporter read it that way, and so would anyone.

Three things changed:

The hint now says where it goes.

They will see it, and any files you attach, in the self-service portal. It is not emailed β€” use Reply for that.

It can email, if you want it to. Tickets β†’ Settings β†’ Email templates gained a trigger, Note shared with requester. Write a template against it and every shared note emails the requester. Nothing is sent until you write one, so no existing installation starts emailing customers because of an upgrade.

The template decides how much it says. Include the new [note_text] merge code and the mail carries the note; leave it out and it says there is an update and points at [ticket_url]. That is what stops it duplicating Reply.

Why the trigger is not called "Note added"

Because it must never fire for an internal note, and a name that says "added" implies it fires for all of them. Requiring an administrator to know a hidden rule in order to predict what a setting does is the same failure as the vanishing button β€” and it is what caused this report in the first place. It is called Note shared with requester, which is what fires it.


4. No way to tell them apart afterwards

The third complaint, and the one with no defence at all: a ticket mixing private remarks with customer-facing ones could not be audited after the fact.

Every note now carries a label β€” Internal, or Visible to requester β€” and a shared note takes a green edge down its side.

is_internal had been returned by the API, and cast to a proper boolean, the whole time. The renderer simply never looked at it.

Both are labelled, not just the unusual one

If only shared notes were marked, then no label would have to mean internal by implication. That puts weight on an absence β€” and any note kind added later would silently inherit the meaning. A tracker-imported note gets no visibility label, because it is not ours to describe as either.

Not the red border

The reporter suggested copying Zammad, which paints internal notes red. FreeITSM does not, for two reasons:

  • Internal is the default and the majority here. A note is internal unless somebody deliberately says otherwise, so colouring the majority red makes an ordinary ticket history read as a wall of alarms.
  • Red is this design's colour for things that are wrong. A colleague writing a private remark is not one of them.

So the eye goes to the consequential, unusual state instead β€” this one left the building. That also reuses the signal .note-item already establishes, where the left border says what kind of note something is, rather than inventing a second visual language for the same question.


5. πŸ“ The files involved

✏️ The labels (#1201)

File
assets/js/inbox.js renderNotes() reads is_internal; the Attach explanation always shows while the restriction still existed
assets/css/inbox.css .note-item-shared, .note-visibility
lang/*/tickets.php note_visibility.* in all 24 languages

✏️ Files on shared notes (#1202)

File
api/self-service/get_document.php new β€” the portal twin
api/self-service/get_ticket_detail.php lists a shared note's documents
self-service/tickets.php renders them, plus a safeExternalUrl() the portal did not have
assets/js/inbox.js Attach no longer hides; saveNote() no longer offers to discard files

✏️ Saying why an attachment was refused (#1204)

File
assets/js/inbox.js the toast now carries the server's reason, not just the filename
File
api/tickets/save_email_template.php note_shared in the whitelist
includes/services/tickets.php the guarded send
includes/template_email.php see the escaping fix
tickets/settings/index.php the option, in all three places the trigger list appears

6. How it was verified

The labels, on a real ticket carrying one internal and one shared note side by side: correct label, correct class and correct border on each β€” checked in both themes. The first attempt at that check flipped data-theme-mode, which is not the attribute theme.css keys off, so light and dark returned identical values and it would have passed regardless. Redone against data-theme: contrast 5.04 and 6.49 in light, 6.21 and 9.79 in dark.

The portal endpoint, over HTTP as a real portal user, with a positive control so a blanket 404 could not pass as security β€” see the table in the developer guide.

The trigger: off before configured, found once configured, the guard structurally outermost, and a note containing a tag, an ampersand, a quote and a newline escaped exactly once.


7. What this means for you

Attach files to a note whether or not you share it β€” the requester gets them.

Reading a ticket back, every note says who could see it.

And if your requesters live in email rather than the portal, add a template under Tickets β†’ Settings β†’ Email templates against Note shared with requester, and sharing a note will reach them.


Related pages

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally