/home/alixis5/integrate.sellofinance.com/src/Services
NameSizeModeActions
ApplicationService.php290940644editdlrm
AuthService.php127280644editdlrm
CatalogAggregator.php57910644editdlrm
CustomerBundleLoader.php39520644editdlrm
EligibilityEvaluator.php176030644editdlrm
GoogleAuthService.php82850644editdlrm
MeritRanker.php62790644editdlrm
OnboardingService.php229470644editdlrm
ProductPolicyLoader.php38180644editdlrm
VerificationService.php37520644editdlrm
Edit: /home/alixis5/integrate.sellofinance.com/src/Services/GoogleAuthService.php (8285B)
verifier->verify($idToken); $email = $claims->email ?? ''; $name = $claims->name ?? ''; $googleUid = $claims->sub; if (empty($email)) { throw new \RuntimeException('Google account has no email address', 422); } // 2. Try to find existing user $appUser = $this->appUserRepo->findByEmail($email); if ($appUser !== null) { // Existing user — treat as login if ($appUser->status === AppUser::STATUS_PENDING) { $appUser = $this->appUserRepo->update($appUser->id, [ 'status' => AppUser::STATUS_ACTIVE, 'emailVerified' => true, ]); } if (in_array($appUser->status, [AppUser::STATUS_SUSPENDED, AppUser::STATUS_LOCKED], true)) { throw new \RuntimeException('ACCOUNT_' . strtoupper($appUser->status)); } $this->appUserRepo->recordSuccessfulLogin($appUser->id); $profile = $this->profileRepo->findByAppUserId($appUser->id); $token = $this->jwt->issue([ 'sub' => $appUser->id, 'accountId' => $appUser->accountId, 'profileId' => $profile?->id, 'userType' => $appUser->userType, ]); return [ 'token' => $token, 'expiresIn' => (int) $_ENV['JWT_EXPIRY_SECONDS'], 'user' => $this->buildUserResponse($appUser, $profile), ]; } // 3. New user — register them return $this->createGoogleUser($email, $name, $googleUid); } // ── Private ───────────────────────────────────────────────────── private function createGoogleUser(string $email, string $displayName, string $googleUid): array { [$firstName, $lastName] = $this->splitName($displayName ?: strstr($email, '@', true) ?: 'User'); $accountId = null; $appUserId = null; try { $account = $this->accountRepo->create([ 'name' => trim($firstName . ' ' . $lastName), 'type' => Account::TYPE_CUSTOMER, 'emailAddress' => $email, ]); $accountId = $account->id; $appUser = $this->appUserRepo->create([ 'firstName' => $firstName, 'lastName' => $lastName ?: $firstName, 'emailAddress' => $email, 'password' => password_hash(bin2hex(random_bytes(24)), PASSWORD_BCRYPT, ['cost' => 12]), 'userType' => AppUser::TYPE_CUSTOMER, 'status' => AppUser::STATUS_ACTIVE, 'signupType' => AppUser::SIGNUP_GOOGLE, 'preferredLanguage' => AppUser::LANG_EN, 'emailVerified' => true, 'mobileVerified' => false, 'mfaEnabled' => false, 'externalRef' => $googleUid, 'accountId' => $accountId, ]); $appUserId = $appUser->id; $profile = $this->profileRepo->create([ 'name' => trim($firstName . ' ' . $lastName), 'appUserId' => $appUserId, 'accountId' => $accountId, 'profileType' => CustomerProfile::TYPE_INDIVIDUAL, 'status' => CustomerProfile::STATUS_DRAFT, 'onboardingStatus' => CustomerProfile::ONBOARDING_NOT_STARTED, 'preferredCurrency' => 'AED', 'creditConsentGiven' => false, 'marketingConsentGiven' => false, 'existingBankCustomer' => false, ]); $token = $this->jwt->issue([ 'sub' => $appUserId, 'accountId' => $accountId, 'profileId' => $profile->id, 'userType' => AppUser::TYPE_CUSTOMER, ]); return [ 'token' => $token, 'expiresIn' => (int) $_ENV['JWT_EXPIRY_SECONDS'], 'user' => $this->buildUserResponse($appUser, $profile), ]; } catch (EspoDuplicateException $e) { // Duplicate on Account (email) or AppUser (email/phone). // For Google auth, a duplicate email always means the email is already registered. if ($appUserId) { try { $this->appUserRepo->delete($appUserId); } catch (\Throwable) {} } if ($accountId) { try { $this->accountRepo->delete($accountId); } catch (\Throwable) {} } throw new \RuntimeException('DUPLICATE_EMAIL', 409, $e); } catch (EspoApiException $e) { if ($appUserId) { try { $this->appUserRepo->delete($appUserId); } catch (\Throwable) {} } if ($accountId) { try { $this->accountRepo->delete($accountId); } catch (\Throwable) {} } throw new \RuntimeException($e->getMessage(), (int) $e->getCode(), $e); } } private function buildUserResponse(AppUser $user, ?CustomerProfile $profile): array { return [ 'id' => $user->id, 'accountId' => $user->accountId, 'firstName' => $user->firstName, 'lastName' => $user->lastName, 'emailAddress' => $user->emailAddress, 'phoneNumber' => $user->phoneNumber, 'emailVerified' => $user->emailVerified, 'mobileVerified' => $user->mobileVerified, 'userType' => $user->userType, 'status' => $user->status, 'preferredLanguage' => $user->preferredLanguage, 'ref' => $user->ref, 'createdAt' => $user->createdAt, 'profileCompletion' => $profile?->profileCompletenessPercent ?? 0, 'profile' => $profile ? [ 'id' => $profile->id, 'onboardingStatus' => $profile->onboardingStatus, 'onboardingStep' => $profile->onboardingStep, 'profileCompletenessPercent' => $profile->profileCompletenessPercent, 'profileType' => $profile->profileType, ] : null, ]; } /** * Splits "Ahmed Al Mansouri" → ["Ahmed", "Al Mansouri"] * Falls back to using the whole name as firstName if no space. */ private function splitName(string $name): array { $name = trim($name); if ($name === '') { return ['', '']; } $pos = strpos($name, ' '); if ($pos === false) { return [$name, '']; } return [substr($name, 0, $pos), substr($name, $pos + 1)]; } }