+170
−0
Loading
Premier des cinq points de durcissement relevés par la revue de sécurité de d6950149. Un appel qui sonne sans réponse est désormais abandonné. Ce que ça répare Deux défauts, dont le second est le plus grave. La sonnerie du navigateur bouclait indéfiniment : `startRingtone` répétait toutes les 2 s sans plafond. Et surtout, un appel jamais décroché maintenait le joueur en PLAYER_BUSY, donc INJOIGNABLE pour tout le reste de l'exercice — un appel manqué condamnait le téléphone du personnage. Où vit le minuteur, et pourquoi Dans VoiceService, pas dans la passerelle. `end()` est le passage obligé de TOUS les chemins de fin : refus, raccrochage, déconnexion de l'un ou l'autre pair. Désarmer à cet endroit unique suffit, là où un minuteur porté par la passerelle aurait exigé un clearTimeout dans quatre gestionnaires — dont un aurait fini par être oublié. C'est exactement la classe de défaut corrigée juste avant sur le contrôle d'impersonnification, et il aurait été absurde de la réintroduire en la réparant ailleurs. Le service ignorant Socket.IO, il ne peut pas annoncer l'abandon lui-même : la passerelle lui fournit l'annonce via `onRingTimeout()` dans `afterInit()`. La dépendance reste dans le bon sens, le service ne connaissant toujours pas la passerelle qui le connaît. 45 s et non 30 : un téléphone réel renonce vers 30 s, mais en exercice le joueur peut être en train de rédiger sa main courante, et mieux vaut lui laisser le temps de revenir à l'onglet. Le minuteur ne borne que la SONNERIE Il est désarmé au décrochage. Couper une conversation en cours serait un défaut, pas une protection : un point de situation en exercice peut légitimement durer. Lecture d'exercice L'abandon est distingué d'un raccrochage — `by: 'TIMEOUT'` sur l'événement, « Sans réponse » côté animateur, « sans réponse » au journal avec la durée de sonnerie. Ne pas décrocher est une observation d'exercice, pas un incident technique : le RETEX doit pouvoir le lire comme tel. Tests 7 tests à horloge simulée, dont 4 tombent quand l'armement du minuteur est retiré. Les 3 autres sont des contre-épreuves, qui doivent passer dans les deux cas : pas d'abandon une seconde avant l'échéance, pas de coupure d'une conversation décrochée, pas de double écriture au journal si l'appel a déjà été raccroché. Le minuteur est `unref()` et purgé à l'extinction du module, pour ne retenir ni le processus ni le harnais de test. 234 tests / 23 suites, eslint et typechecks verts. Espace joueur revérifié dans le navigateur après reconstruction. Durcissement restant Identifiants TURN statiques remis aux joueurs, sans objet tant que WEBRTC_ICE_SERVERS est vide. Absence de limitation de débit sur `voice:call`. Charges SDP et ICE relayées sans contrôle de forme. Adresses IP révélées entre pairs, inhérent à WebRTC. Co-Authored-By: Claude (RCA)