whereRaw('LOWER(email) = ?', [$email]) ->whereNotNull('company_id') ->get(); if ($contacts->isEmpty()) { return false; } $user = $this->resolveUser($email, $contacts); // Deaktivierte Bestands-Accounts nicht verändern: eine unauthentifizierte // Anfrage darf weder Firmenzuordnungen vorbereiten noch einen Link // auslösen. Frisch lazy angelegte Accounts sind aktiv und laufen weiter. if (! $user->is_active) { return false; } $this->linkCompanies($user, $contacts); $generated = $this->magicLinks->createLoginLink($user, $ip); Mail::to($user->email)->send(new MagicLoginLink( user: $user, loginUrl: route('magic-links.consume', ['token' => $generated['plain_token']]), expiresAt: $generated['expires_at']->format('d.m.Y H:i'), )); return true; } /** * Bestehenden Account per E-Mail wiederverwenden (keine Dubletten) oder lazy * einen neuen anlegen. Verifizierung gilt über den Magic-Link-Kanal als * erfüllt (Entscheidung 15.06.) – daher direkt aktiv + customer. * * @param Collection $contacts */ private function resolveUser(string $email, Collection $contacts): User { $existing = User::query()->whereRaw('LOWER(email) = ?', [$email])->first(); if ($existing) { return $existing; } $contact = $contacts->first(); $name = trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')); $user = User::create([ 'name' => $name !== '' ? $name : $email, 'email' => $email, 'registration_type' => RegistrationType::Company->value, 'is_active' => true, ]); $user->forceFill(['email_verified_at' => now()])->save(); $this->roleSync->assignRoleAndSyncPermissions($user, 'customer'); return $user; } /** * Ordnet den User den Firmen seiner Kontakte als Mitglied zu (Firmen-Scope) * und verknüpft ihn mit den Kontakt-Datensätzen. Owner bleiben Owner. * * @param Collection $contacts */ private function linkCompanies(User $user, Collection $contacts): void { $companyIds = $contacts->pluck('company_id')->filter()->unique(); foreach ($companyIds as $companyId) { $alreadyLinked = $user->ownedCompanies()->whereKey($companyId)->exists() || $user->companies()->whereKey($companyId)->exists(); if (! $alreadyLinked) { $user->companies()->attach($companyId, ['role' => 'member']); } } $user->contacts()->syncWithoutDetaching($contacts->pluck('id')->all()); } }