execute($request, $request->string('login')->toString(), $request->string('password')->toString()); if ($result['status'] === 'requires_2fa') { return response()->json(['requires_2fa' => true, 'challenge_token' => $result['challenge_token']]); } $audit->log($result['user'], 'auth.login'); return UserResource::make($result['user']); } public function verifyTwoFactor(TwoFactorChallengeRequest $request, VerifyTwoFactorAction $action, AuditLogger $audit) { $user = $action->execute($request, $request->string('challenge_token')->toString(), $request->string('code')->toString()); $audit->log($user, 'auth.2fa_verified'); return UserResource::make($user); } public function logout(Request $request, AuditLogger $audit) { $audit->log($request->user(), 'auth.logout'); Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return response()->noContent(); } public function me(Request $request) { return UserResource::make($request->user()); } public function enableTwoFactor(Request $request, TwoFactorService $twoFactor) { $user = $request->user(); $secret = $twoFactor->generateSecret(); // Stored but not yet "enabled" until confirmed with a valid code. $user->forceFill(['two_factor_secret' => $secret])->save(); return response()->json([ 'secret' => $secret, 'otpauth_url' => $twoFactor->otpAuthUrl($user, $secret), ]); } public function confirmTwoFactor(TwoFactorConfirmRequest $request, TwoFactorService $twoFactor, AuditLogger $audit) { $user = $request->user(); if (! $user->two_factor_secret || ! $twoFactor->verifyCode($user->two_factor_secret, $request->string('code')->toString())) { throw ValidationException::withMessages(['code' => 'That code is invalid.']); } $user->forceFill([ 'two_factor_enabled' => true, 'two_factor_confirmed_at' => now(), ])->save(); $recoveryCodes = $twoFactor->generateRecoveryCodes($user); $audit->log($user, 'auth.2fa_enabled'); return response()->json(['recovery_codes' => $recoveryCodes]); } public function disableTwoFactor(TwoFactorDisableRequest $request, AuditLogger $audit) { $user = $request->user(); if (! Hash::check($request->string('password')->toString(), $user->password)) { throw ValidationException::withMessages(['password' => 'That password is incorrect.']); } $user->twoFactorRecoveryCodes()->delete(); $user->forceFill([ 'two_factor_enabled' => false, 'two_factor_secret' => null, 'two_factor_confirmed_at' => null, ])->save(); $audit->log($user, 'auth.2fa_disabled'); return response()->noContent(); } }