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:
@@ -41,13 +41,8 @@ class ApiAccountController extends AbstractController
|
||||
|
||||
$user = $em->getRepository(User::class)->findOneBy(['email' => $email]);
|
||||
|
||||
if (!$user) {
|
||||
return $this->error('Utilisateur introuvable.', 404);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'id' => $user->getId(),
|
||||
'stripeAccountId' => $user->getStripeAccountId(),
|
||||
]);
|
||||
return $user
|
||||
? $this->success(['id' => $user->getId(), 'stripeAccountId' => $user->getStripeAccountId()])
|
||||
: $this->error('Utilisateur introuvable.', 404);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
class AttestationController extends AbstractController
|
||||
{
|
||||
private const TPL_NOT_FOUND_VENTES = 'attestation/not_found_ventes.html.twig';
|
||||
public function __construct(
|
||||
#[Autowire('%kernel.secret%')] private string $appSecret,
|
||||
) {
|
||||
@@ -50,7 +51,7 @@ class AttestationController extends AbstractController
|
||||
$attestation = $em->getRepository(Attestation::class)->findOneBy(['reference' => $reference]);
|
||||
|
||||
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', [
|
||||
@@ -69,38 +70,47 @@ class AttestationController extends AbstractController
|
||||
['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);
|
||||
if (!$decoded) {
|
||||
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]);
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = explode('|', $decoded, 2);
|
||||
if (2 !== \count($parts)) {
|
||||
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]);
|
||||
return null;
|
||||
}
|
||||
|
||||
[$signature, $jsonPayload] = $parts;
|
||||
$expectedSignature = hash_hmac('sha256', $jsonPayload, $this->appSecret);
|
||||
|
||||
if (!hash_equals($expectedSignature, $signature)) {
|
||||
return $this->render('attestation/not_found_ventes.html.twig', ['breadcrumbs' => $breadcrumbs]);
|
||||
return null;
|
||||
}
|
||||
|
||||
$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);
|
||||
$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,
|
||||
]);
|
||||
return $data ? ['data' => $data, 'signatureHash' => $expectedSignature] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,30 +33,26 @@ class AnalyticsCryptoService
|
||||
return null;
|
||||
}
|
||||
|
||||
// Try JS format first: iv (12) + ciphertext_with_tag (tag is last 16 bytes)
|
||||
$iv = substr($raw, 0, 12);
|
||||
$ciphertextWithTag = substr($raw, 12);
|
||||
|
||||
if (\strlen($ciphertextWithTag) >= 16) {
|
||||
$tag = substr($ciphertextWithTag, -16);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
// Try JS format first: iv (12) + ciphertext_with_tag (tag is last 16 bytes)
|
||||
$json = $this->tryDecryptJsFormat($iv, substr($raw, 12));
|
||||
|
||||
// Fallback: PHP format iv (12) + tag (16) + ciphertext
|
||||
$tag = substr($raw, 12, 16);
|
||||
$encrypted = substr($raw, 28);
|
||||
$json ??= openssl_decrypt(substr($raw, 28), 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $iv, substr($raw, 12, 16)) ?: null;
|
||||
|
||||
$json = openssl_decrypt($encrypted, 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $iv, $tag);
|
||||
if (false === $json) {
|
||||
return $json ? json_decode($json, true) : null;
|
||||
}
|
||||
|
||||
private function tryDecryptJsFormat(string $iv, string $ciphertextWithTag): ?string
|
||||
{
|
||||
if (\strlen($ciphertextWithTag) < 16) {
|
||||
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
|
||||
|
||||
@@ -174,7 +174,11 @@ class InfraService
|
||||
$issuer = $cert['issuer']['O'] ?? $cert['issuer']['CN'] ?? '?';
|
||||
|
||||
return [
|
||||
'status' => $daysLeft > 7 ? 'ok' : ($daysLeft > 0 ? 'warning' : 'error'),
|
||||
'status' => match (true) {
|
||||
$daysLeft > 7 => 'ok',
|
||||
$daysLeft > 0 => 'warning',
|
||||
default => 'error',
|
||||
},
|
||||
'domain' => $host,
|
||||
'issuer' => $issuer,
|
||||
'valid_until' => $validTo->format('d/m/Y'),
|
||||
@@ -483,16 +487,11 @@ class InfraService
|
||||
|
||||
public static function fmtDuration(int $seconds): string
|
||||
{
|
||||
if ($seconds >= 86400) {
|
||||
return round($seconds / 86400, 1).'j';
|
||||
}
|
||||
if ($seconds >= 3600) {
|
||||
return round($seconds / 3600, 1).'h';
|
||||
}
|
||||
if ($seconds >= 60) {
|
||||
return round($seconds / 60).'min';
|
||||
}
|
||||
|
||||
return $seconds.'s';
|
||||
return match (true) {
|
||||
$seconds >= 86400 => round($seconds / 86400, 1).'j',
|
||||
$seconds >= 3600 => round($seconds / 3600, 1).'h',
|
||||
$seconds >= 60 => round($seconds / 60).'min',
|
||||
default => $seconds.'s',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user