diff --git a/api/app/Services/MfaService.php b/api/app/Services/MfaService.php index dd61b091..fa9df915 100644 --- a/api/app/Services/MfaService.php +++ b/api/app/Services/MfaService.php @@ -34,16 +34,22 @@ final class MfaService /** * Begin TOTP setup: generate a secret and return QR code data. * MFA is NOT yet active — user must confirm with a valid code. + * If MFA is already enabled (re-setup or adding as second method), + * only the secret is rotated — confirmed_at and preferred method + * are preserved so a cancelled setup doesn't break the login flow. */ public function setupTotp(User $user): array { $secret = $this->google2fa->generateSecretKey(32); - $user->update([ - 'mfa_secret' => encrypt($secret), - 'mfa_method' => MfaMethod::TOTP->value, - 'mfa_confirmed_at' => null, - ]); + $updateData = ['mfa_secret' => encrypt($secret)]; + + if (! $user->mfa_enabled) { + $updateData['mfa_method'] = MfaMethod::TOTP->value; + $updateData['mfa_confirmed_at'] = null; + } + + $user->update($updateData); $qrCodeUrl = $this->google2fa->getQRCodeUrl( company: 'Crewli',