discovery-media-player 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server/handler.js +45 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "discovery-media-player",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "Self-hosted document viewer: per-recipient tracked links, reading analytics, live presentation. The core knows nothing about the application hosting it — everything it borrows arrives through an injected context.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pdf-viewer",
|
package/server/handler.js
CHANGED
|
@@ -399,12 +399,53 @@ var Live=(function(){
|
|
|
399
399
|
ch.on('presence',{event:'sync'},function(){renderPres(ch.presenceState());});
|
|
400
400
|
// Plus d'abonnement à la table des messages : elle n'est plus publiée ni lisible
|
|
401
401
|
// publiquement. Tout passe par la diffusion, et l'historique par la route de chat.
|
|
402
|
-
|
|
403
|
-
|
|
402
|
+
// ⚠️ UNE DIFFUSION EST UN SIGNAL, PAS UNE VÉRITÉ.
|
|
403
|
+
//
|
|
404
|
+
// Ce canal est PUBLIC : la clé publiable et le slug sont dans la page, donc tout participant
|
|
405
|
+
// peut émettre. Appliquer directement la charge utile revenait à laisser n'importe quel
|
|
406
|
+
// spectateur annoncer la fin de la présentation, changer la page affichée, verrouiller le
|
|
407
|
+
// chat, ou publier un message signé du nom de quelqu'un d'autre.
|
|
408
|
+
//
|
|
409
|
+
// Déplacer l'émission vers le serveur n'y changerait rien : sur un canal public, un
|
|
410
|
+
// attaquant émet quand même, et le client ne distingue pas les deux sources. La seule
|
|
411
|
+
// défense qui tienne est de CESSER DE CROIRE le transport — on relit auprès du serveur, qui
|
|
412
|
+
// est déjà la source de vérité (routes state=1 et chat=1, elles existaient).
|
|
413
|
+
//
|
|
414
|
+
// Un attaquant peut donc toujours émettre : il déclenche une relecture, et n'obtient rien.
|
|
415
|
+
// C'est une meilleure propriété que d'essayer de l'empêcher — elle vaut aussi le jour où le
|
|
416
|
+
// transport lui-même a un défaut.
|
|
417
|
+
//
|
|
418
|
+
// ⚠️ 'map' et 'typing' restent appliqués tels quels, et c'est un choix : ce sont des signaux
|
|
419
|
+
// ÉPHÉMÈRES (mouvements de carte, « untel écrit »), sans état serveur à confronter et à
|
|
420
|
+
// fréquence élevée. Les revérifier coûterait un aller-retour par déplacement de souris pour
|
|
421
|
+
// protéger… un déplacement de souris. Ce qui fait autorité — la page affichée, le document,
|
|
422
|
+
// la fin de la présentation — passe par 'state', qui est relu.
|
|
423
|
+
function relire(url,applique){
|
|
424
|
+
fetch('/api/doc?present='+encodeURIComponent(SLUG)+url)
|
|
425
|
+
.then(function(r){return r.json();})
|
|
426
|
+
.then(function(d){if(d&&d.ok)applique(d);})
|
|
427
|
+
.catch(function(){});
|
|
428
|
+
}
|
|
429
|
+
var _relEtat=null,_relChat=null;
|
|
430
|
+
// Groupé : dix diffusions d'affilée ne doivent pas produire dix requêtes.
|
|
431
|
+
function relireEtat(){clearTimeout(_relEtat);_relEtat=setTimeout(function(){
|
|
432
|
+
relire('&state=1',function(d){if(d.state&&_onState)_onState(d.state);});
|
|
433
|
+
},120);}
|
|
434
|
+
function relireChat(){clearTimeout(_relChat);_relChat=setTimeout(function(){
|
|
435
|
+
relire('&chat=1',function(d){
|
|
436
|
+
if(d.messages)d.messages.forEach(function(m){if(!addMsg(m))updateMsg(m);});
|
|
437
|
+
if(typeof d.locked!=='undefined')applyLock(d.locked);
|
|
438
|
+
});
|
|
439
|
+
},120);}
|
|
440
|
+
|
|
441
|
+
// Le message reçu sert à savoir QU'IL SE PASSE quelque chose, et à notifier ; son CONTENU
|
|
442
|
+
// vient de la relecture. Sans ça, une notification pourrait afficher un texte forgé.
|
|
443
|
+
ch.on('broadcast',{event:'msg'},function(){relireChat();});
|
|
444
|
+
ch.on('broadcast',{event:'msg-upd'},function(){relireChat();});
|
|
445
|
+
ch.on('broadcast',{event:'lock'},function(){relireChat();});
|
|
446
|
+
ch.on('broadcast',{event:'state'},function(){relireEtat();});
|
|
404
447
|
ch.on('broadcast',{event:'typing'},function(p){onTyping(p&&p.payload);});
|
|
405
|
-
ch.on('broadcast',{event:'lock'},function(p){if(p&&p.payload)applyLock(p.payload.locked);});
|
|
406
448
|
ch.on('broadcast',{event:'map'},function(p){if(_onMap&&p&&p.payload)_onMap(p.payload);});
|
|
407
|
-
ch.on('broadcast',{event:'state'},function(p){if(_onState&&p&&p.payload)_onState(p.payload);});
|
|
408
449
|
ch.subscribe(function(st){if(st==='SUBSCRIBED'){ch.track({name:me.name,email:me.email,avatar:me.avatar,role:me.role,member:!!me.member,uid:attKey(me)});sendAttend();}});
|
|
409
450
|
_tyIv=setInterval(renderTyping,1500);
|
|
410
451
|
_atIv=setInterval(sendAttend,25000);
|