Remove connections from a room when the bot leaves (#257)

* Remove connections on leave

* changelog
This commit is contained in:
Will Hunt 2022-03-30 10:22:40 +01:00 committed by GitHub
parent 5fbd8c9ba0
commit 43db45a698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 4 deletions

1
changelog.d/257.bugfix Normal file
View File

@ -0,0 +1 @@
Fix an issue where the bridge bot would rejoin a room after being removed.

View File

@ -180,6 +180,10 @@ export class Bridge {
return this.onRoomEvent(roomId, event);
});
this.as.on("room.leave", async (roomId, event) => {
return this.onRoomLeave(roomId, event);
});
this.as.on("room.join", async (roomId, event) => {
return this.onRoomJoin(roomId, event);
});
@ -681,6 +685,20 @@ export class Bridge {
}
}
private async onRoomLeave(roomId: string, event: MatrixEvent<MatrixMemberContent>) {
if (event.state_key !== this.as.botUserId) {
// Only interested in bot leaves.
return;
}
// If the bot has left the room, we want to vape all connections for that room.
try {
await this.connectionManager?.removeConnectionsForRoom(roomId);
} catch (ex) {
log.warn(`Failed to remove connections on leave for ${roomId}`);
}
}
private async onRoomMessage(roomId: string, event: MatrixEvent<MatrixMessageContent>) {
if (!this.connectionManager) {
// Not ready yet.
@ -799,7 +817,7 @@ export class Bridge {
for (const connection of existingConnections) {
try {
if (event.content.disabled === true) {
await this.connectionManager.removeConnection(connection.roomId, connection.connectionId);
await this.connectionManager.purgeConnection(connection.roomId, connection.connectionId);
} else {
connection.onStateUpdate?.(event);
}

View File

@ -387,8 +387,8 @@ export class ConnectionManager {
return this.connections.find((c) => c.connectionId === connectionId && c.roomId === roomId);
}
public async removeConnection(roomId: string, connectionId: string) {
const connection = this.connections.find((c) => c.connectionId === connectionId && c.roomId);
public async purgeConnection(roomId: string, connectionId: string) {
const connection = this.connections.find((c) => c.connectionId === connectionId && c.roomId == roomId);
if (!connection) {
throw Error("Connection not found");
}
@ -404,6 +404,16 @@ export class ConnectionManager {
}
}
/**
* Removes connections for a room from memory. This does NOT remove the state
* event from the room.
* @param roomId
*/
public async removeConnectionsForRoom(roomId: string) {
log.info(`Removing all connections from ${roomId}`);
this.connections = this.connections.filter((c) => c.roomId !== roomId);
}
public registerProvisioningConnection(connType: {getProvisionerDetails: (botUserId: string) => GetConnectionTypeResponseItem}) {
const details = connType.getProvisionerDetails(this.as.botUserId);
if (this.enabledForProvisioning[details.type]) {

View File

@ -235,7 +235,7 @@ export class Provisioner {
if (!connection.onRemove) {
return next(new ApiError("Connection does not support removal", ErrCode.UnsupportedOperation));
}
await this.connMan.removeConnection(req.params.roomId, req.params.connectionId);
await this.connMan.purgeConnection(req.params.roomId, req.params.connectionId);
res.send({ok: true});
} catch (ex) {
return next(ex);