discovery-media-player 0.1.114 → 0.1.115

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discovery-media-player",
3
- "version": "0.1.114",
3
+ "version": "0.1.115",
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",
@@ -66,7 +66,8 @@
66
66
  "typecheck": "node -e \"require('fs').existsSync('tsconfig.json')||(console.error('Ce script ne vit pas dans le paquet publié - le champ scripts annonce plus que le tarball ne contient. Clonez le depot puis npm ci : https://github.com/Juli1artha/discovery-media-player'),process.exit(1))\" && tsc --noEmit",
67
67
  "prepublishOnly": "npm run build && npm test",
68
68
  "test:e2e": "node -e \"require('fs').existsSync('vitest.e2e.config.mjs')||(console.error('Ce banc ne vit pas dans le paquet publié - le champ scripts annonce plus que le tarball ne contient. Clonez le depot puis npm ci : https://github.com/Juli1artha/discovery-media-player'),process.exit(1))\" && vitest run --config vitest.e2e.config.mjs",
69
- "test:base": "node -e \"require('fs').existsSync('vitest.base.config.mjs')||(console.error('Ce banc ne vit pas dans le paquet publié - le champ scripts annonce plus que le tarball ne contient. Clonez le depot puis npm ci : https://github.com/Juli1artha/discovery-media-player'),process.exit(1))\" && vitest run --config vitest.base.config.mjs"
69
+ "test:base": "node -e \"require('fs').existsSync('vitest.base.config.mjs')||(console.error('Ce banc ne vit pas dans le paquet publié - le champ scripts annonce plus que le tarball ne contient. Clonez le depot puis npm ci : https://github.com/Juli1artha/discovery-media-player'),process.exit(1))\" && vitest run --config vitest.base.config.mjs",
70
+ "test:charge": "node -e \"require('fs').existsSync('vitest.charge.config.mjs')||(console.error('Ce banc ne vit pas dans le paquet publié - le champ scripts annonce plus que le tarball ne contient. Clonez le depot puis npm ci : https://github.com/Juli1artha/discovery-media-player'),process.exit(1))\" && vitest run --config vitest.charge.config.mjs"
70
71
  },
71
72
  "engines": {
72
73
  "node": ">=22"
package/server/handler.js CHANGED
@@ -610,6 +610,20 @@ async function handler(req, res) {
610
610
  return typeof signer === "function" && !!signer("carte-sonde", "carte-sonde", 60);
611
611
  } catch { return false; }
612
612
  })(),
613
+ // ⚠️ LA PORTE REFUSE-T-ELLE, OU EST-ELLE SEULEMENT CONFIGURÉE POUR REFUSER ? `presenceStrict`
614
+ // au-dessus dit que la porte refuse les battements sans preuve — vrai, et mesuré (il exige de
615
+ // pouvoir émettre). Mais le contrôle anti-usurpation des BOOTSTRAPS, lui, peut être désarmé
616
+ // sans que rien ne le dise : 0018 absente, ou — avant 0.1.111 — un simple hoquet réseau. On
617
+ // avait fermé cet écart sur `presenceJetons` en mesurant plutôt qu'en déclarant, et laissé le
618
+ // champ voisin ouvert. (Nommé par le second hôte.)
619
+ //
620
+ // ⚠️ TROIS ÉTATS. « inconnu » n'est pas « actif » : un processus qui n'a pas encore servi de
621
+ // bootstrap n'a rien constaté, et annoncer une garde active sur une absence d'observation est
622
+ // exactement ce qu'on refuse ailleurs. On ne peut pas sonder la fonction sans l'appeler — elle
623
+ // écrit — donc on rend ce qui a été CONSTATÉ à l'usage, jamais une déduction.
624
+ presenceDurcissement: (() => {
625
+ try { return require("./presentations").etatDurcissementBootstrap(); } catch { return "inconnu"; }
626
+ })(),
613
627
  // ⚠️ LES JETONS DE PRÉSENCE SONT-ILS RÉELLEMENT ÉMIS ? Sans ce booléen, un exploitant qui vient
614
628
  // de poser `PLAYER_PRESENCE_SECRET` n'a AUCUN moyen de vérifier que son réglage a pris : la
615
629
  // carte affiche `presence: {0,0}` aussi bien quand le secret est actif que quand la variable est
@@ -6,7 +6,25 @@ const crypto = require("crypto");
6
6
  // ⚠️ Le contexte est REÇU, pas construit. Ce module ne doit pas savoir d'où il vient : c'est ce
7
7
  // qui lui permettra de partir dans le dépôt du player sans emporter le studio avec lui.
8
8
  let PLAYER = null;
9
- function init(ctx) { PLAYER = ctx; _bumpSansDurcissementJusqua = 0; _avertRpcPresence = false; }
9
+ function init(ctx) { PLAYER = ctx; _bumpSansDurcissementJusqua = 0; _avertRpcPresence = false; _bumpDurcissementTente = false; }
10
+
11
+ /**
12
+ * L'état OBSERVÉ du durcissement des bootstraps — pas sa configuration.
13
+ *
14
+ * ⚠️ LA CARTE RAPPORTAIT UNE CONFIGURATION, PAS UN COMPORTEMENT, et c'est le second hôte qui l'a
15
+ * nommé : `presenceStrict` pouvait dire « la porte refuse » alors que le contrôle anti-usurpation
16
+ * était désarmé — 0018 absente, ou (avant 0.1.111) un simple hoquet réseau. On a fermé cet écart sur
17
+ * `presenceJetons` en MESURANT plutôt qu'en déclarant, et on l'avait laissé ouvert sur le champ voisin.
18
+ *
19
+ * On ne peut pas sonder la fonction sans l'appeler — elle écrit. Ce qu'on peut rendre, c'est ce que le
20
+ * processus a CONSTATÉ en s'en servant : « degrade » = la dernière tentative a trouvé la signature
21
+ * absente ; « actif » = une tentative a abouti ; « inconnu » = on n'a pas encore essayé, et c'est un
22
+ * état à part entière, pas un feu vert.
23
+ */
24
+ function etatDurcissementBootstrap() {
25
+ if (Date.now() < _bumpSansDurcissementJusqua) return "degrade";
26
+ return _bumpDurcissementTente ? "actif" : "inconnu";
27
+ }
10
28
 
11
29
 
12
30
  const enc = encodeURIComponent;
@@ -811,12 +829,18 @@ function signatureAbsente(erreur) {
811
829
  // silence. Un « oui » (la signature existe) n'a pas besoin d'expirer : une fonction ne disparaît pas.
812
830
  let _bumpSansDurcissementJusqua = 0;
813
831
  const MEMO_SANS_DURCISSEMENT_MS = 60 * 1000;
832
+ // ⚠️ A-T-ON SEULEMENT ESSAYÉ ? « Pas dégradé » n'est pas « vérifié » : un processus qui vient de
833
+ // démarrer n'a rien tenté, et rendre `true` reviendrait à annoncer une garde active sur la foi d'une
834
+ // absence d'observation. Trois états, donc — la même règle que le verdict du schéma, où « rien de
835
+ // manquant » se lisait « tout va bien » tant qu'on ne distinguait pas « rien demandé ».
836
+ let _bumpDurcissementTente = false;
814
837
  async function appelerBump(corps, durcissementVoulu) {
815
838
  const appel = (b) => PLAYER.db.request("rpc/player_attendance_bump", { method: "POST", body: b });
816
839
  if (durcissementVoulu && Date.now() < _bumpSansDurcissementJusqua) {
817
840
  const { p_only_if_unclaimed: _retire, ...sansDurcissement } = corps;
818
841
  return appel(sansDurcissement);
819
842
  }
843
+ if (durcissementVoulu) _bumpDurcissementTente = true;
820
844
  try {
821
845
  return await appel(corps);
822
846
  } catch (erreur) {
@@ -1183,4 +1207,4 @@ async function listPresentationsForDoc(docId, email, isAdmin, autoriseLarge) {
1183
1207
  module.exports = {
1184
1208
  reacteurDepuisJeton,
1185
1209
  purgerPerimees,
1186
- messagePublic, CHAMPS_PUBLICS, cheminPieceJointe, init, createPresentation, getPresentation, setPage, endPresentation, addMessage, listMessages, toggleReaction, editMessage, deleteMessage, setChatLock, createUploadUrl, reclaimPresentation, touchPresentation, listActivePresentations, handoverPresentation, endPresentationByOwner, recordAttendance, presentationStats, listPresentationsForDoc, switchPresentationDoc, setPresentationContent , STALE_MS};
1210
+ messagePublic, CHAMPS_PUBLICS, etatDurcissementBootstrap, cheminPieceJointe, init, createPresentation, getPresentation, setPage, endPresentation, addMessage, listMessages, toggleReaction, editMessage, deleteMessage, setChatLock, createUploadUrl, reclaimPresentation, touchPresentation, listActivePresentations, handoverPresentation, endPresentationByOwner, recordAttendance, presentationStats, listPresentationsForDoc, switchPresentationDoc, setPresentationContent , STALE_MS};