diff --git a/.changeset/chilly-spoons-wash.md b/.changeset/chilly-spoons-wash.md new file mode 100644 index 00000000..3622a29b --- /dev/null +++ b/.changeset/chilly-spoons-wash.md @@ -0,0 +1,5 @@ +--- +"draupnir": patch +--- + +Make Room IDs in prompts issued by the ban command into matrix.to links diff --git a/apps/draupnir/src/commands/Ban.tsx b/apps/draupnir/src/commands/Ban.tsx index 8808c9da..ee733656 100644 --- a/apps/draupnir/src/commands/Ban.tsx +++ b/apps/draupnir/src/commands/Ban.tsx @@ -1,4 +1,5 @@ // Copyright 2022 - 2025 Gnuxie +// SPDX-FileCopyrightText: 2026 Catalan Lover // Copyright 2019 - 2021 The Matrix.org Foundation C.I.C. // // SPDX-License-Identifier: Apache-2.0 @@ -25,7 +26,6 @@ import { } from "@the-draupnir-project/matrix-basic-types"; import { BasicInvocationInformation, - MatrixRoomIDPresentationType, MatrixRoomReferencePresentationSchema, MatrixUserIDPresentationType, StringPresentationType, @@ -37,6 +37,7 @@ import { DraupnirContextToCommandContextTranslator, DraupnirInterfaceAdaptor, } from "./DraupnirCommandPrerequisites"; +import { matrixToPermalinkFromClientUser } from "../utils"; import { ResultError } from "@gnuxie/typescript-result"; export async function findPolicyRoomEditorFromRoomReference( @@ -85,7 +86,14 @@ export const DraupnirBanCommand = describeCommand({ return Ok({ suggestions: policyRoomManager .getEditablePolicyRoomIDs(clientUserID, PolicyRuleType.User) - .map((room) => MatrixRoomIDPresentationType.wrap(room)), + .map((room) => + StringPresentationType.wrap( + matrixToPermalinkFromClientUser( + room.toRoomIDOrAlias(), + clientUserID + ) + ) + ), }); }, } diff --git a/apps/draupnir/src/utils.ts b/apps/draupnir/src/utils.ts index c47cfdea..fd542fc8 100644 --- a/apps/draupnir/src/utils.ts +++ b/apps/draupnir/src/utils.ts @@ -1,4 +1,5 @@ // Copyright 2022 Gnuxie +// SPDX-FileCopyrightText: 2026 Catalan Lover // Copyright 2019 - 2021 The Matrix.org Foundation C.I.C. // // SPDX-License-Identifier: Apache-2.0 @@ -16,6 +17,10 @@ import { setRequestFn, MatrixError, } from "@vector-im/matrix-bot-sdk"; +import { + StringUserID, + userServerName, +} from "@the-draupnir-project/matrix-basic-types"; import { ClientRequest, IncomingMessage } from "http"; import * as Sentry from "@sentry/node"; import ManagementRoomOutput from "./managementroom/ManagementRoomOutput"; @@ -31,6 +36,31 @@ export function htmlEscape(input: string): string { return input.replace(/[<&"']/g, (c) => "&#" + c.charCodeAt(0) + ";"); } +/** + * Build a matrix.to permalink for a room id or alias using a single via server. + * Example: https://matrix.to/#/%21room%3Aexample.com?via=example.com + */ +export function matrixToPermalink( + roomIdOrAlias: string, + viaServer: string +): string { + return `https://matrix.to/#/${encodeURIComponent(roomIdOrAlias)}?via=${encodeURIComponent( + viaServer + )}`; +} + +/** + * Build a matrix.to permalink for a room id or alias using the bot's homeserver derived + * from the provided client MXID. + */ +export function matrixToPermalinkFromClientUser( + roomIdOrAlias: string, + clientUserID: StringUserID +): string { + const via = userServerName(clientUserID); + return matrixToPermalink(roomIdOrAlias, via); +} + export function setToArray(set: Set): T[] { const arr: T[] = []; for (const v of set) { diff --git a/apps/draupnir/test/unit/utils/matrixToPermalink.test.ts b/apps/draupnir/test/unit/utils/matrixToPermalink.test.ts new file mode 100644 index 00000000..10c9c4aa --- /dev/null +++ b/apps/draupnir/test/unit/utils/matrixToPermalink.test.ts @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2026 Catalan Lover +// SPDX-License-Identifier: Apache-2.0 + +import expect from "expect"; +import { matrixToPermalink } from "../../../src/utils"; + +describe("matrixToPermalink", function () { + it("builds a matrix.to link with a single via", function () { + const room = "!wJbHKdEdDUKQRGGImO:feline.support"; + const via = "feline.support"; + const result = matrixToPermalink(room, via); + expect(result).toBe( + `https://matrix.to/#/${encodeURIComponent(room)}?via=${encodeURIComponent( + via + )}` + ); + }); +});