Reduce return counts and fix code smells across controllers and services

- ApiAccountController::lookup: reduce from 4 to 3 returns via ternary
- AttestationController::ventes: reduce from 5 to 2 returns by extracting
  decodeAndVerifyHash() helper; add TPL_NOT_FOUND_VENTES constant for the
  template literal duplicated 5 times
- AnalyticsCryptoService::decrypt: reduce from 4 to 2 returns by extracting
  tryDecryptJsFormat() helper
- InfraService::fmtDuration: reduce from 4 to 1 return using match(true)
- InfraService: replace nested ternary with match(true) for SSL status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-28 20:23:08 +01:00
parent 0df78f75ae
commit 3a40de1ba0
4 changed files with 53 additions and 53 deletions

View File

@@ -41,13 +41,8 @@ class ApiAccountController extends AbstractController
$user = $em->getRepository(User::class)->findOneBy(['email' => $email]); $user = $em->getRepository(User::class)->findOneBy(['email' => $email]);
if (!$user) { return $user
return $this->error('Utilisateur introuvable.', 404); ? $this->success(['id' => $user->getId(), 'stripeAccountId' => $user->getStripeAccountId()])
} : $this->error('Utilisateur introuvable.', 404);
return $this->success([
'id' => $user->getId(),
'stripeAccountId' => $user->getStripeAccountId(),
]);
} }
} }

View File

@@ -12,6 +12,7 @@ use Symfony\Component\Routing\Attribute\Route;
class AttestationController extends AbstractController class AttestationController extends AbstractController
{ {
private const TPL_NOT_FOUND_VENTES = 'attestation/not_found_ventes.html.twig';
public function __construct( public function __construct(
#[Autowire('%kernel.secret%')] private string $appSecret, #[Autowire('%kernel.secret%')] private string $appSecret,
) { ) {
@@ -50,7 +51,7 @@ class AttestationController extends AbstractController
$attestation = $em->getRepository(Attestation::class)->findOneBy(['reference' => $reference]); $attestation = $em->getRepository(Attestation::class)->findOneBy(['reference' => $reference]);
if (!$attestation) { if (!$attestation) {
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]); return $this->render(self::TPL_NOT_FOUND_VENTES, ['breadcrumbs' => $breadcrumbs]);
} }
return $this->render('attestation/check_ventes.html.twig', [ return $this->render('attestation/check_ventes.html.twig', [
@@ -69,38 +70,47 @@ class AttestationController extends AbstractController
['name' => 'Verification attestation de ventes', 'url' => null], ['name' => 'Verification attestation de ventes', 'url' => null],
]; ];
$result = $this->decodeAndVerifyHash($hash);
if (!$result) {
return $this->render(self::TPL_NOT_FOUND_VENTES, ['breadcrumbs' => $breadcrumbs]);
}
$attestation = $em->getRepository(Attestation::class)->findOneBy(['signatureHash' => $result['signatureHash']]);
return $this->render('attestation/check_ventes.html.twig', [
'data' => $result['data'],
'breadcrumbs' => $breadcrumbs,
'isRegistered' => null !== $attestation,
'attestation' => $attestation,
]);
}
/**
* @return array{data: array<string, mixed>, signatureHash: string}|null
*/
private function decodeAndVerifyHash(string $hash): ?array
{
$decoded = base64_decode(strtr($hash, '-_', '+/'), true); $decoded = base64_decode(strtr($hash, '-_', '+/'), true);
if (!$decoded) { if (!$decoded) {
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]); return null;
} }
$parts = explode('|', $decoded, 2); $parts = explode('|', $decoded, 2);
if (2 !== \count($parts)) { if (2 !== \count($parts)) {
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]); return null;
} }
[$signature, $jsonPayload] = $parts; [$signature, $jsonPayload] = $parts;
$expectedSignature = hash_hmac('sha256', $jsonPayload, $this->appSecret); $expectedSignature = hash_hmac('sha256', $jsonPayload, $this->appSecret);
if (!hash_equals($expectedSignature, $signature)) { if (!hash_equals($expectedSignature, $signature)) {
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]); return null;
} }
$data = json_decode($jsonPayload, true); $data = json_decode($jsonPayload, true);
if (!$data) {
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]);
}
$signatureHash = hash_hmac('sha256', $jsonPayload, $this->appSecret); return $data ? ['data' => $data, 'signatureHash' => $expectedSignature] : null;
$attestation = $em->getRepository(Attestation::class)->findOneBy(['signatureHash' => $signatureHash]);
$isRegistered = null !== $attestation;
return $this->render('attestation/check_ventes.html.twig', [
'data' => $data,
'breadcrumbs' => $breadcrumbs,
'isRegistered' => $isRegistered,
'attestation' => $attestation,
]);
} }
/** /**

View File

@@ -33,30 +33,26 @@ class AnalyticsCryptoService
return null; return null;
} }
// Try JS format first: iv (12) + ciphertext_with_tag (tag is last 16 bytes)
$iv = substr($raw, 0, 12); $iv = substr($raw, 0, 12);
$ciphertextWithTag = substr($raw, 12);
if (\strlen($ciphertextWithTag) >= 16) { // Try JS format first: iv (12) + ciphertext_with_tag (tag is last 16 bytes)
$tag = substr($ciphertextWithTag, -16); $json = $this->tryDecryptJsFormat($iv, substr($raw, 12));
$encrypted = substr($ciphertextWithTag, 0, -16);
$json = openssl_decrypt($encrypted, 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $iv, $tag);
if (false !== $json) {
return json_decode($json, true);
}
}
// Fallback: PHP format iv (12) + tag (16) + ciphertext // Fallback: PHP format iv (12) + tag (16) + ciphertext
$tag = substr($raw, 12, 16); $json ??= openssl_decrypt(substr($raw, 28), 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $iv, substr($raw, 12, 16)) ?: null;
$encrypted = substr($raw, 28);
$json = openssl_decrypt($encrypted, 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $iv, $tag); return $json ? json_decode($json, true) : null;
if (false === $json) { }
private function tryDecryptJsFormat(string $iv, string $ciphertextWithTag): ?string
{
if (\strlen($ciphertextWithTag) < 16) {
return null; return null;
} }
return json_decode($json, true); $json = openssl_decrypt(substr($ciphertextWithTag, 0, -16), 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $iv, substr($ciphertextWithTag, -16));
return false !== $json ? $json : null;
} }
public function generateVisitorHash(string $uid): string public function generateVisitorHash(string $uid): string

View File

@@ -174,7 +174,11 @@ class InfraService
$issuer = $cert['issuer']['O'] ?? $cert['issuer']['CN'] ?? '?'; $issuer = $cert['issuer']['O'] ?? $cert['issuer']['CN'] ?? '?';
return [ return [
'status' => $daysLeft > 7 ? 'ok' : ($daysLeft > 0 ? 'warning' : 'error'), 'status' => match (true) {
$daysLeft > 7 => 'ok',
$daysLeft > 0 => 'warning',
default => 'error',
},
'domain' => $host, 'domain' => $host,
'issuer' => $issuer, 'issuer' => $issuer,
'valid_until' => $validTo->format('d/m/Y'), 'valid_until' => $validTo->format('d/m/Y'),
@@ -483,16 +487,11 @@ class InfraService
public static function fmtDuration(int $seconds): string public static function fmtDuration(int $seconds): string
{ {
if ($seconds >= 86400) { return match (true) {
return round($seconds / 86400, 1).'j'; $seconds >= 86400 => round($seconds / 86400, 1).'j',
} $seconds >= 3600 => round($seconds / 3600, 1).'h',
if ($seconds >= 3600) { $seconds >= 60 => round($seconds / 60).'min',
return round($seconds / 3600, 1).'h'; default => $seconds.'s',
} };
if ($seconds >= 60) {
return round($seconds / 60).'min';
}
return $seconds.'s';
} }
} }