Room purge fixes

This commit is contained in:
N Pex 2023-01-31 09:39:30 +00:00
parent e4597dd7b4
commit f34144557a
2 changed files with 93 additions and 180 deletions

View file

@ -1018,7 +1018,6 @@ export default {
},
handleScrolledToTop() {
console.log("@top");
if (
this.timelineWindow &&
this.timelineWindow.canPaginate(EventTimeline.BACKWARDS) &&
@ -1045,7 +1044,6 @@ export default {
},
handleScrolledToBottom(scrollToEnd) {
console.log("@bottom");
if (
this.timelineWindow &&
this.timelineWindow.canPaginate(EventTimeline.FORWARDS) &&
@ -1287,7 +1285,6 @@ export default {
* Start/restart the timer to Read Receipts.
*/
restartRRTimer() {
console.log("Restart RR timer");
this.stopRRTimer();
let eventIdFirst = null;
@ -1307,7 +1304,6 @@ export default {
},
rrTimerElapsed(eventIdFirst, eventIdLast) {
console.log("RR timer elapsed", eventIdFirst, eventIdLast);
this.rrTimer = null;
this.sendRR(eventIdFirst, eventIdLast);
this.restartRRTimer();

View file

@ -5,8 +5,8 @@ import { TimelineWindow, EventTimeline } from "matrix-js-sdk";
import util from "../plugins/utils";
import User from "../models/user";
const LocalStorageCryptoStore = require("matrix-js-sdk/lib/crypto/store/localStorage-crypto-store")
.LocalStorageCryptoStore;
const LocalStorageCryptoStore =
require("matrix-js-sdk/lib/crypto/store/localStorage-crypto-store").LocalStorageCryptoStore;
export default {
install(Vue, options) {
@ -67,7 +67,7 @@ export default {
},
currentUserHomeServer() {
return this.$config.homeServer ? this.$config.homeServer : User.serverName(this.currentUserId);
return this.$config.homeServer ? this.$config.homeServer : User.serverName(this.currentUserId);
},
currentRoomId() {
@ -141,18 +141,16 @@ export default {
if (user.device_id) {
data.device_id = user.device_id;
}
promiseLogin = tempMatrixClient
.login("m.login.password", data)
.then((response) => {
var u = Object.assign({}, response);
if (user.is_guest) {
// Copy over needed properties
u = Object.assign(user, response);
}
u.home_server = tempMatrixClient.baseUrl; // Don't use deprecated field from response.
this.$store.commit("setUser", u);
return u;
});
promiseLogin = tempMatrixClient.login("m.login.password", data).then((response) => {
var u = Object.assign({}, response);
if (user.is_guest) {
// Copy over needed properties
u = Object.assign(user, response);
}
u.home_server = tempMatrixClient.baseUrl; // Don't use deprecated field from response.
this.$store.commit("setUser", u);
return u;
});
}
return promiseLogin.then((user) => {
@ -261,11 +259,7 @@ export default {
return matrixClient;
} else {
return new Promise((resolve, reject) => {
matrixClient.once("sync", function(
state,
ignoredprevState,
ignoredres
) {
matrixClient.once("sync", function (state, ignoredprevState, ignoredres) {
console.log(state); // state will be 'PREPARED' when the client is ready to use
if (state == "PREPARED") {
resolve(matrixClient);
@ -293,11 +287,7 @@ export default {
if (this.ready) {
return Promise.resolve(this.currentUser);
}
return this.$store.dispatch(
"login",
this.currentUser ||
new User(this.$config.defaultServer, "", "", true)
);
return this.$store.dispatch("login", this.currentUser || new User(this.$config.defaultServer, "", "", true));
},
addMatrixClientListeners(client) {
@ -337,13 +327,7 @@ export default {
Vue.set(
room,
"avatar",
room.getAvatarUrl(
this.matrixClient.getHomeserverUrl(),
80,
80,
"scale",
true
)
room.getAvatarUrl(this.matrixClient.getHomeserverUrl(), 80, 80, "scale", true)
);
}
}
@ -351,26 +335,20 @@ export default {
case "m.room.member":
{
if (
this.currentRoom &&
event.getRoomId() == this.currentRoom.roomId
) {
if (this.currentRoom && event.getRoomId() == this.currentRoom.roomId) {
// Don't use this.currentRoomId, may be an alias. We need the real id!
if ((
event.getContent().membership == "leave" &&
(event.getPrevContent() || {}).membership == "join" &&
event.getStateKey() == this.currentUserId &&
event.getSender() != this.currentUserId
) || (event.getContent().membership == "ban" && event.getStateKey() == this.currentUserId)) {
if (
(event.getContent().membership == "leave" &&
(event.getPrevContent() || {}).membership == "join" &&
event.getStateKey() == this.currentUserId &&
event.getSender() != this.currentUserId) ||
(event.getContent().membership == "ban" && event.getStateKey() == this.currentUserId)
) {
// We were kicked or banned
// If this is a live event (not just backpaging) then redirect to goodbye!
if (this.matrixClientReady) {
const wasPurged =
event.getContent().reason == "Room Deleted";
this.$navigation.push(
{ name: "Goodbye", params: { roomWasPurged: wasPurged } },
-1
);
const wasPurged = event.getContent().reason == "Room Deleted";
this.$navigation.push({ name: "Goodbye", params: { roomWasPurged: wasPurged } }, -1);
}
}
}
@ -414,15 +392,15 @@ export default {
this.$store.commit("setUser", user);
// Login again
this.login(user).catch(error => {
if (error.data.errcode ==='M_FORBIDDEN' && this.currentUser.is_guest) {
this.login(user).catch((error) => {
if (error.data.errcode === "M_FORBIDDEN" && this.currentUser.is_guest) {
// Guest account and password don't work. We are in a strange state, probably because
// of server cleanup of accounts or similar. Wipe account and restart...
this.$store.commit("setUser", null);
}
this.$store.commit("setCurrentRoomId", null);
this.$navigation.push({ path: "/login" }, -1);
})
});
} else {
this.$store.commit("setUser", null);
this.$store.commit("setCurrentRoomId", null);
@ -435,24 +413,11 @@ 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");
});
updatedRooms.forEach((room) => {
if (!room.avatar) {
Vue.set(
room,
"avatar",
room.getAvatarUrl(
this.matrixClient.getHomeserverUrl(),
80,
80,
"scale",
true
)
);
Vue.set(room, "avatar", room.getAvatarUrl(this.matrixClient.getHomeserverUrl(), 80, 80, "scale", true));
}
});
Vue.set(this, "rooms", updatedRooms);
@ -491,15 +456,9 @@ export default {
var ids = {};
const ret = [];
for (const room of this.rooms) {
if (
room.selfMembership == "join" &&
this.getRoomJoinRule(room) == "invite"
) {
if (room.selfMembership == "join" && this.getRoomJoinRule(room) == "invite") {
for (const member of room.getJoinedMembers()) {
if (
member.userId != this.currentUserId &&
!ids[member.userId]
) {
if (member.userId != this.currentUserId && !ids[member.userId]) {
ids[member.userId] = member;
ret.push(member);
}
@ -516,10 +475,7 @@ export default {
getRoomJoinRule(room) {
if (room) {
const joinRules = room.currentState.getStateEvents(
"m.room.join_rules",
""
);
const joinRules = room.currentState.getStateEvents("m.room.join_rules", "");
return joinRules && joinRules.getContent().join_rule;
}
return null;
@ -527,14 +483,8 @@ export default {
getRoomHistoryVisibility(room) {
if (room) {
const historyVisibility = room.currentState.getStateEvents(
"m.room.history_visibility",
""
);
return (
historyVisibility &&
historyVisibility.getContent().history_visibility
);
const historyVisibility = room.currentState.getStateEvents("m.room.history_visibility", "");
return historyVisibility && historyVisibility.getContent().history_visibility;
}
return null;
},
@ -551,21 +501,13 @@ export default {
kickUser(roomId, userId) {
if (this.matrixClient && roomId && userId) {
this.matrixClient.kick(
roomId,
userId,
""
)
this.matrixClient.kick(roomId, userId, "");
}
},
banUser(roomId, userId) {
if (this.matrixClient && roomId && userId) {
this.matrixClient.ban(
roomId,
userId,
""
)
this.matrixClient.ban(roomId, userId, "");
}
},
@ -577,20 +519,20 @@ export default {
if (powerLevelEvent) {
this.matrixClient.setPowerLevel(roomId, userId, 100, powerLevelEvent);
}
}
}
}
},
makeModerator(roomId, userId) {
if (this.matrixClient && roomId && userId) {
const room = this.getRoom(roomId);
console.log("Room", room);
console.log("Room", room);
if (room && room.currentState) {
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
if (powerLevelEvent) {
this.matrixClient.setPowerLevel(roomId, userId, 50, powerLevelEvent);
}
}
}
}
},
@ -602,7 +544,7 @@ export default {
if (powerLevelEvent) {
this.matrixClient.setPowerLevel(roomId, userId, 0, powerLevelEvent);
}
}
}
}
},
@ -624,22 +566,13 @@ export default {
return;
}
const timelineWindow = new TimelineWindow(
this.matrixClient,
room.getUnfilteredTimelineSet(),
{}
);
const timelineWindow = new TimelineWindow(this.matrixClient, room.getUnfilteredTimelineSet(), {});
const self = this;
//console.log("Purge: set invite only");
statusCallback(this.$t("room.purge_set_room_state"));
this.matrixClient
.sendStateEvent(
roomId,
"m.room.join_rules",
{ join_rule: "invite" },
""
)
.sendStateEvent(roomId, "m.room.join_rules", { join_rule: "invite" }, "")
.then(() => {
//console.log("Purge: forbid guest access");
return this.matrixClient.sendStateEvent(
@ -651,13 +584,9 @@ export default {
})
.then(() => {
//console.log("Purge: set history visibility to 'joined'");
return this.matrixClient.sendStateEvent(
roomId,
"m.room.history_visibility",
{
history_visibility: "joined",
}
);
return this.matrixClient.sendStateEvent(roomId, "m.room.history_visibility", {
history_visibility: "joined",
});
})
.then(() => {
//console.log("Purge: create timeline");
@ -667,11 +596,12 @@ export default {
const getMoreIfAvailable = function _getMoreIfAvailable() {
if (timelineWindow.canPaginate(EventTimeline.BACKWARDS)) {
//console.log("Purge: page back");
return timelineWindow
.paginate(EventTimeline.BACKWARDS, 100, true, 5)
.then((ignoredsuccess) => {
return timelineWindow.paginate(EventTimeline.BACKWARDS, 100, true, 5).then((gotmore) => {
if (gotmore) {
return _getMoreIfAvailable.call(self);
});
}
return Promise.resolve("Done");
});
} else {
return Promise.resolve("Done");
}
@ -685,18 +615,9 @@ export default {
this.matrixClient.setGlobalErrorOnUnknownDevices(false);
var redactionPromises = [];
timelineWindow.getEvents().forEach((event) => {
if (
!event.isRedacted() &&
!event.isRedaction() &&
!event.isState()
) {
if (!event.isRedacted() && !event.isRedaction() && !event.isState()) {
// Redact!
redactionPromises.push(
this.matrixClient.redactEvent(
event.getRoomId(),
event.getId()
)
);
redactionPromises.push(this.matrixClient.redactEvent(event.getRoomId(), event.getId()));
}
});
return Promise.all(redactionPromises);
@ -706,27 +627,44 @@ export default {
statusCallback(this.$t("room.purge_removing_members"));
var joined = room.getMembersWithMembership("join");
var invited = room.getMembersWithMembership("invite");
var members = joined.concat(invited);
var allMembers = joined.concat(invited);
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var kickPromises = [];
members.forEach((member) => {
if (member.userId != self.currentUserId) {
kickPromises.push(
this.matrixClient.kick(
roomId,
member.userId,
"Room Deleted"
)
);
const kickFirstMember = (members) => {
//console.log(`Kicking ${members.length} members`);
if (members.length == 0) {
return Promise.resolve(true);
}
});
return Promise.all(kickPromises);
const member = members[0];
if (member.userId == self.currentUserId) {
return kickFirstMember(members.slice(1));
} else {
// Slight pause to avoid rate limiting.
return sleep(0.1)
.then(() => this.matrixClient.kick(roomId, member.userId, "Room Deleted"))
.catch((error) => {
if (error && error.errcode == "M_LIMIT_EXCEEDED") {
var retry = 1000;
if (error.data) {
const retryIn = error.data.retry_after_ms;
retry = Math.max(retry, retryIn ? retryIn : 0);
}
//console.log("Rate limited, retry in", retry);
return sleep(retry).then(() => kickFirstMember(members));
}
})
.finally(() => kickFirstMember(members.slice(1)))
}
};
return kickFirstMember(allMembers);
})
.then(() => {
statusCallback(null);
this.matrixClient.setGlobalErrorOnUnknownDevices(
oldGlobalErrorSetting
);
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
return this.leaveRoom(roomId);
})
.then(() => {
@ -734,9 +672,7 @@ export default {
})
.catch((err) => {
console.error("Error purging room", err);
this.matrixClient.setGlobalErrorOnUnknownDevices(
oldGlobalErrorSetting
);
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
reject(err);
});
});
@ -814,10 +750,7 @@ export default {
* @param {*} userId
*/
isDirectRoomWith(room, userId) {
if (
room.getJoinRule() == "invite" &&
room.getMembers().length == 2
) {
if (room.getJoinRule() == "invite" && room.getMembers().length == 2) {
let other = room.getMember(userId);
if (other) {
if (room.getMyMembership() == "invite" && other.membership == "join") {
@ -889,9 +822,7 @@ export default {
return this.matrixClient;
});
} else {
const tempMatrixClient = sdk.createClient(
this.$config.defaultServer
);
const tempMatrixClient = sdk.createClient(this.$config.defaultServer);
var tempUserString = this.$store.state.tempuser;
var tempUser = null;
if (tempUserString) {
@ -971,13 +902,7 @@ export default {
})
.then((response) => {
if (response.avatar_url) {
response.avatar = matrixClient.mxcUrlToHttp(
response.avatar_url,
80,
80,
"scale",
true
);
response.avatar = matrixClient.mxcUrlToHttp(response.avatar_url, 80, 80, "scale", true);
}
return Promise.resolve(response);
})
@ -1006,13 +931,7 @@ export default {
(roomId.startsWith("!") && room.room_id == roomId)
) {
if (room.avatar_url) {
room.avatar = client.mxcUrlToHttp(
room.avatar_url,
80,
80,
"scale",
true
);
room.avatar = client.mxcUrlToHttp(room.avatar_url, 80, 80, "scale", true);
}
return Promise.resolve(room);
}
@ -1059,9 +978,7 @@ export default {
},
});
sdk.setCryptoStoreFactory(
matrixService.createCryptoStore.bind(matrixService)
);
sdk.setCryptoStoreFactory(matrixService.createCryptoStore.bind(matrixService));
Vue.prototype.$matrix = matrixService;
},