diff --git a/src/matrix-to.js b/src/matrix-to.js index 944446c4cc..b5827f671a 100644 --- a/src/matrix-to.js +++ b/src/matrix-to.js @@ -24,8 +24,14 @@ export const baseUrl = `https://${host}`; const MAX_SERVER_CANDIDATES = 3; export function makeEventPermalink(roomId, eventId) { + const permalinkBase = `${baseUrl}/#/${roomId}/${eventId}`; + + // 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 permalinkBase; + const serverCandidates = pickServerCandidates(roomId); - return `${baseUrl}/#/${roomId}/${eventId}?${encodeServerCandidates(serverCandidates)}`; + return `${permalinkBase}${encodeServerCandidates(serverCandidates)}`; } export function makeUserPermalink(userId) { @@ -33,8 +39,14 @@ export function makeUserPermalink(userId) { } export function makeRoomPermalink(roomId) { + const permalinkBase = `${baseUrl}/#/${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 permalinkBase; + const serverCandidates = pickServerCandidates(roomId); - return `${baseUrl}/#/${roomId}?${encodeServerCandidates(serverCandidates)}`; + return `${permalinkBase}${encodeServerCandidates(serverCandidates)}`; } export function makeGroupPermalink(groupId) { @@ -42,8 +54,8 @@ export function makeGroupPermalink(groupId) { } export function encodeServerCandidates(candidates) { - if (!candidates) return ''; - return `via=${candidates.map(c => encodeURIComponent(c)).join("&via=")}`; + if (!candidates || candidates.length === 0) return ''; + return `?via=${candidates.map(c => encodeURIComponent(c)).join("&via=")}`; } export function pickServerCandidates(roomId) { diff --git a/test/matrix-to-test.js b/test/matrix-to-test.js index d199588b9a..70533575c4 100644 --- a/test/matrix-to-test.js +++ b/test/matrix-to-test.js @@ -13,7 +13,13 @@ limitations under the License. import expect from 'expect'; import peg from '../src/MatrixClientPeg'; -import {pickServerCandidates} from "../src/matrix-to"; +import { + makeEventPermalink, + makeGroupPermalink, + makeRoomPermalink, + makeUserPermalink, + pickServerCandidates, +} from "../src/matrix-to"; import * as testUtils from "./test-utils"; @@ -228,4 +234,116 @@ describe('matrix-to', function() { expect(pickedServers.length).toBe(1); expect(pickedServers[0]).toBe("example.org:8448"); }); + + it('should generate an event permalink for room IDs with no candidate servers', function() { + peg.get().getRoom = () => null; + const result = makeEventPermalink("!somewhere:example.org", "$something:example.com"); + expect(result).toBe("https://matrix.to/#/!somewhere:example.org/$something:example.com"); + }); + + it('should generate an event permalink for room IDs with some candidate servers', function() { + peg.get().getRoom = () => { + return { + getJoinedMembers: () => [ + { + userId: "@alice:first", + powerLevel: 100, + }, + { + userId: "@bob:second", + powerLevel: 0, + }, + ], + }; + }; + const result = makeEventPermalink("!somewhere:example.org", "$something:example.com"); + expect(result).toBe("https://matrix.to/#/!somewhere:example.org/$something:example.com?via=first&via=second"); + }); + + it('should generate a room permalink for room IDs with no candidate servers', function() { + peg.get().getRoom = () => null; + const result = makeRoomPermalink("!somewhere:example.org"); + expect(result).toBe("https://matrix.to/#/!somewhere:example.org"); + }); + + it('should generate a room permalink for room IDs with some candidate servers', function() { + peg.get().getRoom = () => { + return { + getJoinedMembers: () => [ + { + userId: "@alice:first", + powerLevel: 100, + }, + { + userId: "@bob:second", + powerLevel: 0, + }, + ], + }; + }; + const result = makeRoomPermalink("!somewhere:example.org"); + expect(result).toBe("https://matrix.to/#/!somewhere:example.org?via=first&via=second"); + }); + + // Technically disallowed but we'll test it anyways + it('should generate an event permalink for room aliases with no candidate servers', function() { + peg.get().getRoom = () => null; + const result = makeEventPermalink("#somewhere:example.org", "$something:example.com"); + expect(result).toBe("https://matrix.to/#/#somewhere:example.org/$something:example.com"); + }); + + // Technically disallowed but we'll test it anyways + it('should generate an event permalink for room aliases without candidate servers', function() { + peg.get().getRoom = () => { + return { + getJoinedMembers: () => [ + { + userId: "@alice:first", + powerLevel: 100, + }, + { + userId: "@bob:second", + powerLevel: 0, + }, + ], + }; + }; + const result = makeEventPermalink("#somewhere:example.org", "$something:example.com"); + expect(result).toBe("https://matrix.to/#/#somewhere:example.org/$something:example.com"); + }); + + it('should generate a room permalink for room aliases with no candidate servers', function() { + peg.get().getRoom = () => null; + const result = makeRoomPermalink("#somewhere:example.org"); + expect(result).toBe("https://matrix.to/#/#somewhere:example.org"); + }); + + it('should generate a room permalink for room aliases without candidate servers', function() { + peg.get().getRoom = () => { + return { + getJoinedMembers: () => [ + { + userId: "@alice:first", + powerLevel: 100, + }, + { + userId: "@bob:second", + powerLevel: 0, + }, + ], + }; + }; + const result = makeRoomPermalink("#somewhere:example.org"); + expect(result).toBe("https://matrix.to/#/#somewhere:example.org"); + }); + + it('should generate a user permalink', function() { + const result = makeUserPermalink("@someone:example.org"); + expect(result).toBe("https://matrix.to/#/@someone:example.org"); + }); + + it('should generate a group permalink', function() { + const result = makeGroupPermalink("+community:example.org"); + expect(result).toBe("https://matrix.to/#/+community:example.org"); + }); });