From 303bc8e71e60c3ee8ccd6b823814945d892e3726 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Thu, 21 Sep 2023 05:56:40 -0400 Subject: [PATCH] fix: Issue enforcing user limits on start plan (#7188) --- .../controllers/passwordReset.controller.ts | 2 +- .../integration/passwordReset.api.test.ts | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/controllers/passwordReset.controller.ts b/packages/cli/src/controllers/passwordReset.controller.ts index 838413c319..b3d8de193f 100644 --- a/packages/cli/src/controllers/passwordReset.controller.ts +++ b/packages/cli/src/controllers/passwordReset.controller.ts @@ -231,7 +231,7 @@ export class PasswordResetController { const user = await this.userService.findOne({ where: { id: decodedToken.sub }, - relations: ['authIdentities'], + relations: ['authIdentities', 'globalRole'], }); if (!user) { diff --git a/packages/cli/test/integration/passwordReset.api.test.ts b/packages/cli/test/integration/passwordReset.api.test.ts index 5140820b30..f3dfe483a3 100644 --- a/packages/cli/test/integration/passwordReset.api.test.ts +++ b/packages/cli/test/integration/passwordReset.api.test.ts @@ -1,5 +1,6 @@ import { v4 as uuid } from 'uuid'; import { compare } from 'bcryptjs'; +import { License } from '@/License'; import * as Db from '@/Db'; import config from '@/config'; @@ -25,12 +26,14 @@ config.set('userManagement.jwtSecret', randomString(5, 10)); let globalOwnerRole: Role; let globalMemberRole: Role; let owner: User; +let member: User; const externalHooks = utils.mockInstance(ExternalHooks); const testServer = utils.setupTestServer({ endpointGroups: ['passwordReset'] }); const jwtService = Container.get(JwtService); beforeAll(async () => { + await utils.initEncryptionKey(); globalOwnerRole = await testDb.getGlobalOwnerRole(); globalMemberRole = await testDb.getGlobalMemberRole(); }); @@ -38,6 +41,7 @@ beforeAll(async () => { beforeEach(async () => { await testDb.truncate(['User']); owner = await testDb.createUser({ globalRole: globalOwnerRole }); + member = await testDb.createUser({ globalRole: globalMemberRole }); externalHooks.run.mockReset(); }); @@ -253,4 +257,46 @@ describe('POST /change-password', () => { expect(externalHooks.run).not.toHaveBeenCalled(); }); + + test('owner should be able to reset its password when quota:users = 1', async () => { + jest.spyOn(Container.get(License), 'getUsersLimit').mockReturnValueOnce(1); + + const resetPasswordToken = jwtService.signData({ sub: owner.id }); + const response = await testServer.authlessAgent.post('/change-password').send({ + token: resetPasswordToken, + userId: owner.id, + password: passwordToStore, + }); + + expect(response.statusCode).toBe(200); + + const authToken = utils.getAuthToken(response); + expect(authToken).toBeDefined(); + + const { password: storedPassword } = await Db.collections.User.findOneByOrFail({ + id: owner.id, + }); + + const comparisonResult = await compare(passwordToStore, storedPassword); + expect(comparisonResult).toBe(true); + expect(storedPassword).not.toBe(passwordToStore); + + expect(externalHooks.run).toHaveBeenCalledWith('user.password.update', [ + owner.email, + storedPassword, + ]); + }); + + test('member should not be able to reset its password when quota:users = 1', async () => { + jest.spyOn(Container.get(License), 'getUsersLimit').mockReturnValueOnce(1); + + const resetPasswordToken = jwtService.signData({ sub: member.id }); + const response = await testServer.authlessAgent.post('/change-password').send({ + token: resetPasswordToken, + userId: member.id, + password: passwordToStore, + }); + + expect(response.statusCode).toBe(403); + }); });