diff --git a/.changeset/new-ears-check.md b/.changeset/new-ears-check.md new file mode 100644 index 0000000000000..1fe714395d59b --- /dev/null +++ b/.changeset/new-ears-check.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixes a UI issue where enabling/disabling email two factor authentication didn't update in real-time. diff --git a/apps/meteor/app/api/server/v1/users.ts b/apps/meteor/app/api/server/v1/users.ts index 071517822e33c..1927c4fabb419 100644 --- a/apps/meteor/app/api/server/v1/users.ts +++ b/apps/meteor/app/api/server/v1/users.ts @@ -888,15 +888,15 @@ API.v1.addRoute( // TODO this can be optmized so places that care about loginTokens being removed are invoked directly // instead of having to listen to every watch.users event void notifyOnUserChangeAsync(async () => { - const userTokens = await Users.findOneById(this.userId, { projection: { 'services.resume.loginTokens': 1 } }); - if (!userTokens) { + const user = await Users.findOneById(this.userId, { projection: { 'services.resume.loginTokens': 1, 'services.email2fa': 1 } }); + if (!user) { return; } return { clientAction: 'updated', id: this.user._id, - diff: { 'services.resume.loginTokens': userTokens.services?.resume?.loginTokens }, + diff: { 'services.resume.loginTokens': user.services?.resume?.loginTokens, 'services.email2fa': user.services?.email2fa }, }; }); @@ -912,6 +912,19 @@ API.v1.addRoute( async post() { await Users.disableEmail2FAByUserId(this.userId); + void notifyOnUserChangeAsync(async () => { + const user = await Users.findOneById(this.userId, { projection: { 'services.email2fa': 1 } }); + if (!user) { + return; + } + + return { + clientAction: 'updated', + id: this.user._id, + diff: { 'services.email2fa': user.services?.email2fa }, + }; + }); + return API.v1.success(); }, }, diff --git a/apps/meteor/tests/e2e/account-profile.spec.ts b/apps/meteor/tests/e2e/account-profile.spec.ts index c549a8b420c75..c8b7f4e277467 100644 --- a/apps/meteor/tests/e2e/account-profile.spec.ts +++ b/apps/meteor/tests/e2e/account-profile.spec.ts @@ -69,12 +69,35 @@ test.describe.serial('settings-account-profile', () => { }); test.describe('Security', () => { + test.beforeEach(async ({ page }) => { + await page.goto('account/security'); + await page.waitForSelector('.main-content'); + }); + test('should not have any accessibility violations', async ({ page, makeAxeBuilder }) => { await page.goto('/account/security'); const results = await makeAxeBuilder().analyze(); expect(results.violations).toEqual([]); }); + + test('expect to disable email 2FA', async () => { + await poAccountProfile.security2FASection.click(); + await expect(poAccountProfile.disableEmail2FAButton).toBeVisible(); + await poAccountProfile.disableEmail2FAButton.click(); + + await expect(poHomeChannel.toastSuccess).toBeVisible(); + await expect(poAccountProfile.enableEmail2FAButton).toBeVisible(); + }); + + test('expect to enable email 2FA', async () => { + await poAccountProfile.security2FASection.click(); + await expect(poAccountProfile.enableEmail2FAButton).toBeVisible(); + await poAccountProfile.enableEmail2FAButton.click(); + + await expect(poHomeChannel.toastSuccess).toBeVisible(); + await expect(poAccountProfile.disableEmail2FAButton).toBeVisible(); + }); }); test('Personal Access Tokens', async ({ page }) => { diff --git a/apps/meteor/tests/e2e/fixtures/collections/users.ts b/apps/meteor/tests/e2e/fixtures/collections/users.ts index 5baaccc101345..650d894e1fca0 100644 --- a/apps/meteor/tests/e2e/fixtures/collections/users.ts +++ b/apps/meteor/tests/e2e/fixtures/collections/users.ts @@ -16,7 +16,7 @@ export function createUserFixture(user: IUserState): UserFixture { _id: `${username}`, type: 'user', active: true, - emails: [{ address: `${username}@email.com`, verified: false }], + emails: [{ address: `${username}@email.com`, verified: true }], roles: ['user'], name: username, lastLogin: new Date(), diff --git a/apps/meteor/tests/e2e/page-objects/account-profile.ts b/apps/meteor/tests/e2e/page-objects/account-profile.ts index c1493a077fa43..de358b0df2dc4 100644 --- a/apps/meteor/tests/e2e/page-objects/account-profile.ts +++ b/apps/meteor/tests/e2e/page-objects/account-profile.ts @@ -123,4 +123,12 @@ export class AccountProfile { get btnSaveChanges(): Locator { return this.page.getByRole('button', { name: 'Save changes', exact: true }); } + + get enableEmail2FAButton(): Locator { + return this.page.locator('role=button[name="Enable two-factor authentication via Email"]'); + } + + get disableEmail2FAButton(): Locator { + return this.page.locator('role=button[name="Disable two-factor authentication via Email"]'); + } }