validate([ 'challenge' => ['required', 'string', 'size:64'], 'code' => ['required', 'digits:6'], 'remember_device' => ['sometimes', 'boolean'], ]); $customer = $twoFactor->verifyLoginChallenge($data['challenge'], $data['code']); $extra = []; if ($request->boolean('remember_device')) { $extra = [ 'device_token' => $twoFactor->rememberDevice($customer, $request->userAgent(), $request->ip()), 'device_expires_in' => ClientTwoFactorService::TRUSTED_DEVICE_DAYS * 86400, ]; } return $this->loginResponse($this->authService->issueTokens($customer), $extra); } public function resendLoginTwoFactor(Request $request, ClientTwoFactorService $twoFactor) { $data = $request->validate(['challenge' => ['required', 'string', 'size:64']]); $twoFactor->resendLoginChallenge($data['challenge']); return response()->json(['error' => false, 'message' => 'Đã gửi lại mã xác thực.']); } public function twoFactorStatus(ClientTwoFactorService $twoFactor) { $customer = auth('client')->user(); return response()->json([ 'error' => false, 'data' => [ 'enabled' => (bool) $customer->two_factor_enabled, 'devices' => $twoFactor->devices($customer)->map(fn (CustomerTrustedDevice $device) => [ 'id' => $device->id, 'user_agent' => $device->user_agent, 'ip_address' => $device->ip_address, 'last_used_at' => $device->last_used_at?->toIso8601String(), 'expires_at' => $device->expires_at->toIso8601String(), ]), ], ]); } public function sendTwoFactorSetupCode(ClientTwoFactorService $twoFactor) { $twoFactor->sendSetupCode(auth('client')->user()); return response()->json([ 'error' => false, 'message' => 'Đã gửi mã xác thực tới email của bạn.', 'data' => ['resend_in' => ClientTwoFactorService::RESEND_COOLDOWN_SECONDS], ]); } public function enableTwoFactor(Request $request, ClientTwoFactorService $twoFactor) { $data = $request->validate(['code' => ['required', 'digits:6']]); $customer = auth('client')->user(); $twoFactor->enable($customer, $data['code']); $this->activityLogger->log( event: 'two_factor_enabled', logName: 'Customer', description: "Customer {$customer->email} bật xác thực 2 lớp", subject: $customer, ); return response()->json(['error' => false, 'message' => 'Đã bật xác thực 2 lớp.']); } public function disableTwoFactor(Request $request, ClientTwoFactorService $twoFactor) { $data = $request->validate(['password' => ['required', 'string']]); $customer = auth('client')->user(); $twoFactor->disable($customer, $data['password']); $this->activityLogger->log( event: 'two_factor_disabled', logName: 'Customer', description: "Customer {$customer->email} tắt xác thực 2 lớp", subject: $customer, ); return response()->json(['error' => false, 'message' => 'Đã tắt xác thực 2 lớp.']); } public function revokeTrustedDevices(Request $request, ClientTwoFactorService $twoFactor) { $twoFactor->revokeDevices(auth('client')->user(), $request->integer('id') ?: null); return response()->json(['error' => false, 'message' => 'Đã xoá thiết bị đã ghi nhớ.']); } }