From d7cef28a86c2f2da2b10491f52b477debcaf223d Mon Sep 17 00:00:00 2001 From: herkulessi Date: Tue, 3 Oct 2023 23:24:39 +0200 Subject: [PATCH] Ignore permalink_prefix when serializing Markdown fixes vector-im/element-web/issues/26002 During serialization of messages, pills were wrongfully serialized to a URL starting with `permalink_prefix`. This is against the Spec (which mandates https://matrix.to/#/ links) and the resulting pills were not recognized as pills in other clients. Spec-Appendix concerning matrix.to links: https://spec.matrix.org/v1.8/appendices/#matrixto-navigation Signed-off-by: Lars Wickel --- src/editor/serialize.ts | 4 ++-- .../permalinks/ElementPermalinkConstructor.ts | 21 +++++++++++++------ src/utils/permalinks/PermalinkConstructor.ts | 8 +++---- src/utils/permalinks/Permalinks.ts | 12 +++++------ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 8391183a654..14cb413a140 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -37,7 +37,7 @@ export function mdSerialize(model: EditorModel): string { case Type.AtRoomPill: return html + part.text; case Type.RoomPill: { - const url = makeGenericPermalink(part.resourceId); + const url = makeGenericPermalink(part.resourceId, true); // Escape square brackets and backslashes // Here we use the resourceId for compatibility with non-rich text clients // See https://github.com/vector-im/element-web/issues/16660 @@ -45,7 +45,7 @@ export function mdSerialize(model: EditorModel): string { return html + `[${title}](${url})`; } case Type.UserPill: { - const url = makeGenericPermalink(part.resourceId); + const url = makeGenericPermalink(part.resourceId, true); // Escape square brackets and backslashes; convert newlines to HTML const title = part.text.replace(/[[\\\]]/g, (c) => "\\" + c).replace(/\n/g, "
"); return html + `[${title}](${url})`; diff --git a/src/utils/permalinks/ElementPermalinkConstructor.ts b/src/utils/permalinks/ElementPermalinkConstructor.ts index b75673dc1af..6956c8737c1 100644 --- a/src/utils/permalinks/ElementPermalinkConstructor.ts +++ b/src/utils/permalinks/ElementPermalinkConstructor.ts @@ -31,23 +31,32 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor { } } - public forEvent(roomId: string, eventId: string, serverCandidates: string[]): string { + public forEvent(roomId: string, eventId: string, serverCandidates: string[], ispill = false): string { + if(ispill) { + return `https://matrix.to/#/${roomId}/${eventId}${this.encodeServerCandidates(serverCandidates)}`; + } return `${this.elementUrl}/#/room/${roomId}/${eventId}${this.encodeServerCandidates(serverCandidates)}`; } - public forRoom(roomIdOrAlias: string, serverCandidates?: string[]): string { + public forRoom(roomIdOrAlias: string, serverCandidates?: string[], ispill = false): string { + if(ispill) { + return `https://matrix.to/#/${roomIdOrAlias}${this.encodeServerCandidates(serverCandidates)}`; + } return `${this.elementUrl}/#/room/${roomIdOrAlias}${this.encodeServerCandidates(serverCandidates)}`; } - public forUser(userId: string): string { + public forUser(userId: string, ispill = false): string { + if(ispill) { + return `https://matrix.to/#/${userId}`; + } return `${this.elementUrl}/#/user/${userId}`; } - public forEntity(entityId: string): string { + public forEntity(entityId: string, ispill = false): string { if (entityId[0] === "!" || entityId[0] === "#") { - return this.forRoom(entityId); + return this.forRoom(entityId, [], ispill); } else if (entityId[0] === "@") { - return this.forUser(entityId); + return this.forUser(entityId, ispill); } else throw new Error("Unrecognized entity"); } diff --git a/src/utils/permalinks/PermalinkConstructor.ts b/src/utils/permalinks/PermalinkConstructor.ts index 4248b97885e..a241d38ec80 100644 --- a/src/utils/permalinks/PermalinkConstructor.ts +++ b/src/utils/permalinks/PermalinkConstructor.ts @@ -19,19 +19,19 @@ limitations under the License. * TODO: Convert this to a real TypeScript interface */ export default class PermalinkConstructor { - public forEvent(roomId: string, eventId: string, serverCandidates: string[] = []): string { + public forEvent(roomId: string, eventId: string, serverCandidates: string[] = [], ispill = false): string { throw new Error("Not implemented"); } - public forRoom(roomIdOrAlias: string, serverCandidates: string[] = []): string { + public forRoom(roomIdOrAlias: string, serverCandidates: string[] = [], ispill = false): string { throw new Error("Not implemented"); } - public forUser(userId: string): string { + public forUser(userId: string, ispill = false): string { throw new Error("Not implemented"); } - public forEntity(entityId: string): string { + public forEntity(entityId: string, ispill = false): string { throw new Error("Not implemented"); } diff --git a/src/utils/permalinks/Permalinks.ts b/src/utils/permalinks/Permalinks.ts index 537494b26b6..0bdbd49428f 100644 --- a/src/utils/permalinks/Permalinks.ts +++ b/src/utils/permalinks/Permalinks.ts @@ -274,26 +274,26 @@ export class RoomPermalinkCreator { }; } -export function makeGenericPermalink(entityId: string): string { - return getPermalinkConstructor().forEntity(entityId); +export function makeGenericPermalink(entityId: string, ispill = false): string { + return getPermalinkConstructor().forEntity(entityId, ispill); } -export function makeUserPermalink(userId: string): string { +export function makeUserPermalink(userId: string, ispill = false): string { return getPermalinkConstructor().forUser(userId); } -export function makeRoomPermalink(matrixClient: MatrixClient, roomId: string): string { +export function makeRoomPermalink(matrixClient: MatrixClient, roomId: string, ispill = false): string { if (!roomId) { throw new Error("can't permalink a falsy roomId"); } // If the roomId isn't actually a room ID, don't try to list the servers. // Aliases are already routable, and don't need extra information. - if (roomId[0] !== "!") return getPermalinkConstructor().forRoom(roomId, []); + if (roomId[0] !== "!") return getPermalinkConstructor().forRoom(roomId, [], ispill); const room = matrixClient.getRoom(roomId); if (!room) { - return getPermalinkConstructor().forRoom(roomId, []); + return getPermalinkConstructor().forRoom(roomId, [], ispill); } const permalinkCreator = new RoomPermalinkCreator(room); permalinkCreator.load();