discovery-media-player 0.1.8 → 0.1.9

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/README.md CHANGED
@@ -189,6 +189,11 @@ the player, not the people plugging into it.
189
189
  [`CONTRIBUTING.md`](CONTRIBUTING.md) — how to run the tests, what the review looks for, and the
190
190
  one rule that matters: a behaviour worth keeping is worth a test that fails without it.
191
191
 
192
+ Your first pull request asks you to sign the [CLA](CLA.md) — one reply, once, for good. You keep
193
+ the copyright in your work; you grant a licence that may be sublicensed, so that the core can stay
194
+ AGPL while a commercial licence remains possible for organisations that cannot live with the
195
+ network clause. Better said before you write the patch than after.
196
+
192
197
  The code comments are in French. The project was built in a French company and the reasoning
193
198
  behind each decision is written where the decision is; translating it would have meant either
194
199
  losing it or maintaining two versions. Everything an integrator needs is in English.
@@ -11,7 +11,7 @@
11
11
  // déléguées à des routes de l'hôte, ou refusées si elles ne sont pas configurées.
12
12
  //
13
13
  // ⚠️ Il ne remplace pas un câblage : il ne sait rien de vos rôles. Ce qu'il ne sait pas, il le
14
- // REFUSE — jamais il n'accorde par défaut. Cf. CONTRAT.md, « Le câblage d'une instance ».
14
+ // REFUSE — jamais il n'accorde par défaut. Cf. docs/CONFIGURATION.md, « Decisions that are yours ».
15
15
 
16
16
  const storage = require("./storage");
17
17
 
@@ -289,6 +289,12 @@ function createStandaloneContext(env = process.env) {
289
289
  supabasePublishableKey: env.SUPABASE_PUBLISHABLE_KEY || "",
290
290
  mapsKey: env.GOOGLE_MAPS_API_KEY || "",
291
291
  extraFrameAncestors: String(env.DOC_FRAME_ANCESTORS || "").split(/\s+/).filter(Boolean),
292
+ // ⚠️ Un BOOLÉEN, jamais l'URL. La carte d'identité doit pouvoir dire « un émetteur distinct
293
+ // est configuré » sans dire lequel : c'est le dernier endroit où un hôte devait deviner.
294
+ // `host-auth` dit que le code SAIT faire la séparation ; ceci dit qu'elle est POSÉE. Sans
295
+ // les deux, une variable oubliée redonne exactement le symptôme que 0.1.8 a retiré — des
296
+ // membres « non authentifiés », ce qui ressemble à un droit manquant.
297
+ separateIssuer: !!sansBarreFinale(env.PLAYER_AUTH_URL),
292
298
  },
293
299
  };
294
300
  }
@@ -25,9 +25,10 @@ need.
25
25
  {
26
26
  "product": "discovery-media-player",
27
27
  "contract": 1,
28
- "version": "0.1.8",
28
+ "version": "0.1.9",
29
29
  "capabilities": ["docshare", "presentations", "embed-denied", "host-fetch", "brand-reference", "host-auth"],
30
30
  "frameAncestors": ["'self'", "https://*.vercel.app", "https://app.example.com"],
31
+ "separateIssuer": true,
31
32
  "plugins": { "bot": false, "visitors": false, "brandIntro": false, "botBrowser": false, "providerQuotas": false }
32
33
  }
33
34
  ```
@@ -67,8 +68,14 @@ things. They are the same project while the player and your application share a
67
68
  different by construction once the instance is separate. Point `PLAYER_AUTH_URL` at the project
68
69
  that issues your members' tokens (with its own publishable key in `PLAYER_AUTH_KEY`), or every
69
70
  member action is refused in a way that reads like a missing permission. Unset, it falls back to
70
- the player's own project, so a shared deployment changes by not one character. The `host-auth`
71
- capability tells you an instance supports the split.
71
+ the player's own project, so a shared deployment changes by not one character.
72
+
73
+ Two signals, and you need both: **`host-auth` in `capabilities`** says this instance *can* target
74
+ a separate issuer; **`separateIssuer: true`** says one *is configured*. A version that supports
75
+ the split with the variable left unset fails exactly like the version before it — members come
76
+ back unauthenticated, which reads like a missing permission — and you would conclude the upgrade
77
+ changed nothing. The card answers with a boolean and never the issuer itself: you already know
78
+ which one is yours.
72
79
 
73
80
  ### 2. What a client's brand is
74
81
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discovery-media-player",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
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,12 +66,12 @@
66
66
  "node": ">=22"
67
67
  },
68
68
  "devDependencies": {
69
- "@eslint/js": "^9.39.4",
70
- "esbuild": "^0.25.12",
71
- "eslint": "^9.39.4",
69
+ "@eslint/js": "^10.0.1",
70
+ "esbuild": "^0.28.2",
71
+ "eslint": "^10.8.1",
72
72
  "jsdom": "^25.0.1",
73
73
  "typescript": "^5.5.4",
74
74
  "typescript-eslint": "^8.46.4",
75
- "vitest": "^3.2.7"
75
+ "vitest": "^4.1.10"
76
76
  }
77
77
  }
package/server/handler.js CHANGED
@@ -1172,7 +1172,7 @@ const LEGAL_CSS = `
1172
1172
  function sendHtml(res, status, html, scriptSrc, imgExtra, frameAncestors) {
1173
1173
  res.statusCode = status;
1174
1174
  // Origine Supabase Storage (voix ElevenLabs mise en cache dans le bucket public tts-cache) → autorisée en media-src.
1175
- let supaOrigin = ""; try { supaOrigin = new URL(process.env.SUPABASE_URL || "").origin; } catch { supaOrigin = ""; }
1175
+ let supaOrigin; try { supaOrigin = new URL(process.env.SUPABASE_URL || "").origin; } catch { supaOrigin = ""; }
1176
1176
  res.setHeader("Content-Type", "text/html; charset=utf-8");
1177
1177
  res.setHeader("Cache-Control", "no-store, max-age=0");
1178
1178
  res.setHeader("X-Content-Type-Options", "nosniff");
@@ -2595,6 +2595,11 @@ async function handler(req, res) {
2595
2595
  // autrement — le navigateur bloque avant tout script, et rien ne peut lui être émis.
2596
2596
  // Ce n'est pas un secret : ces mêmes valeurs partent dans chaque en-tête CSP servi.
2597
2597
  frameAncestors: ["'self'", "https://*.vercel.app"].concat(PLAYER.config.extraFrameAncestors || []),
2598
+ // Même besoin que `frameAncestors`, l'inverse de la réponse : là on nomme les origines
2599
+ // parce qu'un hôte doit voir que LA SIENNE manque ; ici un booléen suffit, parce que
2600
+ // l'hôte connaît déjà son émetteur — il veut seulement savoir si l'instance le regarde.
2601
+ // Dire lequel n'aiderait personne et renseignerait qui sonde.
2602
+ separateIssuer: !!(PLAYER.config && PLAYER.config.separateIssuer),
2598
2603
  // Greffons de l'hôte : présents ou coupés (PLAYER_PLUGINS_OFF). Booléens uniquement.
2599
2604
  plugins: {
2600
2605
  bot: !!p.bot, visitors: !!p.visitors, brandIntro: !!p.brandIntro,