validated(); $method = MfaMethod::from($validated['method']); try { $user = $this->mfaService->verifyMfaCode( sessionToken: $validated['mfa_session_token'], code: $validated['code'], method: $method, ipAddress: $request->ip(), ); } catch (\DomainException $e) { return $this->error($e->getMessage(), 422); } // Trust device if requested if (! empty($validated['trust_device']) && ! empty($validated['device_fingerprint'])) { $this->mfaService->trustDevice( user: $user, fingerprint: $validated['device_fingerprint'], ipAddress: $request->ip(), deviceName: $validated['device_name'] ?? null, ); } // Issue auth token (same as login flow) $user->load([ 'organisations', 'roles', 'permissions', 'persons' => fn ($q) => $q->with(['event:id,name,slug,start_date,end_date,organisation_id', 'event.organisation:id,name']), ]); $token = $user->createToken('auth-token')->plainTextToken; $cookieName = $this->resolveCookieName($request); return $this->success([ 'user' => new MeResource($user), ], 'MFA verification successful') ->withCookie($this->makeAuthCookie($cookieName, $token)); } public function sendEmailCode(MfaEmailSendRequest $request): JsonResponse { $sessionToken = $request->validated('mfa_session_token'); $cacheKey = 'mfa_session:' . $sessionToken; $session = Cache::get($cacheKey); if (! $session) { return $this->error('MFA-sessie verlopen. Log opnieuw in.', 422); } $user = User::findOrFail($session['user_id']); try { $this->mfaService->sendEmailCode($user); } catch (\DomainException $e) { return $this->error($e->getMessage(), 429); } return $this->success(null, 'Verification code sent'); } }