From 3cdef7a0f60708c8857d38a9960aac549d701bf6 Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Tue, 12 Mar 2024 00:56:29 +0530 Subject: [PATCH 1/8] stream force logout event on keys reset --- apps/meteor/server/lib/resetUserE2EKey.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/meteor/server/lib/resetUserE2EKey.ts b/apps/meteor/server/lib/resetUserE2EKey.ts index 9ebaa7369a01..4c35fd7430f4 100644 --- a/apps/meteor/server/lib/resetUserE2EKey.ts +++ b/apps/meteor/server/lib/resetUserE2EKey.ts @@ -3,6 +3,7 @@ import { Meteor } from 'meteor/meteor'; import * as Mailer from '../../app/mailer/server/api'; import { settings } from '../../app/settings/server'; +import { Notifications } from '../../app/notifications/server'; import { i18n } from './i18n'; import { isUserIdFederated } from './isUserIdFederated'; @@ -64,6 +65,9 @@ export async function resetUserE2EEncriptionKey(uid: string, notifyUser: boolean throw new Meteor.Error('error-not-allowed', 'Federated Users cant have TOTP', { function: 'resetTOTP' }); } + // force logout the live sessions + Notifications.notifyUser(uid, 'force_logout'); + await Users.resetE2EKey(uid); await Subscriptions.resetUserE2EKey(uid); From 8d54d6035b8af4d2420bc0e0b513c535a34367ae Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Tue, 12 Mar 2024 00:57:38 +0530 Subject: [PATCH 2/8] add cs --- .changeset/eighty-pans-joke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eighty-pans-joke.md diff --git a/.changeset/eighty-pans-joke.md b/.changeset/eighty-pans-joke.md new file mode 100644 index 000000000000..77552bb06d39 --- /dev/null +++ b/.changeset/eighty-pans-joke.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +Force logout live clients on E2EE keys reset From 10df1e99fcc22cbc2a6c3b81f6d67e912ef1f8be Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Tue, 12 Mar 2024 01:32:24 +0530 Subject: [PATCH 3/8] force logout banner text --- packages/i18n/src/locales/en.i18n.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index aebd4c14ed70..e4c322e21278 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -3262,7 +3262,7 @@ "Log_Trace_Subscriptions_Filter": "Trace subscription filter", "Log_Trace_Subscriptions_Filter_Description": "The text here will be evaluated as RegExp (`new RegExp('text')`). Keep it empty to show trace of every call.", "Log_View_Limit": "Log View Limit", - "Logged_Out_Banner_Text": "Your workspace admin ended your session on this device. Please log in again to continue.", + "Logged_Out_Banner_Text": "Your session was ended on this device, please log in again to continue.", "Logged_out_of_other_clients_successfully": "Logged out of other clients successfully", "Login": "Login", "Log_in_to_sync": "Log in to sync", From 0ddc5310705e228729e61ec70213237dae1105b6 Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Tue, 12 Mar 2024 01:34:37 +0530 Subject: [PATCH 4/8] import order --- apps/meteor/server/lib/resetUserE2EKey.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/server/lib/resetUserE2EKey.ts b/apps/meteor/server/lib/resetUserE2EKey.ts index 4c35fd7430f4..01594d924970 100644 --- a/apps/meteor/server/lib/resetUserE2EKey.ts +++ b/apps/meteor/server/lib/resetUserE2EKey.ts @@ -2,8 +2,8 @@ import { Subscriptions, Users } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; import * as Mailer from '../../app/mailer/server/api'; -import { settings } from '../../app/settings/server'; import { Notifications } from '../../app/notifications/server'; +import { settings } from '../../app/settings/server'; import { i18n } from './i18n'; import { isUserIdFederated } from './isUserIdFederated'; From cf79cd61df40a13912e0e40e822ab90d9096db90 Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Tue, 12 Mar 2024 21:32:03 +0530 Subject: [PATCH 5/8] add e2e tests --- apps/meteor/tests/e2e/e2e-encryption.spec.ts | 30 +++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts index dc10729f3b79..3f2947a63b31 100644 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption.spec.ts @@ -1,5 +1,6 @@ import { faker } from '@faker-js/faker'; +import { createAuxContext } from './fixtures/createAuxContext'; import injectInitialData from './fixtures/inject-initial-data'; import { Users, storeState, restoreState } from './fixtures/userStates'; import { AccountProfile, HomeChannel } from './page-objects'; @@ -134,7 +135,6 @@ test.describe.serial('e2e-encryption', () => { expect(statusCode).toBe(200); poHomeChannel = new HomeChannel(page); - await page.goto('/home'); }); @@ -212,4 +212,32 @@ test.describe.serial('e2e-encryption', () => { await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); }); + + test('expect force logout on e2e keys reset', async ({ page, browser }) => { + const poAccountProfile = new AccountProfile(page); + // creating another logged in client, to check force logout + const { page: anotherClientPage } = await createAuxContext(browser, Users.admin); + + await page.goto('/account/security'); + + await poAccountProfile.securityE2EEncryptionSection.click(); + await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); + + await page.locator('role=button[name="Login"]').waitFor(); + await anotherClientPage.locator('role=button[name="Login"]').waitFor(); + + await expect(page).toHaveURL('/home'); + await expect(anotherClientPage).toHaveURL('/home'); + + await expect(page.locator('role=button[name="Login"]')).toBeVisible(); + await expect(anotherClientPage.locator('role=button[name="Login"]')).toBeVisible(); + + await expect(page.locator('role=banner')).toContainText('Your session was ended on this device, please log in again to continue.'); + await expect(anotherClientPage.locator('role=banner')).toContainText('Your session was ended on this device, please log in again to continue.'); + + await anotherClientPage.close(); + + // inject initial data, so that tokens are restored after forced logout + await injectInitialData(); + }); }); From 3afc8fe8e18dc6423445934fe9abd926bc642945 Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Tue, 12 Mar 2024 23:53:00 +0530 Subject: [PATCH 6/8] fix review --- apps/meteor/tests/e2e/e2e-encryption.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts index 3f2947a63b31..775e80c50139 100644 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption.spec.ts @@ -142,6 +142,9 @@ test.describe.serial('e2e-encryption', () => { const statusCode = (await api.post('/settings/E2E_Enable', { value: false })).status(); await expect(statusCode).toBe(200); + + // inject initial data, so that tokens are restored after forced logout + await injectInitialData(); }); test('expect create a private channel encrypted and send an encrypted message', async ({ page }) => { @@ -236,8 +239,5 @@ test.describe.serial('e2e-encryption', () => { await expect(anotherClientPage.locator('role=banner')).toContainText('Your session was ended on this device, please log in again to continue.'); await anotherClientPage.close(); - - // inject initial data, so that tokens are restored after forced logout - await injectInitialData(); }); }); From ac7b3bd417a4bd063f5a39cf136bf3a982ba5f59 Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Wed, 13 Mar 2024 18:57:37 +0530 Subject: [PATCH 7/8] oops --- apps/meteor/tests/e2e/e2e-encryption.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts index 775e80c50139..3ba9083101d9 100644 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption.spec.ts @@ -139,12 +139,12 @@ test.describe.serial('e2e-encryption', () => { }); test.afterAll(async ({ api }) => { + // inject initial data, so that tokens are restored after forced logout + await injectInitialData(); + const statusCode = (await api.post('/settings/E2E_Enable', { value: false })).status(); await expect(statusCode).toBe(200); - - // inject initial data, so that tokens are restored after forced logout - await injectInitialData(); }); test('expect create a private channel encrypted and send an encrypted message', async ({ page }) => { From 3348daa2478e461c58708576e7ce49aaf00b466e Mon Sep 17 00:00:00 2001 From: yash-rajpal Date: Wed, 13 Mar 2024 19:57:47 +0530 Subject: [PATCH 8/8] update CS --- .changeset/eighty-pans-joke.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/eighty-pans-joke.md b/.changeset/eighty-pans-joke.md index 77552bb06d39..83eabdd8f856 100644 --- a/.changeset/eighty-pans-joke.md +++ b/.changeset/eighty-pans-joke.md @@ -1,5 +1,5 @@ --- -'@rocket.chat/meteor': minor +'@rocket.chat/meteor': patch --- -Force logout live clients on E2EE keys reset +Force logout the clients which are actively online, whenever a user resets E2EE keys.