<?php
 namespace App\Services\Domain; use App\Models\ClientDomain; use App\Models\Setting; use Symfony\Component\HttpKernel\Exception\HttpException; final class DomainPolicyGuard { public static function assertIdnAllowed(?string $domain): void { if ($domain === null || $domain === '') { return; } if ((bool) Setting::getValue('allow_idn_domains', false)) { return; } if (self::looksIdn($domain)) { throw new HttpException(422, __('store.domain_idn_not_allowed')); } } public static function renewalEnabled(): bool { return (bool) Setting::getValue('enable_renewal_orders', true); } public static function assertRenewalEnabled(): void { if (! self::renewalEnabled()) { throw new HttpException(403, __('store.domain_renewal_disabled')); } } public static function isExistingDomainBlocked(?string $domain): bool { if ($domain === null || $domain === '') { return false; } if (! (bool) Setting::getValue('block_existing_domains', false)) { return false; } return ClientDomain::where('domain', $domain) ->whereNotIn('status', ['cancelled', 'terminated', 'expired']) ->exists(); } public static function maxRenewalYears(\App\Models\ClientDomain $domain): int { $maxYears = ($domain->tld?->max_years) ?: 10; if (! $domain->expire_date) { return 0; } $limit = now()->addYears($maxYears); $cap = 0; for ($p = 1; $p <= $maxYears; $p++) { if ($domain->expire_date->copy()->addYears($p)->lessThanOrEqualTo($limit)) { $cap = $p; } else { break; } } return $cap; } public static function looksIdn(string $domain): bool { if (preg_match('/[^\x00-\x7F]/u', $domain) === 1) { return true; } foreach (explode('.', strtolower($domain)) as $label) { if (str_starts_with($label, 'xn--')) { return true; } } return false; } } 