Skip to content

Commit

Permalink
Merge pull request #1258 from matrix-org/hs/delete-room-on-matrix-leave
Browse files Browse the repository at this point in the history
Remove admin/pm rooms when the matrix-side user leaves to allow server to GC
  • Loading branch information
Half-Shot authored Mar 2, 2021
2 parents 450097d + 0b70b95 commit 29c5450
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog.d/1258.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Leave DM rooms and admin rooms if the Matrix user leaves so that a homeserver may clear them up later.
27 changes: 26 additions & 1 deletion src/bridge/MatrixHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,34 @@ export class MatrixHandler {
serverLookup[ircClient.server.domain] = ircClient;
});

const store = this.ircBridge.getStore();

// which channels should the connected client leave?
const ircRooms = await this.ircBridge.getStore().getIrcChannelsForRoomId(event.room_id);
const ircRooms = await store.getIrcChannelsForRoomId(event.room_id);

if (!ircRooms) {
const adminRoom = await store.getAdminRoomById(event.room_id);
if (adminRoom) {
await store.removeAdminRoom(adminRoom);
// The user left the admin room, let's also leave.
// XXX: The typing of .leave is wrong, it should
// allow undefined.
await this.membershipQueue.leave(event.room_id, "", req);
return null;
}

const pmRoom = await store.getMatrixPmRoomById(event.room_id);
if (pmRoom) {
await store.removePmRoom(pmRoom.roomId);
// The user left the pm room, let's also leave.
const members = await this.ircBridge.getAppServiceBridge().getBot().getJoinedMembers(pmRoom.roomId);
await Promise.all(Object.keys(members).map((u) => {
this.membershipQueue.leave(event.room_id, u, req);
}));
return null;
}

}

// ========== Client Parting ==========
// for each room, if we're connected to it, leave the channel.
Expand Down
4 changes: 4 additions & 0 deletions src/datastore/DataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ export interface DataStore {

getMatrixPmRoom(realUserId: string, virtualUserId: string): Promise<MatrixRoom|null>;

getMatrixPmRoomById(roomId: string): Promise<MatrixRoom|null>;

getTrackedChannelsForServer(domain: string): Promise<string[]>;

getRoomIdsFromConfig(): Promise<string[]>;
Expand All @@ -138,6 +140,8 @@ export interface DataStore {

storeAdminRoom(room: MatrixRoom, userId: string): Promise<void>;

removeAdminRoom(room: MatrixRoom): Promise<void>;

upsertMatrixRoom(room: MatrixRoom): Promise<void>;

getAdminRoomByUserId(userId: string): Promise<MatrixRoom|null>;
Expand Down
18 changes: 18 additions & 0 deletions src/datastore/NedbDataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,18 @@ export class NeDBDataStore implements DataStore {
return entry.matrix || null;
}

public async getMatrixPmRoomById(roomId: string) {
const entry = await this.roomStore.getEntriesByMatrixId(roomId);
if (!entry) {
return null;
}
if (entry.length > 1) {
log.warn(`More than one PM room assigned to Matrix room ${roomId}, returning first`);
}
return entry[0].matrix || null;
}


public async getTrackedChannelsForServer(domain: string) {
const entries: Entry[] = await this.roomStore.getEntriesByRemoteRoomData({ domain });
const channels = new Set<string>();
Expand Down Expand Up @@ -480,6 +492,12 @@ export class NeDBDataStore implements DataStore {
});
}

public async removeAdminRoom(room: MatrixRoom): Promise<void> {
await this.roomStore.delete({
matrix: room,
});
}

public async upsertMatrixRoom(room: MatrixRoom): Promise<void> {
await this.roomStore.setMatrixRoom(room);
}
Expand Down
16 changes: 16 additions & 0 deletions src/datastore/postgres/PgDataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,18 @@ export class PgDataStore implements DataStore {
return new MatrixRoom(res.rows[0].room_id);
}

public async getMatrixPmRoomById(roomId: string): Promise<MatrixRoom|null> {
log.debug(`getMatrixPmRoom (roomId=${roomId})`);
const res = await this.pgPool.query(
"SELECT room_id, matrix_user_id, virtual_user_id FROM pm_rooms WHERE room_id = $1", [
roomId,
]);
if (res.rowCount === 0) {
return null;
}
return new MatrixRoom(res.rows[0].room_id);
}

public async getTrackedChannelsForServer(domain: string): Promise<string[]> {
if (!this.serverMappings[domain]) {
// Return empty if we don't know the server.
Expand Down Expand Up @@ -410,6 +422,10 @@ export class PgDataStore implements DataStore {
return new MatrixRoom(res.rows[0].room_id);
}

public async removeAdminRoom(room: MatrixRoom): Promise<void> {
await this.pgPool.query("DELETE FROM admin_rooms WHERE room_id = $1", [room.roomId]);
}

public async storeMatrixUser(matrixUser: MatrixUser): Promise<void> {
const parameters = {
user_id: matrixUser.getId(),
Expand Down

0 comments on commit 29c5450

Please sign in to comment.