Skip to content

Commit 532604e

Browse files
authored
fix: prevent push notifications from being sent after logout (#37845)
1 parent 25a10b6 commit 532604e

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

.changeset/poor-apricots-heal.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@rocket.chat/meteor': patch
3+
---
4+
5+
Fixes push notifications continuing after logout due to missing token cleanup.

apps/meteor/server/services/push/service.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ export class PushService extends ServiceClassInternal implements IPushService {
1313
if (!('diff' in data) || !data.diff || !('services.resume.loginTokens' in data.diff)) {
1414
return;
1515
}
16-
if (data.diff['services.resume.loginTokens'] === undefined) {
16+
17+
const loginTokens = Array.isArray(data.diff['services.resume.loginTokens']) ? data.diff['services.resume.loginTokens'] : [];
18+
19+
if (data.diff['services.resume.loginTokens'] === undefined || loginTokens.length === 0) {
1720
await PushToken.removeAllByUserId(data.id);
1821
return;
1922
}
20-
const loginTokens = Array.isArray(data.diff['services.resume.loginTokens']) ? data.diff['services.resume.loginTokens'] : [];
2123
const tokens = loginTokens.map(({ hashedToken }: { hashedToken: string }) => hashedToken);
2224
if (tokens.length > 0) {
2325
await PushToken.removeByUserIdExceptTokens(data.id, tokens);

apps/meteor/tests/end-to-end/api/users.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4433,6 +4433,69 @@ describe('[Users]', () => {
44334433
})
44344434
.then(tryAuthentication);
44354435
});
4436+
4437+
it('should remove only logged out session push tokens', async () => {
4438+
const credentials1 = await login(user.username, password);
4439+
const credentials2 = await login(user.username, password);
4440+
4441+
await request
4442+
.post(api('push.token'))
4443+
.set(credentials1)
4444+
.send({
4445+
type: 'gcm',
4446+
value: 'device-1-token',
4447+
appName: 'com.example.device1',
4448+
})
4449+
.expect(200)
4450+
.expect((res) => {
4451+
expect(res.body).to.have.property('success', true);
4452+
});
4453+
4454+
await request
4455+
.post(api('push.token'))
4456+
.set(credentials2)
4457+
.send({
4458+
type: 'gcm',
4459+
value: 'device-2-token',
4460+
appName: 'com.example.device2',
4461+
})
4462+
.expect(200)
4463+
.expect((res) => {
4464+
expect(res.body).to.have.property('success', true);
4465+
});
4466+
4467+
await request
4468+
.post(api('users.logoutOtherClients'))
4469+
.set(credentials2)
4470+
.expect(200)
4471+
.expect((res) => {
4472+
expect(res.body).to.have.property('success', true);
4473+
});
4474+
4475+
await new Promise((resolve) => setTimeout(resolve, 1000));
4476+
4477+
await request
4478+
.delete(api('push.token'))
4479+
.set(credentials2)
4480+
.send({
4481+
token: 'device-1-token',
4482+
})
4483+
.expect(404)
4484+
.expect((res) => {
4485+
expect(res.body).to.have.property('success', false);
4486+
});
4487+
4488+
await request
4489+
.delete(api('push.token'))
4490+
.set(credentials2)
4491+
.send({
4492+
token: 'device-2-token',
4493+
})
4494+
.expect(200)
4495+
.expect((res) => {
4496+
expect(res.body).to.have.property('success', true);
4497+
});
4498+
});
44364499
});
44374500

44384501
describe('[/users.autocomplete]', () => {
@@ -4962,6 +5025,49 @@ describe('[Users]', () => {
49625025
void request.post(api('users.logout')).set(userCredentials).expect('Content-Type', 'application/json').expect(200).end(done);
49635026
});
49645027
});
5028+
5029+
it('should remove all push tokens when user logs out', async () => {
5030+
const testCredentials = await login(user.username, password);
5031+
5032+
await request
5033+
.post(api('push.token'))
5034+
.set(testCredentials)
5035+
.send({
5036+
type: 'gcm',
5037+
value: 'logout-test-token',
5038+
appName: 'com.example.logout.test',
5039+
})
5040+
.expect(200)
5041+
.expect((res) => {
5042+
expect(res.body).to.have.property('success', true);
5043+
});
5044+
5045+
await request
5046+
.post(api('users.logout'))
5047+
.set(testCredentials)
5048+
.send({
5049+
userId: user._id,
5050+
})
5051+
.expect(200)
5052+
.expect((res) => {
5053+
expect(res.body).to.have.property('success', true);
5054+
});
5055+
5056+
await new Promise((resolve) => setTimeout(resolve, 1000));
5057+
5058+
const newCredentials = await login(user.username, password);
5059+
5060+
await request
5061+
.delete(api('push.token'))
5062+
.set(newCredentials)
5063+
.send({
5064+
token: 'logout-test-token',
5065+
})
5066+
.expect(404)
5067+
.expect((res) => {
5068+
expect(res.body).to.have.property('success', false);
5069+
});
5070+
});
49655071
});
49665072

49675073
describe('[/users.listByStatus]', () => {

0 commit comments

Comments
 (0)