Improved sanitization of href's in editor
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
export default function isUrl(text: string) {
|
||||
if (text.match(/\n/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = new URL(text);
|
||||
return url.hostname !== "";
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import { EditorState, Plugin } from "prosemirror-state";
|
||||
import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
import * as React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { isExternalUrl } from "../../utils/urls";
|
||||
import { isExternalUrl, sanitizeHref } from "../../utils/urls";
|
||||
import findLinkNodes from "../queries/findLinkNodes";
|
||||
import { EventType, Dispatch } from "../types";
|
||||
import Mark from "./Mark";
|
||||
@@ -80,6 +80,7 @@ export default class Link extends Mark {
|
||||
"a",
|
||||
{
|
||||
...node.attrs,
|
||||
href: sanitizeHref(node.attrs.href),
|
||||
rel: "noopener noreferrer nofollow",
|
||||
},
|
||||
0,
|
||||
@@ -196,18 +197,25 @@ export default class Link extends Mark {
|
||||
? event.target.parentNode.href
|
||||
: "");
|
||||
|
||||
const isHashtag = href.startsWith("#");
|
||||
if (isHashtag && this.options.onClickHashtag) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.options.onClickHashtag(href, event);
|
||||
try {
|
||||
const isHashtag = href.startsWith("#");
|
||||
if (isHashtag && this.options.onClickHashtag) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.options.onClickHashtag(href, event);
|
||||
}
|
||||
|
||||
if (this.options.onClickLink) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.options.onClickLink(href, event);
|
||||
}
|
||||
} catch (err) {
|
||||
this.editor.props.onShowToast(
|
||||
this.options.dictionary.openLinkError
|
||||
);
|
||||
}
|
||||
|
||||
if (this.options.onClickLink) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.options.onClickLink(href, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { NodeSpec, NodeType, Node as ProsemirrorNode } from "prosemirror-model";
|
||||
import * as React from "react";
|
||||
import { Trans } from "react-i18next";
|
||||
import { bytesToHumanReadable } from "../../utils/files";
|
||||
import { sanitizeHref } from "../../utils/urls";
|
||||
import toggleWrap from "../commands/toggleWrap";
|
||||
import FileExtension from "../components/FileExtension";
|
||||
import Widget from "../components/Widget";
|
||||
@@ -56,7 +57,7 @@ export default class Attachment extends Node {
|
||||
{
|
||||
class: `attachment`,
|
||||
id: node.attrs.id,
|
||||
href: node.attrs.href,
|
||||
href: sanitizeHref(node.attrs.href),
|
||||
download: node.attrs.title,
|
||||
"data-size": node.attrs.size,
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import Token from "markdown-it/lib/token";
|
||||
import { NodeSpec, NodeType, Node as ProsemirrorNode } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import * as React from "react";
|
||||
import { sanitizeHref } from "../../utils/urls";
|
||||
import DisabledEmbed from "../components/DisabledEmbed";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
import embedsRule from "../rules/embeds";
|
||||
@@ -47,7 +48,11 @@ export default class Embed extends Node {
|
||||
],
|
||||
toDOM: (node) => [
|
||||
"iframe",
|
||||
{ class: "embed", src: node.attrs.href, contentEditable: "false" },
|
||||
{
|
||||
class: "embed",
|
||||
src: sanitizeHref(node.attrs.href),
|
||||
contentEditable: "false",
|
||||
},
|
||||
0,
|
||||
],
|
||||
toPlainText: (node) => node.attrs.href,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { toggleMark } from "prosemirror-commands";
|
||||
import { Plugin } from "prosemirror-state";
|
||||
import { isInTable } from "prosemirror-tables";
|
||||
import { isUrl } from "../../utils/urls";
|
||||
import Extension from "../lib/Extension";
|
||||
import isMarkdown from "../lib/isMarkdown";
|
||||
import isUrl from "../lib/isUrl";
|
||||
import selectionIsInCode from "../queries/isInCode";
|
||||
import { LANGUAGES } from "./Prism";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user