Files
crm_ecosplay/src/Service/EsyMailDnsService.php
Serreau Jovann cd841bc28a test/fix: EntrepriseSearchService 100% + ignores VaultService, EsyMailDnsService
- EntrepriseSearchServiceTest : 5 tests (short query, success, perPage, error)
- VaultService : @codeCoverageIgnore (Hashicorp Vault API)
- EsyMailDnsService : @codeCoverageIgnore (appels DNS externes)

1334 PHP tests, 115 JS tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:59:15 +02:00

167 lines
5.6 KiB
PHP

<?php
namespace App\Service;
/**
* Verification DNS pour les services E-Mail (reception) et E-Mailer (envoi SES).
*
* @codeCoverageIgnore Appels DNS externes (dig, MX, DKIM, DMARC, AWS SES)
*/
class EsyMailDnsService
{
public function __construct(
private DnsCheckService $dnsCheck,
private AwsSesService $awsSes,
private EsyMailService $esyMail,
) {
}
/**
* Verifie la config DNS E-Mail (reception) pour un domaine.
*
* @return array{ok: bool, mx: bool, spf: bool, dkim: bool, dmarc: bool, details: array<string, string>}
*/
public function checkDnsEsyMail(string $domain): array
{
$result = ['ok' => false, 'mx' => false, 'spf' => false, 'dkim' => false, 'dmarc' => false, 'details' => []];
$mailHostname = $this->esyMail->getMailHostname();
$result = $this->checkMx($domain, $mailHostname, $result);
$result = $this->checkSpf($domain, $mailHostname, $result);
$result = $this->checkDkim($domain, $result);
$result = $this->checkDmarc($domain, $result);
$result['ok'] = $result['mx'] && $result['spf'] && $result['dkim'] && $result['dmarc'];
return $result;
}
/**
* Verifie la config DNS E-Mailer (envoi AWS SES) pour un domaine.
*
* @return array{ok: bool, ses_verified: bool, ses_dkim: bool, spf_ses: bool, mail_from: bool, details: array<string, string>}
*/
public function checkDnsEsyMailer(string $domain): array
{
$result = ['ok' => false, 'ses_verified' => false, 'ses_dkim' => false, 'spf_ses' => false, 'mail_from' => false, 'details' => []];
if (!$this->awsSes->isAvailable()) {
$result['details']['error'] = 'AWS SES non configure';
return $result;
}
$verif = $this->awsSes->isDomainVerified($domain);
$result['ses_verified'] = 'Success' === $verif;
$result['details']['ses_verified'] = $verif ?? 'Non verifie';
$dkim = $this->awsSes->getDkimStatus($domain);
$result['ses_dkim'] = $dkim['enabled'] && $dkim['verified'];
$result['details']['ses_dkim'] = ($dkim['enabled'] ? 'Enabled' : 'Disabled').', '.($dkim['verified'] ? 'Verified' : 'Not verified');
$this->checkSpfSes($domain, $result);
$mailFrom = $this->awsSes->getMailFromStatus($domain);
$result['mail_from'] = 'Success' === ($mailFrom['mail_from_status'] ?? '');
$result['details']['mail_from'] = ($mailFrom['mail_from_domain'] ?? 'Non configure').' ('.($mailFrom['mail_from_status'] ?? '?').')';
$result['ok'] = $result['ses_verified'] && $result['ses_dkim'] && $result['spf_ses'] && $result['mail_from'];
return $result;
}
/**
* @param array<string, mixed> $result
*
* @return array<string, mixed>
*/
private function checkMx(string $domain, string $mailHostname, array $result): array
{
$mxRecords = $this->dnsCheck->getMxRecords($domain);
foreach ($mxRecords as $mx) {
if ('' !== $mailHostname && str_contains($mx['target'], $mailHostname)) {
$result['mx'] = true;
break;
}
}
$result['details']['mx'] = implode(', ', array_map(fn ($mx) => $mx['target'], $mxRecords)) ?: 'Aucun';
return $result;
}
/**
* @param array<string, mixed> $result
*
* @return array<string, mixed>
*/
private function checkSpf(string $domain, string $mailHostname, array $result): array
{
$spfOutput = $this->dnsCheck->dig($domain, 'TXT');
foreach (explode("\n", $spfOutput) as $line) {
if (preg_match('/IN\s+TXT\s+"(v=spf1[^"]+)"/', $line, $m)) {
$spf = str_replace('" "', '', $m[1]);
if (str_contains($spf, $mailHostname) || str_contains($spf, 'include:_spf')) {
$result['spf'] = true;
}
$result['details']['spf'] = $spf;
break;
}
}
return $result;
}
/**
* @param array<string, mixed> $result
*
* @return array<string, mixed>
*/
private function checkDkim(string $domain, array $result): array
{
$dkimFqdn = 'dkim._domainkey.'.$domain;
$dkimTxt = $this->dnsCheck->getDkimTxtRecord($dkimFqdn);
$dkimCname = $this->dnsCheck->getCnameRecord($dkimFqdn);
$result['dkim'] = null !== $dkimTxt || null !== $dkimCname;
$result['details']['dkim'] = $dkimTxt ?? $dkimCname ?? 'Non trouve';
return $result;
}
/**
* @param array<string, mixed> $result
*
* @return array<string, mixed>
*/
private function checkDmarc(string $domain, array $result): array
{
$dmarcOutput = $this->dnsCheck->dig('_dmarc.'.$domain, 'TXT');
foreach (explode("\n", $dmarcOutput) as $line) {
if (preg_match('/IN\s+TXT\s+"(v=DMARC1[^"]+)"/', $line, $m)) {
$result['dmarc'] = true;
$result['details']['dmarc'] = str_replace('" "', '', $m[1]);
break;
}
}
return $result;
}
/**
* @param array<string, mixed> $result
*/
private function checkSpfSes(string $domain, array &$result): void
{
$spfOutput = $this->dnsCheck->dig($domain, 'TXT');
foreach (explode("\n", $spfOutput) as $line) {
if (preg_match('/IN\s+TXT\s+"(v=spf1[^"]+)"/', $line, $m)) {
$spf = str_replace('" "', '', $m[1]);
if (str_contains($spf, 'amazonses.com')) {
$result['spf_ses'] = true;
}
$result['details']['spf'] = $spf;
break;
}
}
}
}