license: force UTC + fixed-Z date format on both sides

Symptom: "Réponse serveur non authentifiée (signature invalide)" on
license activation. Root cause: PHP \DateTimeInterface::ATOM emits the
server's local timezone offset (e.g. +02:00 on a CET host), while the
C# canonicalizer emitted +00:00 after ToUniversalTime(). Same instant,
different string, different bytes, signature mismatch.

Server (ValidateLicense.php):
- All timestamps now built with `new DateTimeZone('UTC')` and formatted
  as 'Y-m-d\TH:i:s\Z' — fixed string, no offset variation.
- Reads issued_at / download_entitlement_until from MySQL as UTC; the
  display is consistent with what the client sees.

Client (LicenseService.cs):
- FormatDateAtom now produces "yyyy-MM-ddTHH:mm:ssZ" with literal Z and
  handles null safely (previous version would have produced "Z" alone
  for a null input thanks to string + null concatenation).

Both sides therefore agree on the canonical bytes for any datetime,
including across daylight savings transitions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 11:27:55 +02:00
parent 558fa93f2c
commit 1a3910ef9d
4 changed files with 63 additions and 12 deletions

View File

@@ -0,0 +1,43 @@
<?php
// === À RENSEIGNER LORS DU DÉPLOIEMENT ===
// Copier ce fichier en config.php sur le serveur, puis le compléter.
// Le fichier config.php est gitignored.
return [
// Base path public sous lequel le launcher est servi
'base_url' => 'https://asterionvr.com/PS_Launcher',
// MySQL (depuis le manager OVH : Hébergements -> Bases de données)
'db' => [
// Format DSN OVH typique : mysql:host=<bdd>.mysql.db;dbname=<bdd>;charset=utf8mb4
'dsn' => 'mysql:host=localhost;dbname=replace_me;charset=utf8mb4',
'username' => 'replace_me',
'password' => 'replace_me',
],
// HMAC secret pour les URLs présignées de /builds/ (v0.6, optionnel)
// Génère 64 hex chars : `php -r "echo bin2hex(random_bytes(32));"`
'hmac_secret' => 'replace_with_random_64_bytes_hex',
// Clés Ed25519 pour signer la réponse de validation license et le manifest.
// Génère le keypair via : `php tools/generate-keypair.php`
// Recopie les hex strings ci-dessous, et embarque la public_key_hex dans le launcher.
'ed25519' => [
'private_key_hex' => '', // 128 hex chars (sodium secret key, contient la pub key)
'public_key_hex' => '', // 64 hex chars (32 bytes)
],
// (v0.4-β) JWT pour les URLs de download protégées (optionnel pour le moment)
'jwt_secret' => 'replace_with_random_secret',
'jwt_ttl_seconds' => 900, // 15 min
// Limites de validation
'validate_max_per_minute_per_ip' => 10,
// === BACKOFFICE ADMIN ===
// Mot de passe bcrypt pour la connexion à /PS_Launcher/admin/
// Génère le hash via SSH OVH :
// php -r "echo password_hash('motdepasse_choisi', PASSWORD_DEFAULT);"
// puis colle le résultat ci-dessous.
'admin_password_hash' => '',
];