HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/hi.naniguide.com/app/Http/Controllers/Customer/GoogleIntegrationController.php
<?php

namespace App\Http\Controllers\Customer;

use App\Http\Controllers\Controller;
use App\Models\GoogleIntegration;
use App\Models\Setting;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class GoogleIntegrationController extends Controller
{
    private const SERVICE_SHEETS = 'sheets';
    private const SERVICE_DRIVE = 'drive';

    private function resolveService(string $service): string
    {
        $service = strtolower(trim($service));

        if (!in_array($service, [self::SERVICE_SHEETS, self::SERVICE_DRIVE], true)) {
            abort(404);
        }

        return $service;
    }

    private function hydrateGoogleConfigForIntegration(string $service): void
    {
        $clientId = config('services.google.client_id') ?: env('GOOGLE_CLIENT_ID');
        $clientSecret = config('services.google.client_secret') ?: env('GOOGLE_CLIENT_SECRET');

        $dbClientId = Setting::get('google_client_id');
        $dbClientSecret = Setting::get('google_client_secret');

        if (is_string($dbClientId)) {
            $dbClientId = trim($dbClientId);
        }
        if (is_string($dbClientSecret)) {
            $dbClientSecret = trim($dbClientSecret);
        }

        $redirectToUse = route('customer.integrations.google.callback', ['service' => $service]);

        $resolvedClientId = (is_string($dbClientId) && $dbClientId !== '') ? $dbClientId : $clientId;
        $resolvedClientSecret = (is_string($dbClientSecret) && $dbClientSecret !== '') ? $dbClientSecret : $clientSecret;

        config([
            'services.google.client_id' => $resolvedClientId,
            'services.google.client_secret' => $resolvedClientSecret,
            'services.google.redirect' => $redirectToUse,
        ]);
    }

    private function scopesForService(string $service): array
    {
        return match ($service) {
            self::SERVICE_SHEETS => [
                'https://www.googleapis.com/auth/spreadsheets',
            ],
            self::SERVICE_DRIVE => [
                'https://www.googleapis.com/auth/drive.file',
            ],
            default => [],
        };
    }

    public function connect(Request $request, string $service): RedirectResponse
    {
        $service = $this->resolveService($service);

        if (!class_exists('Laravel\\Socialite\\Facades\\Socialite')) {
            return redirect()
                ->route('customer.integrations.index', ['tab' => 'google'])
                ->with('error', 'Google integration is not available. Please install Laravel Socialite.');
        }

        $this->hydrateGoogleConfigForIntegration($service);

        $clientId = config('services.google.client_id');
        $clientSecret = config('services.google.client_secret');
        $redirectUri = config('services.google.redirect');

        if (!$clientId || !$clientSecret || !$redirectUri) {
            return redirect()
                ->route('customer.integrations.index', ['tab' => 'google'])
                ->with('error', 'Google OAuth is not configured. Please set Google Client ID and Client Secret in Admin → Settings → Auth.');
        }

        $scopes = $this->scopesForService($service);

        return \Laravel\Socialite\Facades\Socialite::driver('google')
            ->scopes($scopes)
            ->with([
                'access_type' => 'offline',
                'prompt' => 'consent',
                'include_granted_scopes' => 'true',
            ])
            ->redirect();
    }

    public function callback(Request $request, string $service): RedirectResponse
    {
        $service = $this->resolveService($service);

        if (!class_exists('Laravel\\Socialite\\Facades\\Socialite')) {
            return redirect()
                ->route('customer.integrations.index', ['tab' => 'google'])
                ->with('error', 'Google integration is not available. Please install Laravel Socialite.');
        }

        $this->hydrateGoogleConfigForIntegration($service);

        $clientId = config('services.google.client_id');
        $clientSecret = config('services.google.client_secret');
        $redirectUri = config('services.google.redirect');

        if (!$clientId || !$clientSecret || !$redirectUri) {
            return redirect()
                ->route('customer.integrations.index', ['tab' => 'google'])
                ->with('error', 'Google OAuth is not configured. Please set Google Client ID and Client Secret in Admin → Settings → Auth.');
        }

        try {
            $googleUser = \Laravel\Socialite\Facades\Socialite::driver('google')->user();
        } catch (\Throwable $e) {
            return redirect()
                ->route('customer.integrations.index', ['tab' => 'google'])
                ->with('error', 'Google connection failed. Please try again.');
        }

        $customer = Auth::guard('customer')->user();
        if (!$customer) {
            return redirect()->route('login');
        }

        $expiresIn = (int) ($googleUser->expiresIn ?? 0);
        $expiresAt = $expiresIn > 0 ? now()->addSeconds($expiresIn) : null;

        GoogleIntegration::query()->updateOrCreate(
            [
                'customer_id' => $customer->id,
                'service' => $service,
            ],
            [
                'google_account_email' => $googleUser->getEmail(),
                'access_token' => (string) ($googleUser->token ?? ''),
                'refresh_token' => $googleUser->refreshToken ? (string) $googleUser->refreshToken : null,
                'expires_at' => $expiresAt,
                'scopes' => $this->scopesForService($service),
            ]
        );

        return redirect()
            ->route('customer.integrations.index', ['tab' => 'google'])
            ->with('success', 'Google account connected successfully.');
    }

    public function disconnect(Request $request, string $service): RedirectResponse
    {
        $service = $this->resolveService($service);

        $customer = Auth::guard('customer')->user();
        if (!$customer) {
            return redirect()->route('login');
        }

        GoogleIntegration::query()
            ->where('customer_id', $customer->id)
            ->where('service', $service)
            ->delete();

        return redirect()
            ->route('customer.integrations.index', ['tab' => 'google'])
            ->with('success', 'Google account disconnected.');
    }
}