mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 10:31:15 +00:00
fix: Require mfa code to change email (#10354)
This commit is contained in:
@@ -53,9 +53,14 @@ describe('MeController', () => {
|
||||
password: 'password',
|
||||
authIdentities: [],
|
||||
role: 'global:owner',
|
||||
mfaEnabled: false,
|
||||
});
|
||||
const reqBody = { email: 'valid@email.com', firstName: 'John', lastName: 'Potato' };
|
||||
const req = mock<MeRequest.UserUpdate>({ user, body: reqBody, browserId });
|
||||
const req = mock<MeRequest.UserUpdate>({ user, browserId });
|
||||
req.body = {
|
||||
email: 'valid@email.com',
|
||||
firstName: 'John',
|
||||
lastName: 'Potato',
|
||||
};
|
||||
const res = mock<Response>();
|
||||
userRepository.findOneByOrFail.mockResolvedValue(user);
|
||||
userRepository.findOneOrFail.mockResolvedValue(user);
|
||||
@@ -67,7 +72,7 @@ describe('MeController', () => {
|
||||
expect(externalHooks.run).toHaveBeenCalledWith('user.profile.beforeUpdate', [
|
||||
user.id,
|
||||
user.email,
|
||||
reqBody,
|
||||
req.body,
|
||||
]);
|
||||
|
||||
expect(userService.update).toHaveBeenCalled();
|
||||
@@ -98,25 +103,25 @@ describe('MeController', () => {
|
||||
password: 'password',
|
||||
authIdentities: [],
|
||||
role: 'global:member',
|
||||
mfaEnabled: false,
|
||||
});
|
||||
const reqBody = { email: 'valid@email.com', firstName: 'John', lastName: 'Potato' };
|
||||
const req = mock<MeRequest.UserUpdate>({ user, browserId });
|
||||
req.body = reqBody;
|
||||
req.body = { email: 'valid@email.com', firstName: 'John', lastName: 'Potato' };
|
||||
const res = mock<Response>();
|
||||
userRepository.findOneOrFail.mockResolvedValue(user);
|
||||
jest.spyOn(jwt, 'sign').mockImplementation(() => 'signed-token');
|
||||
|
||||
// Add invalid data to the request payload
|
||||
Object.assign(reqBody, { id: '0', role: 'global:owner' });
|
||||
Object.assign(req.body, { id: '0', role: 'global:owner' });
|
||||
|
||||
await controller.updateCurrentUser(req, res);
|
||||
|
||||
expect(userService.update).toHaveBeenCalled();
|
||||
|
||||
const updatePayload = userService.update.mock.calls[0][1];
|
||||
expect(updatePayload.email).toBe(reqBody.email);
|
||||
expect(updatePayload.firstName).toBe(reqBody.firstName);
|
||||
expect(updatePayload.lastName).toBe(reqBody.lastName);
|
||||
expect(updatePayload.email).toBe(req.body.email);
|
||||
expect(updatePayload.firstName).toBe(req.body.firstName);
|
||||
expect(updatePayload.lastName).toBe(req.body.lastName);
|
||||
expect(updatePayload.id).toBeUndefined();
|
||||
expect(updatePayload.role).toBeUndefined();
|
||||
});
|
||||
@@ -127,10 +132,11 @@ describe('MeController', () => {
|
||||
password: 'password',
|
||||
authIdentities: [],
|
||||
role: 'global:owner',
|
||||
mfaEnabled: false,
|
||||
});
|
||||
const reqBody = { email: 'valid@email.com', firstName: 'John', lastName: 'Potato' };
|
||||
const req = mock<MeRequest.UserUpdate>({ user, body: reqBody });
|
||||
// userService.findOneOrFail.mockResolvedValue(user);
|
||||
req.body = reqBody; // We don't want the body to be a mock object
|
||||
|
||||
externalHooks.run.mockImplementationOnce(async (hookName) => {
|
||||
if (hookName === 'user.profile.beforeUpdate') {
|
||||
@@ -142,6 +148,76 @@ describe('MeController', () => {
|
||||
new BadRequestError('Invalid email address'),
|
||||
);
|
||||
});
|
||||
|
||||
describe('when mfa is enabled', () => {
|
||||
it('should throw BadRequestError if mfa code is missing', async () => {
|
||||
const user = mock<User>({
|
||||
id: '123',
|
||||
email: 'valid@email.com',
|
||||
password: 'password',
|
||||
authIdentities: [],
|
||||
role: 'global:owner',
|
||||
mfaEnabled: true,
|
||||
});
|
||||
const req = mock<MeRequest.UserUpdate>({ user, browserId });
|
||||
req.body = { email: 'new@email.com', firstName: 'John', lastName: 'Potato' };
|
||||
|
||||
await expect(controller.updateCurrentUser(req, mock())).rejects.toThrowError(
|
||||
new BadRequestError('Two-factor code is required to change email'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw InvalidMfaCodeError if mfa code is invalid', async () => {
|
||||
const user = mock<User>({
|
||||
id: '123',
|
||||
email: 'valid@email.com',
|
||||
password: 'password',
|
||||
authIdentities: [],
|
||||
role: 'global:owner',
|
||||
mfaEnabled: true,
|
||||
});
|
||||
const req = mock<MeRequest.UserUpdate>({ user, browserId });
|
||||
req.body = {
|
||||
email: 'new@email.com',
|
||||
firstName: 'John',
|
||||
lastName: 'Potato',
|
||||
mfaCode: 'invalid',
|
||||
};
|
||||
mockMfaService.validateMfa.mockResolvedValue(false);
|
||||
|
||||
await expect(controller.updateCurrentUser(req, mock())).rejects.toThrow(
|
||||
InvalidMfaCodeError,
|
||||
);
|
||||
});
|
||||
|
||||
it("should update the user's email if mfa code is valid", async () => {
|
||||
const user = mock<User>({
|
||||
id: '123',
|
||||
email: 'valid@email.com',
|
||||
password: 'password',
|
||||
authIdentities: [],
|
||||
role: 'global:owner',
|
||||
mfaEnabled: true,
|
||||
});
|
||||
const req = mock<MeRequest.UserUpdate>({ user, browserId });
|
||||
req.body = {
|
||||
email: 'new@email.com',
|
||||
firstName: 'John',
|
||||
lastName: 'Potato',
|
||||
mfaCode: '123456',
|
||||
};
|
||||
const res = mock<Response>();
|
||||
userRepository.findOneByOrFail.mockResolvedValue(user);
|
||||
userRepository.findOneOrFail.mockResolvedValue(user);
|
||||
jest.spyOn(jwt, 'sign').mockImplementation(() => 'signed-token');
|
||||
userService.toPublic.mockResolvedValue({} as unknown as PublicUser);
|
||||
mockMfaService.validateMfa.mockResolvedValue(true);
|
||||
|
||||
const result = await controller.updateCurrentUser(req, res);
|
||||
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('updatePassword', () => {
|
||||
|
||||
Reference in New Issue
Block a user