diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js index 102df72..e4bba6d 100644 --- a/src/services/matrix.service.js +++ b/src/services/matrix.service.js @@ -406,6 +406,18 @@ export default { } break; + case "m.room.join_rules": + { + const room = this.matrixClient.getRoom(event.getRoomId()); + if (room && room.getJoinRule() == "private" && room.selfMembership == "invite") { + // We have an invite to a room that's now "private"? This is most probably a deleted DM room. + // Reject the invite, i.e. call "leave" on it. + console.error("Room made private while we have an invite! Leave..."); + this.matrixClient.leave(room.roomId); + } + } + break; + case STATE_EVENT_ROOM_DELETED: { const room = this.matrixClient.getRoom(event.getRoomId()); @@ -494,7 +506,7 @@ export default { // each time! var updatedRooms = this.matrixClient.getVisibleRooms(); updatedRooms = updatedRooms.filter((room) => { - return room.selfMembership && (room.selfMembership == "invite" || room.selfMembership == "join"); + return room.selfMembership && (room.selfMembership == "invite" || room.selfMembership == "join") && room.currentState.getStateEvents(STATE_EVENT_ROOM_DELETED).length == 0; }); updatedRooms.forEach((room) => { if (!room.avatar) { @@ -580,7 +592,7 @@ export default { }, leaveRoom(roomId) { - return this.matrixClient.leave(roomId, undefined).then(() => { + return this.matrixClient.leave(roomId).then(() => { this.$store.commit("setCurrentRoomId", null); this.rooms = this.rooms.filter((room) => { room.roomId != roomId; @@ -805,7 +817,7 @@ export default { //console.log("Purge: set invite only"); statusCallback(this.$t("room.purge_set_room_state")); - withRetry(() => this.matrixClient.sendStateEvent(roomId, "m.room.join_rules", { join_rule: "invite" }, "")) + withRetry(() => this.matrixClient.sendStateEvent(roomId, "m.room.join_rules", { join_rule: "private" }, "")) .then(() => { //console.log("Purge: forbid guest access"); return withRetry(() => this.matrixClient.sendStateEvent( @@ -887,6 +899,8 @@ export default { var invited = room.getMembersWithMembership("invite"); var allMembers = joined.concat(invited); + const me = allMembers.find((m) => m.userId == self.currentUserId); + const kickFirstMember = (members) => { //console.log(`Kicking ${members.length} members`); statusCallback( @@ -904,7 +918,16 @@ export default { } else { // Slight pause to avoid rate limiting. return sleep(0.1) - .then(() => withRetry(() => this.matrixClient.kick(roomId, member.userId, "Room Deleted"))) + .then(() => withRetry(() => { + if (member.membership == "invite" && me && me.powerLevel <= member.powerLevel) { + // The user is invited, but we can't kick them because of power levels. + // Send a new invite with reason set to "Room Deleted". + // The client will be sent stripped room state, and can from that see the + // join_rule of "private". It will then "leave", i.e. reject the invite. + return this.matrixClient.invite(roomId, member.userId, "Room Deleted"); + } + return this.matrixClient.kick(roomId, member.userId, "Room Deleted") + })) .then(() => kickFirstMember(members.slice(1))); } };