presseportale/app/Services/Auth/SocialAuthService.php
Kevin Adametz 3a11963990 admin: Aktivitäts-Verlauf unter Reports ▸ Verlauf
Chronologisches Protokoll der Systemereignisse als neue Admin-Seite
(/admin/reports/activity) mit Filter nach Ereignistyp, Zeitraum und
Suche. Erfasst ab jetzt fortlaufend:

- Registrierungen inkl. Weg (Formular, Google, Magic-Link)
- Anmeldungen inkl. Weg (Passwort, Google, Magic-Link, Impersonation)
- PM-Statuswechsel mit Ergebnis/Begründung (zentral im Status-Log-Hook;
  KI-/Scheduler-Wechsel erscheinen als „System")
- Zahlungseingänge (Rechnungsspiegelung) und Credit-Aufladungen
- Formular-Eingänge: Kontakt, Rechtsanfrage, Widerruf, Kündigung,
  Newsletter-Anmeldung (Observer auf den Modellen)

Schreiben ist Best-Effort über den ActivityLog-Service — ein
fehlgeschlagener Verlaufseintrag bricht nie den fachlichen Ablauf.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:00:58 +00:00

79 lines
2.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services\Auth;
use App\Models\User;
/**
* Auflösung eines Social-Logins (Google, ggf. weitere) auf einen lokalen User.
*
* Identität ist die E-Mail (De-Dup darüber, keine Dubletten). Der Provider
* bestätigt die E-Mail, daher gilt die Verifizierung über den Kanal als erfüllt
* (Entscheidung 15.06.) – kein zusätzlicher E-Mail-Verifizierungsschritt.
*/
class SocialAuthService
{
public function __construct(
private readonly UserRolePermissionSyncService $roleSync,
private readonly CustomerAccountProvisioner $accountProvisioner,
) {}
/**
* Liefert den (ggf. neu angelegten) User zur Social-Identität. Ein
* deaktivierter Bestands-Account wird NICHT reaktiviert – der Aufrufer prüft
* danach is_active und blockiert.
*/
public function resolveUser(string $provider, string $providerId, ?string $email, ?string $name): ?User
{
$email = $email ? mb_strtolower(trim($email)) : null;
if ($email === null || $email === '') {
return null;
}
$user = User::findByEmail($email);
if (! $user) {
return $this->createUser($provider, $providerId, $email, $name);
}
$user->forceFill([
'oauth_provider' => $provider,
'oauth_provider_id' => $providerId,
]);
// Noch nicht verifiziert (offener Selbst-Registrierer): der Provider
// bestätigt die E-Mail → Onboarding abschließen (aktiv + customer).
if ($user->email_verified_at === null) {
$user->forceFill([
'email_verified_at' => now(),
'is_active' => true,
])->save();
if ($user->roles()->doesntExist()) {
$this->roleSync->assignRoleAndSyncPermissions($user, 'customer');
}
return $user;
}
// Bereits verifiziert: nur Provider verknüpfen. is_active bleibt
// unangetastet (deaktivierte Accounts werden nicht reaktiviert).
$user->save();
return $user;
}
private function createUser(string $provider, string $providerId, string $email, ?string $name): User
{
return $this->accountProvisioner->provisionVerifiedCustomer(
$email,
$name !== null ? trim($name) : '',
[
'oauth_provider' => $provider,
'oauth_provider_id' => $providerId,
],
channel: $provider,
);
}
}