Skip to content

Commit

Permalink
fix: inconsistent behavior when removing subscriptions and inquiries (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksandernsilva authored Oct 18, 2023
1 parent 049b921 commit e24d071
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/long-cars-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed intermittent errors caused by the removal of subscriptions and inquiries when lacking permissions.
26 changes: 21 additions & 5 deletions apps/meteor/app/livechat/client/lib/stream/queueManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,34 @@ import { LivechatInquiry } from '../../collections/LivechatInquiry';
const departments = new Set();

const events = {
added: (inquiry: ILivechatInquiryRecord) => {
departments.has(inquiry.department) && LivechatInquiry.insert({ ...inquiry, alert: true, _updatedAt: new Date(inquiry._updatedAt) });
added: async (inquiry: ILivechatInquiryRecord) => {
if (!departments.has(inquiry.department)) {
return;
}

LivechatInquiry.insert({ ...inquiry, alert: true, _updatedAt: new Date(inquiry._updatedAt) });
await invalidateRoomQueries(inquiry.rid);
},
changed: async (inquiry: ILivechatInquiryRecord) => {
if (inquiry.status !== 'queued' || (inquiry.department && !departments.has(inquiry.department))) {
return LivechatInquiry.remove(inquiry._id);
return removeInquiry(inquiry);
}

LivechatInquiry.upsert({ _id: inquiry._id }, { ...inquiry, alert: true, _updatedAt: new Date(inquiry._updatedAt) });
await queryClient.invalidateQueries(['/v1/rooms.info', inquiry.rid]);
await invalidateRoomQueries(inquiry.rid);
},
removed: (inquiry: ILivechatInquiryRecord) => LivechatInquiry.remove(inquiry._id),
removed: (inquiry: ILivechatInquiryRecord) => removeInquiry(inquiry),
};

const invalidateRoomQueries = async (rid: string) => {
await queryClient.invalidateQueries(['rooms', { reference: rid, type: 'l' }]);
await queryClient.removeQueries(['rooms', rid]);
await queryClient.removeQueries(['/v1/rooms.info', rid]);
};

const removeInquiry = async (inquiry: ILivechatInquiryRecord) => {
await LivechatInquiry.remove(inquiry._id);
return queryClient.invalidateQueries(['rooms', { reference: inquiry.rid, type: 'l' }]);
};

const getInquiriesFromAPI = async () => {
Expand Down
10 changes: 10 additions & 0 deletions apps/meteor/client/views/room/hooks/useOpenRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { omit } from '../../../../lib/utils/omit';
import { NotAuthorizedError } from '../../../lib/errors/NotAuthorizedError';
import { OldUrlRoomError } from '../../../lib/errors/OldUrlRoomError';
import { RoomNotFoundError } from '../../../lib/errors/RoomNotFoundError';
import { queryClient } from '../../../lib/queryClient';

export function useOpenRoom({ type, reference }: { type: RoomType; reference: string }) {
const user = useUser();
Expand Down Expand Up @@ -102,6 +103,15 @@ export function useOpenRoom({ type, reference }: { type: RoomType; reference: st
},
{
retry: 0,
onError: async (error) => {
if (['l', 'v'].includes(type) && error instanceof RoomNotFoundError) {
const { ChatRoom } = await import('../../../../app/models/client');

ChatRoom.remove(reference);
queryClient.removeQueries(['rooms', reference]);
queryClient.removeQueries(['/v1/rooms.info', reference]);
}
},
},
);
}
39 changes: 2 additions & 37 deletions apps/meteor/client/views/room/providers/RoomProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { usePermission, useStream, useUserId, useRouter } from '@rocket.chat/ui-contexts';
import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from '@rocket.chat/ui-contexts';
import type { ReactNode, ContextType, ReactElement } from 'react';
import React, { useMemo, memo, useEffect, useCallback } from 'react';

import { ChatRoom, ChatSubscription } from '../../../../app/models/client';
import { ChatSubscription } from '../../../../app/models/client';
import { RoomHistoryManager } from '../../../../app/ui-utils/client';
import { UserAction } from '../../../../app/ui/client/lib/UserAction';
import { useReactiveQuery } from '../../../hooks/useReactiveQuery';
Expand All @@ -29,24 +28,6 @@ const RoomProvider = ({ rid, children }: RoomProviderProps): ReactElement => {

const { data: room, isSuccess } = useRoomQuery(rid);

const subscribeToRoom = useStream('room-data');

const queryClient = useQueryClient();
const userId = useUserId();
const isLivechatAdmin = usePermission('view-livechat-rooms');
const { t: roomType } = room ?? {};

// TODO: move this to omnichannel context only
useEffect(() => {
if (roomType !== 'l') {
return;
}

return subscribeToRoom(rid, (room) => {
queryClient.setQueryData(['rooms', rid], room);
});
}, [subscribeToRoom, rid, queryClient, roomType]);

// TODO: the following effect is a workaround while we don't have a general and definitive solution for it
const router = useRouter();
useEffect(() => {
Expand All @@ -55,22 +36,6 @@ const RoomProvider = ({ rid, children }: RoomProviderProps): ReactElement => {
}
}, [isSuccess, room, router]);

const { _id: servedById } = room?.servedBy ?? {};

// TODO: Review the necessity of this effect when we move away from cached collections
useEffect(() => {
if (roomType !== 'l' || !servedById) {
return;
}

if (!isLivechatAdmin && servedById !== userId) {
ChatRoom.remove(rid);
queryClient.removeQueries(['rooms', rid]);
queryClient.removeQueries(['rooms', { reference: rid, type: 'l' }]);
queryClient.removeQueries(['/v1/rooms.info', rid]);
}
}, [isLivechatAdmin, queryClient, userId, rid, roomType, servedById]);

const subscriptionQuery = useReactiveQuery(['subscriptions', { rid }], () => ChatSubscription.findOne({ rid }) ?? null);

const pseudoRoom = useMemo(() => {
Expand Down

0 comments on commit e24d071

Please sign in to comment.