Add security key to BilletOrder, QR code helper text

- securityKey: HMAC-SHA256(reference, APP_SECRET) truncated to 16 hex chars
- Generated automatically at ticket creation via BilletOrderService
- Deterministic: same reference + secret = same key, verifiable server-side
- Cannot be forged without knowing APP_SECRET
- PDF: "Presentez ce QR code pour valider votre ticket" under QR code
- PDF: "Cle de securite" displayed with letter-spacing
- Tests: generateSecurityKey determinism, uniqueness, format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-21 16:43:59 +01:00
parent 6cd91a7c8e
commit b0dead8120
5 changed files with 76 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ class BilletOrderTest extends TestCase
self::assertSame(0.0, $ticket->getUnitPriceHTDecimal());
self::assertSame(BilletOrder::STATE_VALID, $ticket->getState());
self::assertTrue($ticket->isValid());
self::assertSame('', $ticket->getSecurityKey());
self::assertNull($ticket->isInvitation());
self::assertNull($ticket->getFirstScannedAt());
self::assertMatchesRegularExpression('/^ETICKET-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/', $ticket->getReference());
@@ -83,6 +84,29 @@ class BilletOrderTest extends TestCase
self::assertTrue($ticket->isValid());
}
public function testSetAndGetSecurityKey(): void
{
$ticket = new BilletOrder();
$result = $ticket->setSecurityKey('ABC123');
self::assertSame('ABC123', $ticket->getSecurityKey());
self::assertSame($ticket, $result);
}
public function testGenerateSecurityKey(): void
{
$key = BilletOrder::generateSecurityKey('ETICKET-ABCD-1234-EFGH', 'my-secret');
self::assertSame(16, \strlen($key));
self::assertMatchesRegularExpression('/^[A-F0-9]{16}$/', $key);
$key2 = BilletOrder::generateSecurityKey('ETICKET-ABCD-1234-EFGH', 'my-secret');
self::assertSame($key, $key2);
$key3 = BilletOrder::generateSecurityKey('ETICKET-XXXX-YYYY-ZZZZ', 'my-secret');
self::assertNotSame($key, $key3);
}
public function testSetAndGetIsInvitation(): void
{
$ticket = new BilletOrder();