Fix user added to channel event not correctly getting the channel id (#6053)

* Fix user added to channel event not correctly getting the channel id

* Fix several other websocket problems
This commit is contained in:
Daniel Espino García
2022-03-15 19:55:09 +01:00
committed by GitHub
parent 9f9190f5db
commit ff952ced2a
7 changed files with 62 additions and 43 deletions

View File

@@ -24,7 +24,8 @@ export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any)
return;
}
const currentUser = await queryCurrentUser(database.database);
const {team_id: teamId, channel_id: channelId, user_id: userId} = msg.data;
const {team_id: teamId, user_id: userId} = msg.data;
const {channel_id: channelId} = msg.broadcast;
const models: Model[] = [];
try {
@@ -64,8 +65,6 @@ export async function handleUserAddedToChannelEvent(serverUrl: string, msg: any)
if (authors?.length) {
models.push(...await database.operator.handleUsers({users: authors, prepareRecordsOnly: true}));
}
database.operator.batchRecords(models);
} else {
const channels = await queryChannelsById(database.database, [channelId]);
if (channels?.[0]) {
@@ -94,8 +93,9 @@ export async function handleUserRemovedFromChannelEvent(serverUrl: string, msg:
return;
}
const userId = msg.data.user_id;
const channelId = msg.data.channel_id;
// Depending on who was removed, the ids may come from one place dataset or the other.
const userId = msg.data.user_id || msg.broadcast.user_id;
const channelId = msg.data.channel_id || msg.broadcast.channel_id;
const models: Model[] = [];
@@ -158,18 +158,20 @@ export async function handleChannelDeletedEvent(serverUrl: string, msg: WebSocke
return;
}
const {channel_id: channelId, delete_at: deleteAt} = msg.data;
const config = await queryConfig(database.database);
await setChannelDeleteAt(serverUrl, msg.data.channel_id, msg.data.delete_at);
await setChannelDeleteAt(serverUrl, channelId, deleteAt);
if (user.isGuest) {
updateUsersNoLongerVisible(serverUrl);
}
if (config?.ExperimentalViewArchivedChannels !== 'true') {
removeCurrentUserFromChannel(serverUrl, msg.data.channel_id);
removeCurrentUserFromChannel(serverUrl, channelId);
if (currentChannel && currentChannel.id === msg.data.channel_id) {
if (currentChannel && currentChannel.id === channelId) {
const currentServer = await queryActiveServer(DatabaseManager.appDatabase!.database);
if (currentServer?.url === serverUrl) {

View File

@@ -213,9 +213,11 @@ export function handlePostDeleted(serverUrl: string, msg: WebSocketMessage) {
}
export async function handlePostUnread(serverUrl: string, msg: WebSocketMessage) {
const {channels} = await fetchMyChannel(serverUrl, msg.broadcast.team_id, msg.broadcast.channel_id, true);
const {team_id: teamId, channel_id: channelId} = msg.broadcast;
const {mention_count: mentionCount, msg_count: msgCount, last_viewed_at: lastViewedAt} = msg.data;
const {channels} = await fetchMyChannel(serverUrl, teamId, channelId, true);
const channel = channels?.[0];
const postNumber = channel?.total_msg_count;
const delta = postNumber ? postNumber - msg.data.msg_count : msg.data.msg_count;
markChannelAsUnread(serverUrl, msg.broadcast.channel_id, delta, msg.data.mention_count, msg.data.last_viewed_at);
const delta = postNumber ? postNumber - msgCount : msgCount;
markChannelAsUnread(serverUrl, channelId, delta, mentionCount, lastViewedAt);
}

View File

@@ -28,15 +28,16 @@ export async function handleLeaveTeamEvent(serverUrl: string, msg: WebSocketMess
return;
}
if (user.id === msg.data.user_id) {
await removeUserFromTeam(serverUrl, msg.data.team_id);
const {user_id: userId, team_id: teamId} = msg.data;
if (user.id === userId) {
await removeUserFromTeam(serverUrl, teamId);
fetchAllTeams(serverUrl);
if (user.isGuest) {
updateUsersNoLongerVisible(serverUrl);
}
if (currentTeamId === msg.data.team_id) {
if (currentTeamId === teamId) {
const currentServer = await queryActiveServer(DatabaseManager.appDatabase!.database);
if (currentServer?.url === serverUrl) {
@@ -70,13 +71,26 @@ export async function handleUpdateTeamEvent(serverUrl: string, msg: WebSocketMes
}
}
// As of today, the server sends a duplicated event to add the user to the team.
// If we do not handle this, this ends up showing some errors in the database, apart
// of the extra computation time. We use this to track the events that are being handled
// and make sure we only handle one.
const addingTeam: {[id: string]: boolean} = {};
export async function handleUserAddedToTeamEvent(serverUrl: string, msg: WebSocketMessage) {
const database = DatabaseManager.serverDatabases[serverUrl];
if (!database) {
return;
}
const {team_id: teamId} = msg.data;
const {teams, memberships: teamMemberships} = await fetchMyTeam(serverUrl, msg.data.team_id, true);
// Ignore duplicated team join events sent by the server
if (addingTeam[teamId]) {
return;
}
addingTeam[teamId] = true;
const {teams, memberships: teamMemberships} = await fetchMyTeam(serverUrl, teamId, true);
const modelPromises: Array<Promise<Model[]>> = [];
if (teams?.length && teamMemberships?.length) {
@@ -108,4 +122,6 @@ export async function handleUserAddedToTeamEvent(serverUrl: string, msg: WebSock
const models = await Promise.all(modelPromises);
await database.operator.batchRecords(models.flat());
}
delete addingTeam[teamId];
}

View File

@@ -117,13 +117,13 @@ export const prepareCategoryChannels = (
export const prepareDeleteCategory = async (category: CategoryModel): Promise<Model[]> => {
const preparedModels: Model[] = [category.prepareDestroyPermanently()];
const associatedChildren: Array<Query<any>> = [
const associatedChildren: Array<Query<Model>|undefined> = [
category.categoryChannels,
];
for await (const children of associatedChildren) {
const models = await children?.fetch?.() as Model[] | undefined;
await Promise.all(associatedChildren.map(async (children) => {
const models = await children?.fetch();
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
}
}));
return preparedModels;
};

View File

@@ -15,7 +15,6 @@ import type ServerDataOperator from '@database/operator/server_data_operator';
import type ChannelModel from '@typings/database/models/servers/channel';
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type PostModel from '@typings/database/models/servers/post';
const {SERVER: {CHANNEL, MY_CHANNEL, CHANNEL_MEMBERSHIP}} = MM_TABLES;
@@ -96,29 +95,29 @@ export const prepareMyChannelsForTeam = async (operator: ServerDataOperator, tea
export const prepareDeleteChannel = async (channel: ChannelModel): Promise<Model[]> => {
const preparedModels: Model[] = [channel.prepareDestroyPermanently()];
const relations: Array<Relation<Model>> = [channel.membership, channel.info, channel.settings, channel.categoryChannel];
for await (const relation of relations) {
const relations: Array<Relation<Model> | undefined> = [channel.membership, channel.info, channel.settings, channel.categoryChannel];
await Promise.all(relations.map(async (relation) => {
try {
const model = await relation?.fetch?.();
const model = await relation?.fetch();
if (model) {
preparedModels.push(model.prepareDestroyPermanently());
}
} catch {
// Record not found, do nothing
}
}
}));
const associatedChildren: Array<Query<any>> = [
const associatedChildren: Array<Query<Model> | undefined> = [
channel.members,
channel.drafts,
channel.postsInChannel,
];
for await (const children of associatedChildren) {
const models = await children?.fetch?.() as Model[] | undefined;
await Promise.all(associatedChildren.map(async (children) => {
const models = await children?.fetch();
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
}
}));
const posts = await channel.posts?.fetch?.() as PostModel[] | undefined;
const posts = await channel.posts?.fetch();
if (posts?.length) {
for await (const post of posts) {
const preparedPost = await prepareDeletePost(post);

View File

@@ -29,11 +29,11 @@ export const prepareDeletePost = async (post: PostModel): Promise<Model[]> => {
}
}
const associatedChildren: Array<Query<any>> = [post.files, post.reactions];
for await (const children of associatedChildren) {
const models = await children.fetch?.() as Model[] | undefined;
const associatedChildren: Array<Query<Model>|undefined> = [post.files, post.reactions];
await Promise.all(associatedChildren.map(async (children) => {
const models = await children?.fetch();
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
}
}));
return preparedModels;
};

View File

@@ -209,32 +209,32 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
const preparedModels: Model[] = [team.prepareDestroyPermanently()];
const relations: Array<Relation<Model>> = [team.myTeam, team.teamChannelHistory];
for await (const relation of relations) {
await Promise.all(relations.map(async (relation) => {
try {
const model = await relation?.fetch?.();
const model = await relation?.fetch();
if (model) {
preparedModels.push(model.prepareDestroyPermanently());
}
} catch {
} catch (error) {
// Record not found, do nothing
}
}
}));
const associatedChildren: Array<Query<any>> = [
const associatedChildren: Array<Query<Model>|undefined> = [
team.members,
team.slashCommands,
team.teamSearchHistories,
];
for await (const children of associatedChildren) {
await Promise.all(associatedChildren.map(async (children) => {
try {
const models = await children.fetch?.() as Model[] | undefined;
const models = await children?.fetch();
models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
} catch {
// Record not found, do nothing
}
}
}));
const categories = await team.categories.fetch?.() as CategoryModel[] | undefined;
const categories = await team.categories?.fetch() as CategoryModel[] | undefined;
if (categories?.length) {
for await (const category of categories) {
try {
@@ -246,7 +246,7 @@ export const prepareDeleteTeam = async (team: TeamModel): Promise<Model[]> => {
}
}
const channels = await team.channels.fetch?.() as ChannelModel[] | undefined;
const channels = await team.channels?.fetch() as ChannelModel[] | undefined;
if (channels?.length) {
for await (const channel of channels) {
try {