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/ai.naniguide.com/bootstrap/app.php
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->use([
            \Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks::class,
            // \Illuminate\Http\Middleware\TrustHosts::class,
            \App\Http\Middleware\TrustProxies::class,
            \Illuminate\Http\Middleware\HandleCors::class,
            \Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
            \Illuminate\Http\Middleware\ValidatePostSize::class,
            \Illuminate\Foundation\Http\Middleware\TrimStrings::class,
            \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        ]);

        $middleware->appendToGroup('web', [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            // \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ]);

        $middleware->prependToGroup('web_nocsrf', [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            #\App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ]);

        $middleware->prependToGroup('api', [
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ]);

        $middleware->alias([
            'auth' => \App\Http\Middleware\Authenticate::class,
            'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
            'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
            'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
            'can' => \Illuminate\Auth\Middleware\Authorize::class,
            'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
            'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
            'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
            'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
            'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
            // `frontend` is intentionally NOT aliased here — it is defined
            // as a middleware GROUP below so that FrontendRouteGuard runs
            // immediately after Frontend on every customer route, without
            // having to touch routes/refactor.php.
            'backend' => \App\Http\Middleware\Backend::class,
            'installed' => \App\Http\Middleware\Installed::class,
            'not_installed' => \App\Http\Middleware\NotInstalled::class,
            'not_logged_in' => \App\Http\Middleware\NotLoggedIn::class,
            'subscription' => \App\Http\Middleware\Subscription::class,
            'email_verify' => \App\Http\Middleware\EmailVerify::class,
            '2fa' => \App\Http\Middleware\TwoFA::class,
            'setdb' => \App\Http\Middleware\SetUserDbConnection::class,
            'api_key_auth' => \App\Http\Middleware\ApiKeyAuth::class,
            'demo_guard' => \App\Http\Middleware\DemoGuard::class,
            // `ai.active` middleware alias now lives in the acelle/ai
            // plugin's ServiceProvider (W4 of the AI-extraction plan).
            // The earlier `ai_module_visible` env-kill-switch alias was
            // removed once the plugin lifecycle owned the install-time
            // gate. Removing the plugin folder unbinds the alias
            // automatically — no shim needed here.
        ]);

        // `frontend` middleware GROUP — applied to every customer-facing
        // route in routes/refactor.php. Composed of:
        //   1. Frontend          — gates customer_access permission + locale
        //   2. FrontendRouteGuard — delegates routing decisions to
        //                          ModuleManager::resolveRouteDecision()
        // When no plugin has overridden the slot, ModuleManager seeds a
        // null-returning default lazily, so Acelle behaves unchanged with
        // no frontend-skin plugin installed. Admin routes use the `backend`
        // alias and are unaffected by this group.
        $middleware->group('frontend', [
            \App\Http\Middleware\Frontend::class,
            \App\Http\Middleware\FrontendRouteGuard::class,
        ]);

        $middleware->priority([
            \App\Http\Middleware\NotInstalled::class,
            \Illuminate\Auth\Middleware\Authenticate::class,
        ]);

        $middleware->validateCsrfTokens(except: [
            'webhook/*',
            'webhooks/*',
            'plugins/webhooks/*',
            'delivery/*',
            'api/*',
            '*/embedded-form-*',
            'payments/stripe/credit-card*',
            'frontend/*',
            'paytr/*',
            // RFC 8058 one-click unsubscribe — POST from mail clients (Gmail/Apple)
            // has no session cookie and cannot acquire a CSRF token; the signed
            // URL is the integrity check.
            'c/*/unsubscribe-oneclick/*',
            // Messenger W3 public opt-in confirm POSTs (acelle/messenger plugin).
            // Per DESIGN.md §9.5: subscribers reach these pages via signed URL
            // from the subscribe form submit handler, without a session/cookie.
            // The signed URL is the integrity check; CSRF token cannot be
            // acquired without auth chrome.
            'c/opt-in/sms-confirm/*',
            'c/opt-in/sms-resend/*',
        ]);
    })

    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )

    // Laravel 12 registers its base EventServiceProvider in addition to the
    // app-level one, and the base instance has `shouldDiscoverEvents()` returning
    // true (for its own class). That auto-scans `app/Listeners/` and registers
    // every `handle(EventClass $e)` as `Class@handle`, which DUPLICATES our
    // explicit `$listen` mappings (verified live: each `BounceReceived` was
    // dispatching two `RecordBounce` jobs). Disable discovery so our `$listen`
    // array in App\Providers\EventServiceProvider is the single source of truth.
    ->withEvents(discover: false)

    ->withExceptions(function (Exceptions $exceptions) {
        // Auth — JSON requests get the Laravel-default `message` shape (which
        // is what the framework was already emitting anyway when this hook
        // was empty). Web requests redirect to admin or customer login based
        // on path. This replaces the dead app/Exceptions/Handler.php that
        // never auto-registered in Laravel 11+.
        $exceptions->render(function (\Illuminate\Auth\AuthenticationException $e, $request) {
            if ($request->expectsJson()) {
                return response()->json(['message' => 'Unauthenticated.'], 401);
            }
            $isAdmin = $request->is('admin/*') || $request->is('admin')
                || $request->is('rui/admin/*') || $request->is('rui/admin');
            return redirect()->guest($isAdmin ? route('refactor.admin.login') : route('login'));
        });

        // Mirror CLI exceptions to the admin notification inbox via the
        // shared 'admins' broadcast (migrated from the old Handler::report()).
        $exceptions->report(function (\Throwable $e) {
            if (\App::runningInConsole() && function_exists('isInitiated') && isInitiated()) {
                try {
                    app(\App\Services\Notifications\Notifier::class)->shareWithAdmins(
                        new \App\Notifications\System\BackendErrorOccurred($e)
                    );
                } catch (\PDOException $dbErr) {
                    // DB unreachable — log and continue. HARD RULE: do not
                    // swallow silently. Re-throwing would loop since we're
                    // already inside the global reporter.
                    \Log::warning('Notifier dispatch failed during exception report (DB unreachable)', [
                        'original_exception' => get_class($e),
                        'original_message'   => $e->getMessage(),
                        'dispatch_error'     => $dbErr->getMessage(),
                    ]);
                }
            }
        });

        $exceptions->dontReport([
            // Currently, Acelle allows user to "cancel" a job by deleting its
            // monitor model, resulting in a ModelNotFoundException. Suppress
            // here to avoid a log recorded to admin notification area.
            \Illuminate\Database\Eloquent\ModelNotFoundException::class,
            // For this type of issue, it is normally because the related
            // process is terminated by the OS and the error is already logged
            // to the related campaign, verification process, etc.
            \Illuminate\Queue\MaxAttemptsExceededException::class,
        ]);

        $exceptions->dontFlash([
            'current_password',
            'password',
            'password_confirmation',
        ]);
    })->create();