Skip to content

Commit d39e70a

Browse files
committed
fix: preserve dm archive behavior for other users on deactivation
Signed-off-by: Abhinav Kumar <abhinav@avitechlab.com>
1 parent 10ff7eb commit d39e70a

4 files changed

Lines changed: 43 additions & 3 deletions

File tree

apps/meteor/app/lib/server/functions/setUserActiveStatus.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { IUser, IUserEmail } from '@rocket.chat/core-typings';
22
import { isUserFederated, isDirectMessageRoom } from '@rocket.chat/core-typings';
3-
import { Rooms, Users } from '@rocket.chat/models';
3+
import { Rooms, Users, Subscriptions } from '@rocket.chat/models';
44
import { Accounts } from 'meteor/accounts-base';
55
import { check } from 'meteor/check';
66
import { Meteor } from 'meteor/meteor';
@@ -12,7 +12,12 @@ import { relinquishRoomOwnerships } from './relinquishRoomOwnerships';
1212
import { callbacks } from '../../../../server/lib/callbacks';
1313
import * as Mailer from '../../../mailer/server/api';
1414
import { settings } from '../../../settings/server';
15-
import { notifyOnRoomChangedById, notifyOnRoomChangedByUserDM, notifyOnUserChange } from '../lib/notifyListener';
15+
import {
16+
notifyOnRoomChangedById,
17+
notifyOnRoomChangedByUserDM,
18+
notifyOnSubscriptionChangedByNameAndRoomType,
19+
notifyOnUserChange,
20+
} from '../lib/notifyListener';
1621

1722
async function reactivateDirectConversations(userId: string) {
1823
// since both users can be deactivated at the same time, we should just reactivate rooms if both users are active
@@ -107,6 +112,13 @@ export async function setUserActiveStatus(
107112
await callbacks.run('afterDeactivateUser', user);
108113
}
109114

115+
if (user.username) {
116+
const { modifiedCount } = await Subscriptions.setArchivedForDMsWithUsername(user.username, !active);
117+
if (modifiedCount) {
118+
void notifyOnSubscriptionChangedByNameAndRoomType({ t: 'd', name: user.username });
119+
}
120+
}
121+
110122
if (active === false) {
111123
await Users.unsetLoginTokens(userId);
112124
await Rooms.setDmReadOnlyByUserId(userId, undefined, true, false);

apps/meteor/tests/unit/app/lib/server/functions/setUserActiveStatus.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ describe('setUserActiveStatus', () => {
2222
setDmReadOnlyByUserId: sandbox.stub(),
2323
getDirectConversationsByUserId: sandbox.stub(),
2424
},
25+
Subscriptions: {
26+
setArchivedForDMsWithUsername: sandbox.stub(),
27+
},
2528
check: sandbox.stub(),
2629
callbacks: {
2730
run: sandbox.stub(),
@@ -32,6 +35,7 @@ describe('setUserActiveStatus', () => {
3235
notifyOnUserChange: sandbox.stub(),
3336
notifyOnRoomChangedByUserDM: sandbox.stub(),
3437
notifyOnRoomChangedById: sandbox.stub(),
38+
notifyOnSubscriptionChangedByNameAndRoomType: sandbox.stub(),
3539
getSubscribedRoomsForUserWithDetails: sandbox.stub(),
3640
shouldRemoveOrChangeOwner: sandbox.stub(),
3741
getUserSingleOwnedRooms: sandbox.stub(),
@@ -56,7 +60,7 @@ describe('setUserActiveStatus', () => {
5660
'meteor/meteor': { Meteor: { Error } },
5761
'meteor/accounts-base': { Accounts: stubs.Accounts },
5862
'@rocket.chat/core-typings': { isUserFederated: stubs.isUserFederated, isDirectMessageRoom: sinon.stub() },
59-
'@rocket.chat/models': { Users: stubs.Users, Rooms: stubs.Rooms },
63+
'@rocket.chat/models': { Users: stubs.Users, Rooms: stubs.Rooms, Subscriptions: stubs.Subscriptions },
6064
'./closeOmnichannelConversations': { closeOmnichannelConversations: stubs.closeOmnichannelConversations },
6165
'./getRoomsWithSingleOwner': {
6266
shouldRemoveOrChangeOwner: stubs.shouldRemoveOrChangeOwner,
@@ -71,6 +75,7 @@ describe('setUserActiveStatus', () => {
7175
notifyOnRoomChangedById: stubs.notifyOnRoomChangedById,
7276
notifyOnRoomChangedByUserDM: stubs.notifyOnRoomChangedByUserDM,
7377
notifyOnUserChange: stubs.notifyOnUserChange,
78+
notifyOnSubscriptionChangedByNameAndRoomType: stubs.notifyOnSubscriptionChangedByNameAndRoomType,
7479
},
7580
});
7681

@@ -91,9 +96,11 @@ describe('setUserActiveStatus', () => {
9196
stubs.settings.get.returns(false);
9297
stubs.Rooms.setDmReadOnlyByUserId.resolves({ modifiedCount: 0 });
9398
stubs.Rooms.getDirectConversationsByUserId.returns({ toArray: sinon.stub().resolves([]) });
99+
stubs.Subscriptions.setArchivedForDMsWithUsername.resolves({ modifiedCount: 0 });
94100
stubs.notifyOnRoomChangedById.returns(undefined);
95101
stubs.notifyOnUserChange.returns(undefined);
96102
stubs.notifyOnRoomChangedByUserDM.returns(undefined);
103+
stubs.notifyOnSubscriptionChangedByNameAndRoomType.returns(undefined);
97104
});
98105

99106
afterEach(() => {
@@ -102,12 +109,16 @@ describe('setUserActiveStatus', () => {
102109

103110
describe('Successful status changes', () => {
104111
it('should deactivate a user successfully', async () => {
112+
stubs.Subscriptions.setArchivedForDMsWithUsername.resolves({ modifiedCount: 1 });
113+
105114
const result = await setUserActiveStatus(userId, false);
106115

107116
expect(result).to.be.true;
108117
expect(stubs.Users.setUserActive.calledWith(userId, false)).to.be.true;
109118
expect(stubs.Users.unsetLoginTokens.calledWith(userId)).to.be.true;
110119
expect(stubs.Rooms.setDmReadOnlyByUserId.calledWith(userId, undefined, true, false)).to.be.true;
120+
expect(stubs.Subscriptions.setArchivedForDMsWithUsername.calledWith(username, true)).to.be.true;
121+
expect(stubs.notifyOnSubscriptionChangedByNameAndRoomType.calledWith({ t: 'd', name: username })).to.be.true;
111122
expect(stubs.callbacks.run.calledWith('afterDeactivateUser', sinon.match({ _id: userId }))).to.be.true;
112123
expect(
113124
stubs.notifyOnUserChange.calledWith(
@@ -125,6 +136,7 @@ describe('setUserActiveStatus', () => {
125136
expect(result).to.be.true;
126137
expect(stubs.callbacks.run.calledWith('beforeActivateUser', sinon.match({ _id: userId }))).to.be.true;
127138
expect(stubs.Users.setUserActive.calledWith(userId, true)).to.be.true;
139+
expect(stubs.Subscriptions.setArchivedForDMsWithUsername.calledWith(username, false)).to.be.true;
128140
expect(stubs.callbacks.run.calledWith('afterActivateUser', sinon.match({ _id: userId }))).to.be.true;
129141
expect(stubs.Users.unsetReason.calledWith(userId)).to.be.true;
130142
expect(stubs.notifyOnUserChange.calledWith(sinon.match({ clientAction: 'updated', id: userId, diff: { active: true } }))).to.be.true;

packages/model-typings/src/models/ISubscriptionsModel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ export interface ISubscriptionsModel extends IBaseModel<ISubscription> {
287287
removeRoleById(_id: string, role: string): Promise<UpdateResult>;
288288
updateDirectFNameByName(name: string, fname: string): Promise<UpdateResult | Document>;
289289
setArchivedByUserId(userId: string, archived: boolean): Promise<UpdateResult | Document>;
290+
setArchivedForDMsWithUsername(username: string, archived: boolean): Promise<UpdateResult | Document>;
290291
updateUserHighlights(userId: string, userHighlights: any): Promise<UpdateResult | Document>;
291292
updateNotificationUserPreferences(
292293
userId: string,

packages/models/src/models/Subscriptions.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,21 @@ export class SubscriptionsRaw extends BaseRaw<ISubscription> implements ISubscri
17421742
return this.updateOne(query, update);
17431743
}
17441744

1745+
setArchivedForDMsWithUsername(username: string, archived: boolean): Promise<UpdateResult | Document> {
1746+
const query: Filter<ISubscription> = {
1747+
name: username,
1748+
t: 'd',
1749+
};
1750+
1751+
const update: UpdateFilter<ISubscription> = {
1752+
$set: {
1753+
archived,
1754+
},
1755+
};
1756+
1757+
return this.updateMany(query, update);
1758+
}
1759+
17451760
setArchivedByUserId(userId: string, archived: boolean): Promise<UpdateResult | Document> {
17461761
const query: Filter<ISubscription> = {
17471762
'u._id': userId,

0 commit comments

Comments
 (0)