fix: récupérer expiration NDD via RDAP quand Cloudflare ou registrar externe

DnsCheckService :
- Ajout getExpirationDate(domain) : requête RDAP pour récupérer
  la date d'expiration d'un domaine (events[].eventAction=expiration)

autoDetectDomain :
- Fallback RDAP en fin de détection : si expiredAt est encore null
  après check OVH/Cloudflare, interroge RDAP pour l'expiration
- Fonctionne pour tous les TLD (.fr, .com, .dev, etc.)

Flux : OVH serviceInfos → Cloudflare (pas d'expiration) → RDAP fallback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-04 20:50:02 +02:00
parent aa8df3687c
commit 5578d53cbd
2 changed files with 35 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ use App\Entity\User;
use App\Repository\CustomerRepository;
use App\Entity\Domain;
use App\Service\CloudflareService;
use App\Service\DnsCheckService;
use App\Service\MailerService;
use App\Service\MeilisearchService;
use App\Service\OvhService;
@@ -315,7 +316,7 @@ class ClientsController extends AbstractController
}
#[Route('/{id}', name: 'show')]
public function show(Customer $customer, Request $request, EntityManagerInterface $em, OvhService $ovhService, CloudflareService $cloudflareService): Response
public function show(Customer $customer, Request $request, EntityManagerInterface $em, OvhService $ovhService, CloudflareService $cloudflareService, DnsCheckService $dnsCheckService): Response
{
$tab = $request->query->getString('tab', 'info');
@@ -333,7 +334,7 @@ class ClientsController extends AbstractController
}
if ('POST' === $request->getMethod() && 'ndd' === $tab) {
return $this->handleDomainForm($request, $customer, $em, $ovhService, $cloudflareService);
return $this->handleDomainForm($request, $customer, $em, $ovhService, $cloudflareService, $dnsCheckService);
}
$this->ensureDefaultContact($customer, $em);
@@ -381,7 +382,7 @@ class ClientsController extends AbstractController
return $this->redirectToRoute('app_admin_clients_show', ['id' => $customer->getId(), 'tab' => 'contacts']);
}
private function handleDomainForm(Request $request, Customer $customer, EntityManagerInterface $em, OvhService $ovhService, CloudflareService $cloudflareService): Response
private function handleDomainForm(Request $request, Customer $customer, EntityManagerInterface $em, OvhService $ovhService, CloudflareService $cloudflareService, DnsCheckService $dnsCheckService): Response
{
$action = $request->request->getString('domain_action');
@@ -405,7 +406,7 @@ class ClientsController extends AbstractController
$domain = new Domain($customer, $fqdn);
$domain->setRegistrar($registrar);
$this->autoDetectDomain($domain, $ovhService, $cloudflareService);
$this->autoDetectDomain($domain, $ovhService, $cloudflareService, $dnsCheckService);
$em->persist($domain);
$em->flush();
@@ -426,7 +427,7 @@ class ClientsController extends AbstractController
return $this->redirectToRoute('app_admin_clients_show', ['id' => $customer->getId(), 'tab' => 'ndd']);
}
private function autoDetectDomain(Domain $domain, OvhService $ovhService, CloudflareService $cloudflareService): void
private function autoDetectDomain(Domain $domain, OvhService $ovhService, CloudflareService $cloudflareService, DnsCheckService $dnsCheckService): void
{
$fqdn = $domain->getFqdn();
@@ -467,6 +468,14 @@ class ClientsController extends AbstractController
}
}
}
// Fallback RDAP pour l'expiration si pas encore trouvée
if (null === $domain->getExpiredAt()) {
$expiration = $dnsCheckService->getExpirationDate($fqdn);
if (null !== $expiration) {
$domain->setExpiredAt($expiration);
}
}
}
#[Route('/{id}/resend-welcome', name: 'resend_welcome', methods: ['POST'])]

View File

@@ -227,6 +227,27 @@ class DnsCheckService
* @param list<string> $warnings
* @param list<string> $successes
*/
public function getExpirationDate(string $domain): ?\DateTimeImmutable
{
$rdapData = $this->queryRdap($domain);
if (null === $rdapData) {
return null;
}
foreach ($rdapData['events'] ?? [] as $event) {
if ('expiration' === ($event['eventAction'] ?? '')) {
try {
return new \DateTimeImmutable($event['eventDate']);
} catch (\Throwable) {
return null;
}
}
}
return null;
}
public function checkWhois(string $domain, array &$checks, array &$errors, array &$warnings, array &$successes): void
{
// Nameservers via dig NS