feat: update allowed frontend hosts and add clinic-pro.ir domain

This commit is contained in:
hamed
2026-07-21 16:51:42 +03:30
parent 512dbdaba0
commit 7e847b62c4
14 changed files with 207 additions and 25 deletions
+11 -4
View File
@@ -3,16 +3,23 @@
namespace App\Shared\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\NullLogger;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Cache\CacheInterface;
class HealthController
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly CacheInterface $cache,
) {}
private readonly CacheItemPoolInterface $healthPool,
) {
// probe سلامت نباید هنگام افتادن redis لاگ warning تولید کند؛ logger این pool را خنثی می‌کنیم.
if ($this->healthPool instanceof LoggerAwareInterface) {
$this->healthPool->setLogger(new NullLogger());
}
}
#[Route('/health', methods: ['GET'])]
public function __invoke(): JsonResponse
@@ -29,7 +36,7 @@ class HealthController
}
try {
$item = $this->cache->getItem('health_check');
$this->healthPool->getItem('health_check');
$checks['redis'] = 'ok';
} catch (\Throwable) {
$checks['redis'] = 'error';
-12
View File
@@ -1,12 +0,0 @@
<?php
namespace App\Shared\Message;
class SendSmsMessage
{
public function __construct(
public readonly string $mobile,
public readonly string $message,
public readonly ?int $smsLogId = null,
) {}
}
+20 -3
View File
@@ -3,6 +3,7 @@
namespace App\Sms\Provider;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -57,6 +58,9 @@ class KavehNegarProvider implements SmsProviderInterface
'sender' => $this->sender(),
]);
return ($data['return']['status'] ?? 0) === 200;
} catch (HttpExceptionInterface $e) {
$this->logger->warning(sprintf('SMS send rejected (kavenegar): HTTP %d', $e->getResponse()->getStatusCode()), ['mobile' => $mobile]);
return false;
} catch (\Throwable $e) {
$this->logger->error(sprintf('SMS send failed (kavenegar): %s @ %s:%d', $e->getMessage(), $e->getFile(), $e->getLine()), ['exception' => $e, 'mobile' => $mobile]);
return false;
@@ -66,12 +70,20 @@ class KavehNegarProvider implements SmsProviderInterface
// token/token2/token3 مقدارِ دارای فاصله را رد می‌کنند؛ فاصله را با نیم‌فاصله (ZWNJ) جایگزین می‌کنیم.
private const NO_SPACE_SLOTS = ['token', 'token2', 'token3'];
// کاوه‌نگار روی طول توکن سقف دارد؛ مقدار بلند (مثلاً نام کلینیک فارسی که هر کاراکترش
// ۹ بایت URL-encode می‌شود) درخواست را بزرگ می‌کند و پاسخ 431 می‌گیریم. مقدار را cap می‌کنیم.
private const MAX_TOKEN_LEN = 60;
private function forSlot(string $slot, string $value): string
{
if (!in_array($slot, self::NO_SPACE_SLOTS, true)) {
return $value;
$value = trim($value);
if (in_array($slot, self::NO_SPACE_SLOTS, true)) {
$value = preg_replace('/\s+/u', "\u{200C}", $value) ?? $value;
}
return preg_replace('/\s+/u', "\u{200C}", $value) ?? $value;
if (mb_strlen($value, 'UTF-8') > self::MAX_TOKEN_LEN) {
$value = mb_substr($value, 0, self::MAX_TOKEN_LEN, 'UTF-8');
}
return $value;
}
public function sendTemplate(string $mobile, string $templateCode, array $vars): bool
@@ -95,6 +107,11 @@ class KavehNegarProvider implements SmsProviderInterface
}
$data = $this->get('/verify/lookup.json', $params);
return ($data['return']['status'] ?? 0) === 200;
} catch (HttpExceptionInterface $e) {
// 4xx/5xx از کاوه‌نگار (مثل 431): خطای دائم درخواست است نه transient؛
// warning کوتاه با کد وضعیت، بدون dump کامل exception.
$this->logger->warning(sprintf('SMS sendTemplate rejected (kavenegar): HTTP %d', $e->getResponse()->getStatusCode()), ['mobile' => $mobile, 'template' => $templateCode]);
return false;
} catch (\Throwable $e) {
$this->logger->error(sprintf('SMS sendTemplate failed (kavenegar): %s @ %s:%d', $e->getMessage(), $e->getFile(), $e->getLine()), ['exception' => $e, 'mobile' => $mobile, 'template' => $templateCode]);
return false;