diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts index 6d530aba3b..77c4351cb6 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts @@ -61,10 +61,15 @@ export default class extends Endpoint { private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); + const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); + if (!passwordMatched) { + throw new ApiError(meta.errors.incorrectPassword); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -74,14 +79,7 @@ export default class extends Endpoint { } catch (e) { throw new Error('authentication failed'); } - } - - const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); - if (!passwordMatched) { - throw new ApiError(meta.errors.incorrectPassword); - } - - if (!profile.twoFactorEnabled) { + } else { throw new ApiError(meta.errors.twoFactorNotEnabled); } diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts index c39005f2dd..66cb69d46f 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts @@ -58,7 +58,6 @@ export default class extends Endpoint { private userAuthService: UserAuthService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOne({ where: { userId: me.id, @@ -70,7 +69,13 @@ export default class extends Endpoint { throw new ApiError(meta.errors.userNotFound); } + const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); + if (!passwordMatched) { + throw new ApiError(meta.errors.incorrectPassword); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -80,14 +85,7 @@ export default class extends Endpoint { } catch (e) { throw new Error('authentication failed'); } - } - - const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); - if (!passwordMatched) { - throw new ApiError(meta.errors.incorrectPassword); - } - - if (!profile.twoFactorEnabled) { + } else { throw new ApiError(meta.errors.twoFactorNotEnabled); } diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register.ts b/packages/backend/src/server/api/endpoints/i/2fa/register.ts index b358c812ee..160af7a35c 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register.ts @@ -49,10 +49,15 @@ export default class extends Endpoint { // eslint- private userAuthService: UserAuthService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); + const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); + if (!passwordMatched) { + throw new ApiError(meta.errors.incorrectPassword); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -64,11 +69,6 @@ export default class extends Endpoint { // eslint- } } - const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); - if (!passwordMatched) { - throw new ApiError(meta.errors.incorrectPassword); - } - // Generate user's secret key const secret = new OTPAuth.Secret(); diff --git a/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts index da8ac98556..3e2a3c7d39 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts @@ -51,10 +51,15 @@ export default class extends Endpoint { // eslint- private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); + const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); + if (!passwordMatched) { + throw new ApiError(meta.errors.incorrectPassword); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -66,11 +71,6 @@ export default class extends Endpoint { // eslint- } } - const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); - if (!passwordMatched) { - throw new ApiError(meta.errors.incorrectPassword); - } - // Make sure we only delete the user's own creds await this.userSecurityKeysRepository.delete({ userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts b/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts index 338f12c5cd..c008a983bf 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts @@ -47,10 +47,15 @@ export default class extends Endpoint { // eslint- private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); + const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); + if (!passwordMatched) { + throw new ApiError(meta.errors.incorrectPassword); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -62,11 +67,6 @@ export default class extends Endpoint { // eslint- } } - const passwordMatched = await bcrypt.compare(ps.password, profile.password ?? ''); - if (!passwordMatched) { - throw new ApiError(meta.errors.incorrectPassword); - } - await this.userProfilesRepository.update(me.id, { twoFactorSecret: null, twoFactorBackupSecret: null, diff --git a/packages/backend/src/server/api/endpoints/i/change-password.ts b/packages/backend/src/server/api/endpoints/i/change-password.ts index a3c37ffdb7..d5042d7564 100644 --- a/packages/backend/src/server/api/endpoints/i/change-password.ts +++ b/packages/backend/src/server/api/endpoints/i/change-password.ts @@ -35,10 +35,15 @@ export default class extends Endpoint { // eslint- private userAuthService: UserAuthService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); + const passwordMatched = await bcrypt.compare(ps.currentPassword, profile.password!); + if (!passwordMatched) { + throw new Error('incorrect password'); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -50,12 +55,6 @@ export default class extends Endpoint { // eslint- } } - const passwordMatched = await bcrypt.compare(ps.currentPassword, profile.password!); - - if (!passwordMatched) { - throw new Error('incorrect password'); - } - // Generate hash of password const salt = await bcrypt.genSalt(8); const hash = await bcrypt.hash(ps.newPassword, salt); diff --git a/packages/backend/src/server/api/endpoints/i/delete-account.ts b/packages/backend/src/server/api/endpoints/i/delete-account.ts index eb5379c171..9c08863ae2 100644 --- a/packages/backend/src/server/api/endpoints/i/delete-account.ts +++ b/packages/backend/src/server/api/endpoints/i/delete-account.ts @@ -40,21 +40,8 @@ export default class extends Endpoint { // eslint- private deleteAccountService: DeleteAccountService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); - if (profile.twoFactorEnabled) { - if (token == null) { - throw new Error('authentication failed'); - } - - try { - await this.userAuthService.twoFactorAuthenticate(profile, token); - } catch (e) { - throw new Error('authentication failed'); - } - } - const userDetailed = await this.usersRepository.findOneByOrFail({ id: me.id }); if (userDetailed.isDeleted) { return; @@ -65,6 +52,19 @@ export default class extends Endpoint { // eslint- throw new Error('incorrect password'); } + if (profile.twoFactorEnabled) { + const token = ps.token; + if (token == null) { + throw new Error('authentication failed'); + } + + try { + await this.userAuthService.twoFactorAuthenticate(profile, token); + } catch (e) { + throw new Error('authentication failed'); + } + } + await this.deleteAccountService.deleteAccount(me); }); } diff --git a/packages/backend/src/server/api/endpoints/i/update-email.ts b/packages/backend/src/server/api/endpoints/i/update-email.ts index 941f531f0a..55bd402f26 100644 --- a/packages/backend/src/server/api/endpoints/i/update-email.ts +++ b/packages/backend/src/server/api/endpoints/i/update-email.ts @@ -68,10 +68,15 @@ export default class extends Endpoint { // eslint- private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - const token = ps.token; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id }); + const passwordMatched = await bcrypt.compare(ps.password, profile.password!); + if (!passwordMatched) { + throw new ApiError(meta.errors.incorrectPassword); + } + if (profile.twoFactorEnabled) { + const token = ps.token; if (token == null) { throw new Error('authentication failed'); } @@ -83,11 +88,6 @@ export default class extends Endpoint { // eslint- } } - const passwordMatched = await bcrypt.compare(ps.password, profile.password!); - if (!passwordMatched) { - throw new ApiError(meta.errors.incorrectPassword); - } - if (ps.email != null) { const res = await this.emailService.validateEmailForAccount(ps.email); if (!res.available) {