diff --git a/src/api/dimension/DimensionIrcService.ts b/src/api/dimension/DimensionIrcService.ts index 1cd13df..827d94b 100644 --- a/src/api/dimension/DimensionIrcService.ts +++ b/src/api/dimension/DimensionIrcService.ts @@ -46,4 +46,20 @@ export class DimensionIrcService { LogService.info("DimensionIrcService", userId + " requested #" + channelNoHash + " on " + networkId + " to be linked to " + roomId); return {}; // 200 OK } + + @POST + @Path(":networkId/channel/:channel/unlink/:roomId") + public async unlink(@QueryParam("scalar_token") scalarToken: string, @PathParam("networkId") networkId: string, @PathParam("channel") channelNoHash: string, @PathParam("roomId") roomId: string): Promise { + const userId = await ScalarService.getTokenOwner(scalarToken); + + const parsed = IrcBridge.parseNetworkId(networkId); + const bridge = await IrcBridgeRecord.findByPrimary(parsed.bridgeId); + if (!bridge) throw new ApiError(404, "Bridge not found"); + + const client = new IrcBridge(userId); + await client.removeLink(bridge, parsed.bridgeNetworkId, "#" + channelNoHash, roomId); + + LogService.info("DimensionIrcService", userId + " unlinked #" + channelNoHash + " on " + networkId + " from " + roomId); + return {}; // 200 OK + } } \ No newline at end of file diff --git a/src/bridges/IrcBridge.ts b/src/bridges/IrcBridge.ts index 922f5c9..1b45d44 100644 --- a/src/bridges/IrcBridge.ts +++ b/src/bridges/IrcBridge.ts @@ -127,6 +127,25 @@ export class IrcBridge { } } + public async removeLink(bridge: IrcBridgeRecord, networkId: string, channel: string, inRoomId: string): Promise { + const network = (await this.getAllNetworks()).find(n => n.isEnabled && n.ircBridgeId === bridge.id && n.bridgeNetworkId === networkId); + if (!network) throw new Error("Network not found"); + + const requestBody = { + remote_room_server: network.domain, + remote_room_channel: channel, + matrix_room_id: inRoomId, + user_id: this.requestingUserId, + }; + + if (bridge.upstreamId) { + delete requestBody["user_id"]; + await this.doUpstreamRequest(bridge, "POST", "/bridges/irc/_matrix/provision/unlink", null, requestBody); + } else { + await this.doProvisionRequest(bridge, "POST", "/_matrix/provision/unlink", null, requestBody); + } + } + private async getAllNetworks(): Promise { const cached = Cache.for(CACHE_IRC_BRIDGE).get("networks"); if (cached) return cached; diff --git a/src/temp_todo.txt b/src/temp_todo.txt index 66e12e0..87362b4 100644 --- a/src/temp_todo.txt +++ b/src/temp_todo.txt @@ -1,5 +1,4 @@ Release checklist: -* IRC Bridge * Update documentation * Configuration migration (if possible) * Final testing (widgets, bots, etc) diff --git a/web/app/configs/bridge/irc/irc.bridge.component.ts b/web/app/configs/bridge/irc/irc.bridge.component.ts index fb31acb..a02f9cb 100644 --- a/web/app/configs/bridge/irc/irc.bridge.component.ts +++ b/web/app/configs/bridge/irc/irc.bridge.component.ts @@ -127,7 +127,16 @@ export class IrcBridgeConfigComponent extends BridgeComponent { return channels; } - public removeChannel(channel: any) { - console.log(channel); + public removeChannel(channel: LocalChannel) { + this.isUpdating = true; + this.irc.removeLink(this.roomId, channel.networkId, channel.name.substring(1)).then(() => { + this.isUpdating = false; + const idx = this.bridge.config.links[channel.networkId].findIndex(c => c.channelName === channel.name); + if (idx !== -1) this.bridge.config.links[channel.networkId].splice(idx, 1); + this.toaster.pop("success", "Link removed"); + }).catch(err => { + console.error(err); + this.toaster.pop("error", "Failed to remove link"); + }); } } \ No newline at end of file diff --git a/web/app/shared/services/integrations/irc-api.service.ts b/web/app/shared/services/integrations/irc-api.service.ts index 7932098..d9004e3 100644 --- a/web/app/shared/services/integrations/irc-api.service.ts +++ b/web/app/shared/services/integrations/irc-api.service.ts @@ -15,4 +15,8 @@ export class IrcApiService extends AuthedApi { public requestLink(roomId: string, networkId: string, channelNoHash: string, op: string): Promise { return this.authedPost("/api/v1/dimension/irc/" + networkId + "/channel/" + channelNoHash + "/link/" + roomId, {op: op}).map(r => r.json()).toPromise(); } + + public removeLink(roomId: string, networkId: string, channelNoHash: string): Promise { + return this.authedPost("/api/v1/dimension/irc/" + networkId + "/channel/" + channelNoHash + "/unlink/" + roomId).map(r => r.json()).toPromise(); + } }