fix: Require mfa code for password change if its enabled (#10341)

This commit is contained in:
Tomi Turtiainen
2024-08-12 17:08:55 +03:00
committed by GitHub
parent 2580a5e19e
commit 9d7caacc69
10 changed files with 141 additions and 26 deletions

View File

@@ -23,6 +23,8 @@ import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { UserRepository } from '@/databases/repositories/user.repository';
import { isApiEnabled } from '@/PublicApi';
import { EventService } from '@/events/event.service';
import { MfaService } from '@/Mfa/mfa.service';
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
export const API_KEY_PREFIX = 'n8n_api_';
@@ -44,6 +46,7 @@ export class MeController {
private readonly passwordUtility: PasswordUtility,
private readonly userRepository: UserRepository,
private readonly eventService: EventService,
private readonly mfaService: MfaService,
) {}
/**
@@ -115,12 +118,12 @@ export class MeController {
/**
* Update the logged-in user's password.
*/
@Patch('/password')
@Patch('/password', { rateLimit: true })
async updatePassword(req: MeRequest.Password, res: Response) {
const { user } = req;
const { currentPassword, newPassword } = req.body;
const { currentPassword, newPassword, mfaCode } = req.body;
// If SAML is enabled, we don't allow the user to change their email address
// If SAML is enabled, we don't allow the user to change their password
if (isSamlLicensedAndEnabled()) {
this.logger.debug('Attempted to change password for user, while SAML is enabled', {
userId: user.id,
@@ -145,6 +148,17 @@ export class MeController {
const validPassword = this.passwordUtility.validate(newPassword);
if (user.mfaEnabled) {
if (typeof mfaCode !== 'string') {
throw new BadRequestError('Two-factor code is required to change password.');
}
const isMfaTokenValid = await this.mfaService.validateMfa(user.id, mfaCode, undefined);
if (!isMfaTokenValid) {
throw new ForbiddenError('Invalid two-factor code.');
}
}
user.password = await this.passwordUtility.hash(validPassword);
const updatedUser = await this.userRepository.save(user, { transaction: false });