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/app/Http/Controllers/Api/LicenseController.php
<?php

namespace App\Http\Controllers\Api;

use App\Helpers\LicenseHelper;
use App\Http\Controllers\Controller;
use App\Library\License;
use Illuminate\Http\Request;

/**
 * POST /api/v1/license/refresh — refresh license state from verify.acellemail.com
 * and return the current license snapshot in one JSON call.
 *
 * Mirrors the webapp "Refresh" button in Admin → Settings → License so support
 * engineers don't need headless browser / console session to check license state
 * after an upgrade.
 *
 * Auth: admin api_token + setting_general permission == 'yes' (same gate as webapp).
 */
class LicenseController extends Controller
{
    public function refresh(Request $request)
    {
        $user = \Auth::guard('api')->user();
        if (!$user || !$user->admin
            || $user->admin->getPermission('setting_general') !== 'yes') {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 401);
        }

        $current = LicenseHelper::getCurrentLicense();
        if (!$current) {
            return response()->json([
                'status' => 'error',
                'message' => 'No license installed',
                'license' => null,
            ], 404);
        }

        try {
            LicenseHelper::refreshLicense();
        } catch (\Throwable $e) {
            // Refresh call failed — still return the locally-stored snapshot so caller
            // can at least inspect whether the cached state is valid. Include the error.
            return response()->json([
                'status' => 'error',
                'message' => $e->getMessage(),
                'license' => $this->present(LicenseHelper::getCurrentLicense()),
            ], 400);
        }

        return response()->json([
            'status' => 'success',
            'license' => $this->present(LicenseHelper::getCurrentLicense()),
        ]);
    }

    /**
     * Build a JSON-safe snapshot of a License object.
     * Purchase code is masked (first 4 + last 4 chars) to avoid leaking via logs.
     *
     * @return array<string, mixed>|null
     */
    private function present(?License $license): ?array
    {
        if (!$license) {
            return null;
        }

        $supportedUntil = $license->getSupportedUntil();
        $now = \Carbon\Carbon::now();
        $daysRemaining = (int)$now->copy()->startOfDay()->diffInDays($supportedUntil->copy()->startOfDay(), false);

        $code = (string)$license->getLicenseNumber();
        $masked = strlen($code) > 8
            ? substr($code, 0, 4) . str_repeat('*', max(0, strlen($code) - 8)) . substr($code, -4)
            : str_repeat('*', strlen($code));

        return [
            'purchase_code_masked' => $masked,
            'type' => $license->getType(),
            'status' => $license->isActive() ? License::STATUS_ACTIVE
                : ($license->isExpired() ? License::STATUS_EXPIRED : License::STATUS_INACTIVE),
            'is_active' => $license->isActive(),
            'is_expired' => $license->isExpired(),
            'supported_until' => $supportedUntil->toIso8601String(),
            'supported_until_human' => $supportedUntil->toDayDateTimeString(),
            'days_remaining' => $daysRemaining,
            'buyer' => $license->getBuyer(),
        ];
    }
}