diff --git a/.changeset/wise-pianos-explode.md b/.changeset/wise-pianos-explode.md new file mode 100644 index 000000000000..3473275e20ab --- /dev/null +++ b/.changeset/wise-pianos-explode.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixed issue with external users being able to reset their passwords even when the "Allow Password Change for OAuth Users" setting is disabled diff --git a/apps/meteor/server/methods/sendForgotPasswordEmail.ts b/apps/meteor/server/methods/sendForgotPasswordEmail.ts index 474d9bf06e46..b77f6318a324 100644 --- a/apps/meteor/server/methods/sendForgotPasswordEmail.ts +++ b/apps/meteor/server/methods/sendForgotPasswordEmail.ts @@ -20,7 +20,7 @@ Meteor.methods({ const email = to.trim().toLowerCase(); - const user = await Users.findOneByEmailAddress(email, { projection: { _id: 1 } }); + const user = await Users.findOneByEmailAddress(email, { projection: { _id: 1, services: 1 } }); if (!user) { return true; diff --git a/apps/meteor/tests/e2e/saml.spec.ts b/apps/meteor/tests/e2e/saml.spec.ts index dc18aeae37c3..8859e46e71c5 100644 --- a/apps/meteor/tests/e2e/saml.spec.ts +++ b/apps/meteor/tests/e2e/saml.spec.ts @@ -12,6 +12,7 @@ import { Users } from './fixtures/userStates'; import { Registration } from './page-objects'; import { createCustomRole, deleteCustomRole } from './utils/custom-role'; import { getUserInfo } from './utils/getUserInfo'; +import { parseMeteorResponse } from './utils/parseMeteorResponse'; import { setSettingValueById } from './utils/setSettingValueById'; import { test, expect, BaseTest } from './utils/test'; @@ -195,6 +196,30 @@ test.describe('SAML', () => { }); }); + test('Allow password change for OAuth users', async ({ api }) => { + await test.step("should not send password reset mail if 'Allow Password Change for OAuth Users' setting is disabled", async () => { + expect((await setSettingValueById(api, 'Accounts_AllowPasswordChangeForOAuthUsers', false)).status()).toBe(200); + + const response = await api.post('/method.call/sendForgotPasswordEmail', { + message: JSON.stringify({ msg: 'method', id: 'id', method: 'sendForgotPasswordEmail', params: ['samluser1@example.com'] }), + }); + const mailSent = await parseMeteorResponse(response); + expect(response.status()).toBe(200); + expect(mailSent).toBe(false); + }); + + await test.step("should send password reset mail if 'Allow Password Change for OAuth Users' setting is enabled", async () => { + expect((await setSettingValueById(api, 'Accounts_AllowPasswordChangeForOAuthUsers', true)).status()).toBe(200); + + const response = await api.post('/method.call/sendForgotPasswordEmail', { + message: JSON.stringify({ msg: 'method', id: 'id', method: 'sendForgotPasswordEmail', params: ['samluser1@example.com'] }), + }); + const mailSent = await parseMeteorResponse(response); + expect(response.status()).toBe(200); + expect(mailSent).toBe(true); + }); + }); + const doLoginStep = async (page: Page, username: string, redirectUrl: string | null = '/home') => { await test.step('expect successful login', async () => { await poRegistration.btnLoginWithSaml.click(); diff --git a/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts b/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts index 308e6f4460a4..f92ff9244ec5 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/monitors.ts @@ -1,5 +1,5 @@ +import { parseMeteorResponse } from '../parseMeteorResponse'; import { BaseTest } from '../test'; -import { parseMeteorResponse } from './utils'; const removeMonitor = async (api: BaseTest['api'], id: string) => api.post('/method.call/livechat:removeMonitor', { diff --git a/apps/meteor/tests/e2e/utils/omnichannel/tags.ts b/apps/meteor/tests/e2e/utils/omnichannel/tags.ts index 078ca8dd02f7..169f4825bd75 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/tags.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/tags.ts @@ -1,7 +1,7 @@ import { ILivechatTag } from '@rocket.chat/core-typings'; +import { parseMeteorResponse } from '../parseMeteorResponse'; import { BaseTest } from '../test'; -import { parseMeteorResponse } from './utils'; type CreateTagParams = { id?: string | null; diff --git a/apps/meteor/tests/e2e/utils/omnichannel/units.ts b/apps/meteor/tests/e2e/utils/omnichannel/units.ts index fa872a37eae6..bbc37ed12df8 100644 --- a/apps/meteor/tests/e2e/utils/omnichannel/units.ts +++ b/apps/meteor/tests/e2e/utils/omnichannel/units.ts @@ -1,8 +1,8 @@ import { faker } from '@faker-js/faker'; import { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings'; +import { parseMeteorResponse } from '../parseMeteorResponse'; import { BaseTest } from '../test'; -import { parseMeteorResponse } from './utils'; type CreateUnitParams = { id?: string | null; diff --git a/apps/meteor/tests/e2e/utils/omnichannel/utils.ts b/apps/meteor/tests/e2e/utils/parseMeteorResponse.ts similarity index 100% rename from apps/meteor/tests/e2e/utils/omnichannel/utils.ts rename to apps/meteor/tests/e2e/utils/parseMeteorResponse.ts