diff --git a/src/channelsyncroniser.ts b/src/channelsyncroniser.ts index 89c745897b646dad02e8ef732ebc6b854012b2c1..2877f3d6a6c86a8d0ff1b69453bb4cfb23e6e16c 100644 --- a/src/channelsyncroniser.ts +++ b/src/channelsyncroniser.ts @@ -169,6 +169,7 @@ export class ChannelSyncroniser { try { rooms = await this.GetRoomIdsFromChannel(channel); } catch (err) { } // do nothing, our rooms array will just be empty + let fallbackAlias = ""; for (const room of rooms) { try { const al = (await this.bridge.botIntent.underlyingClient.getRoomStateEvent( @@ -177,16 +178,23 @@ export class ChannelSyncroniser { "") ).alias; if (al) { - return al; // we are done, we found an alias + if (this.bridge.isNamespacedAlias(al)) { + fallbackAlias = al; + } else { + return al; // we are done, we found an alias + } } } catch (err) { } // do nothing, as if we error we just roll over to the next entry } + if (fallbackAlias) { + return fallbackAlias; + } const guildChannel = channel as Discord.TextChannel; if (!guildChannel.guild) { return null; // we didn't pass a guild, so we have no way of bridging this room, thus no alias } // at last, no known canonical aliases and we are a guild....so we know an alias! - return `#_discord_${guildChannel.guild.id}_${channel.id}:${this.config.bridge.domain}`; + return this.bridge.getAliasForSuffix(`${guildChannel.guild.id}_${channel.id}`); } public async GetChannelUpdateState(channel: Discord.TextChannel, forceUpdate = false): Promise<IChannelState> { diff --git a/test/mocks/appservicemock.ts b/test/mocks/appservicemock.ts index 63bc08d2c4d8dd630e4e4e67b00a0c12a130b923..b832db55365c5c8b23e3ffa7ba3ae1cd38c14984 100644 --- a/test/mocks/appservicemock.ts +++ b/test/mocks/appservicemock.ts @@ -10,7 +10,9 @@ interface IAppserviceMockOpts { profileFetcher?: (userId) => Promise<any>; botUserId?: string; userIdPrefix?: string; + aliasPrefix?: string; joinedrooms?: string[]; + homeserverName?: string; } class AppserviceMockBase { @@ -84,6 +86,14 @@ export class AppserviceMock extends AppserviceMockBase { throw Error("No prefix defined"); } + public isNamespacedAlias(alias: string) { + this.funcCalled("isNamespacedAlias", alias); + if (this.opts.aliasPrefix) { + return alias.startsWith(this.opts.aliasPrefix); + } + throw Error("No prefix defined"); + } + public getIntent(userId: string) { this.funcCalled("getIntent", userId); if (!this.intents[userId]) { @@ -100,6 +110,14 @@ export class AppserviceMock extends AppserviceMockBase { return this.intents[suffix]; } + public getAliasForSuffix(suffix: string) { + this.funcCalled("getAliasForSuffix", suffix); + if (this.opts.aliasPrefix) { + return `${this.opts.aliasPrefix}${suffix}:${this.opts.homeserverName}`; + } + throw Error("No prefix defined"); + } + public getIntentForUserId(userId: string) { this.funcCalled("getIntentForUserId", userId); if (!this.intents[userId]) { diff --git a/test/test_channelsyncroniser.ts b/test/test_channelsyncroniser.ts index 738ef8838914149afc7cb6a53373648734381a2c..f75d6d2040b164e9dbdc87b7b256990e01d15f8b 100644 --- a/test/test_channelsyncroniser.ts +++ b/test/test_channelsyncroniser.ts @@ -55,6 +55,8 @@ class Entry implements IRoomStoreEntry { function CreateChannelSync(remoteChannels: any[] = []) { const bridge = new AppserviceMock({ + aliasPrefix: "#_discord_", + homeserverName: "localhost", stateEventFetcher: async (roomId: string, type: string, key: string) => { if (roomId === "!valid:localhost" && type === "m.room.canonical_alias" && key === "") { return { alias: "#alias:localhost"}; @@ -245,6 +247,27 @@ describe("ChannelSyncroniser", () => { const alias = await channelSync.GetAliasFromChannel(chan as any); expect(alias).to.equal("#alias:localhost"); }); + it("Should prefer non-discord canonical aliases", async () => { + const {channelSync} = CreateChannelSync(); + channelSync.GetRoomIdsFromChannel = async (_) => { + return ["!discord:localhost", "!valid:localhost"]; + }; + const alias = await channelSync.GetAliasFromChannel({} as any); + + expect(alias).to.equal("#alias:localhost"); + }); + it("Should use discord canonical alias if none other present", async () => { + const {channelSync} = CreateChannelSync(); + channelSync.GetRoomIdsFromChannel = async (_) => { + return ["!discord:localhost"]; + }; + const alias = await channelSync.GetAliasFromChannel({ + guild: { id: "123" }, + id: "123", + } as any); + + expect(alias).to.equal("#_discord_123_123:localhost"); + }); it("Should return null if no alias found and no guild present", async () => { const chan = new MockChannel(); chan.id = "123";