Skip to content

Commit 2e5d91a

Browse files
committed
chore(share): fix escape in reference link and handling of attachment links
1 parent ae184ab commit 2e5d91a

File tree

2 files changed

+97
-26
lines changed

2 files changed

+97
-26
lines changed

apps/server/src/share/content_renderer.spec.ts

Lines changed: 92 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,6 @@ describe("content_renderer", () => {
3535
expect(result.content).toStrictEqual(content);
3636
});
3737

38-
it("handles attachment link", () => {
39-
const content = trimIndentation`\
40-
<h1>Test</h1>
41-
<p>
42-
<a class="reference-link" href="#root/iwTmeWnqBG5Q?viewMode=attachments&amp;attachmentId=q14s2Id7V6pp">
43-
5863845791835102555.mp4
44-
</a>
45-
&nbsp;
46-
</p>
47-
`;
48-
const note = buildShareNote({
49-
content,
50-
attachments: [ { id: "q14s2Id7V6pp", title: "5863845791835102555.mp4" } ]
51-
});
52-
const result = getContent(note);
53-
expect(result.content).toStrictEqual(trimIndentation`\
54-
<h1>Test</h1>
55-
<p>
56-
<a class="reference-link attachment-link role-file" href="api/attachments/q14s2Id7V6pp/download">5863845791835102555.mp4</a>
57-
&nbsp;
58-
</p>
59-
`);
60-
});
61-
6238
it("renders included notes", () => {
6339
buildShareNotes([
6440
{ id: "subnote1", content: `<p>Foo</p><div>Bar</div>` },
@@ -110,6 +86,98 @@ describe("content_renderer", () => {
11086
</pre>
11187
`)
11288
});
89+
90+
describe("Reference links", () => {
91+
it("handles attachment link", () => {
92+
const content = trimIndentation`\
93+
<h1>Test</h1>
94+
<p>
95+
<a class="reference-link" href="#root/iwTmeWnqBG5Q?viewMode=attachments&amp;attachmentId=q14s2Id7V6pp">
96+
5863845791835102555.mp4
97+
</a>
98+
&nbsp;
99+
</p>
100+
`;
101+
const note = buildShareNote({
102+
content,
103+
attachments: [ { id: "q14s2Id7V6pp", title: "5863845791835102555.mp4" } ]
104+
});
105+
const result = getContent(note);
106+
expect(result.content).toStrictEqual(trimIndentation`\
107+
<h1>Test</h1>
108+
<p>
109+
<a class="reference-link attachment-link role-file" href="api/attachments/q14s2Id7V6pp/download">5863845791835102555.mp4</a>
110+
&nbsp;
111+
</p>
112+
`);
113+
});
114+
115+
it("handles protected notes", () => {
116+
buildShareNote({
117+
id: "MSkxxCFbBsYP",
118+
title: "Foo",
119+
isProtected: true
120+
});
121+
const note = buildShareNote({
122+
id: "note",
123+
content: trimIndentation`\
124+
<p>
125+
<a class="reference-link" href="#root/zaIItd4TM5Ly/MSkxxCFbBsYP">
126+
Foo
127+
</a>
128+
</p>
129+
`
130+
});
131+
const result = getContent(note);
132+
expect(result.content).toStrictEqual(trimIndentation`\
133+
<p>
134+
<a class="reference-link type-text" href="./MSkxxCFbBsYP">[protected]</a>
135+
</p>
136+
`);
137+
});
138+
139+
it("handles missing notes", () => {
140+
const note = buildShareNote({
141+
id: "note",
142+
content: trimIndentation`\
143+
<p>
144+
<a class="reference-link" href="#root/zaIItd4TM5Ly/AsKxyCFbBsYp">
145+
Foo
146+
</a>
147+
</p>
148+
`
149+
});
150+
const result = getContent(note);
151+
expect(result.content).toStrictEqual(trimIndentation`\
152+
<p>
153+
<a class="reference-link">[missing note]</a>
154+
</p>
155+
`);
156+
});
157+
158+
it("properly escapes note title", () => {
159+
buildShareNote({
160+
id: "MSkxxCFbBsYP",
161+
title: "The quick <strong>brown</strong> fox"
162+
});
163+
const note = buildShareNote({
164+
id: "note",
165+
content: trimIndentation`\
166+
<p>
167+
<a class="reference-link" href="#root/zaIItd4TM5Ly/MSkxxCFbBsYP">
168+
Hi
169+
</a>
170+
</p>
171+
`
172+
});
173+
const result = getContent(note);
174+
expect(result.content).toStrictEqual(trimIndentation`\
175+
<p>
176+
<a class="reference-link type-text" href="./MSkxxCFbBsYP"><span><span class="bx bx-note"></span>The quick &lt;strong&gt;brown&lt;/strong&gt; fox</span></a>
177+
</p>
178+
`);
179+
});
180+
});
113181
});
114182

115183
describe("renderCode", () => {

apps/server/src/share/content_renderer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,14 +394,17 @@ function handleAttachmentLink(linkEl: HTMLElement, href: string, getNote: (id: s
394394
*/
395395
function cleanUpReferenceLinks(linkEl: HTMLElement) {
396396
// Note: this method is basically a reimplementation of getReferenceLinkTitleSync from the link service of the client.
397-
const noteId = linkEl.getAttribute("href")?.split("/").at(-1);
397+
const href = linkEl.getAttribute("href") ?? "";
398+
if (linkEl.classList.contains("attachment-link")) return;
399+
400+
const noteId = href.split("/").at(-1);
398401
const note = noteId ? shaca.getNote(noteId) : undefined;
399402
if (!note) {
400403
linkEl.innerHTML = "[missing note]";
401404
} else if (note.isProtected) {
402405
linkEl.innerHTML = "[protected]";
403406
} else {
404-
linkEl.innerHTML = `<span><span class="${note.getIcon()}"></span>${note.title}</span>`;
407+
linkEl.innerHTML = `<span><span class="${note.getIcon()}"></span>${utils.escapeHtml(note.title)}</span>`;
405408
}
406409
}
407410

0 commit comments

Comments
 (0)