Paillasse/portail/app/Services/Visio/JetonVisio.php

53 lines
1.7 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\Visio;
use App\Models\Seance;
use RuntimeException;
/**
* Jeton JWT (HS256) qui ouvre une salle Jitsi : Prosody le vérifie avec le
* même secret. Le nom vient du jeton et ne se modifie pas ; seul le prof a
* moderator = true (module natif token_affiliation de Prosody).
*/
class JetonVisio
{
public function pour(Seance $seance, string $identifiant, string $nom, bool $moderateur): string
{
$secret = config('visio.jwt.secret');
if (! is_string($secret) || strlen($secret) < 32 || $seance->visio_salle === null) {
throw new RuntimeException('Visio non configurée ou salle non ouverte.');
}
$maintenant = time();
$charge = [
'iss' => config('visio.jwt.app_id'),
'aud' => config('visio.jwt.audience'),
'sub' => '*',
'room' => $seance->visio_salle,
'iat' => $maintenant,
'nbf' => $maintenant - 10,
'exp' => $maintenant + 60 * (int) config('visio.jwt.duree_minutes'),
'context' => [
'user' => [
'id' => $identifiant,
'name' => $nom,
'moderator' => $moderateur,
],
],
];
$entete = $this->base64Url(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
$corps = $this->base64Url(json_encode($charge, JSON_UNESCAPED_UNICODE));
$signature = $this->base64Url(hash_hmac('sha256', "{$entete}.{$corps}", $secret, true));
return "{$entete}.{$corps}.{$signature}";
}
private function base64Url(string $donnees): string
{
return rtrim(strtr(base64_encode($donnees), '+/', '-_'), '=');
}
}