openvibers/openvibe.shared Commits
Shared 2.0.0: X-Internal-Key is gone from the shared package (plan T2). internalApiAuth, OpenVibeAuthClient#verifyTokenInternal (Network's deleted /internal/verify-token) and #getUserProfile (a route Network never had) are removed, and the deprecated openvibe-shared/chrome-ssr alias with them (use openvibe-shared/frame). Nothing in the estate used any of it. A test asserts the helpers stay gone. npm test 42/42.
Changes
@@@ -4,6 +4,15 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semvebreaking change to any exported module, browser global or served file name is a new major.A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).++## 2.0.0 — 2026-09-29++++**X-Internal-Key is gone from the shared package** (plan T2: every internal call in the estate uses a service token).++Breaking, and nothing in the estate used any of it:++- `internalApiAuth` (the `middleware` export and the index re-export) is removed.++- `OpenVibeAuthClient#verifyTokenInternal` (Network's `/internal/verify-token`, deleted) and `#getUserProfile` (a route++ Network never had) are removed; the rest of the client is unchanged.++- The deprecated `openvibe-shared/chrome-ssr` alias is removed: use `openvibe-shared/frame`.++## 1.30.1 — 2026-09-28Page moves, measured on Live with a 400 ms network: the bar runs from the click, "Loading Content…" appears at 150 ms and follows the phase ("starting up"), the styled page fades in, and nothing shows unstyled in between. Fixes to 1.30.0: the first move after a server-rendered page is animated (the "first page" is the first `enter()` before any route change, route generation ≤ 1, not simply the first call); `route-transition.js` is fetched a few seconds after load, so it is ready for the first click; the loading line sits over the page's visible area but outside the section (a page script that re-renders its section while loading can no longer take it away); the file is requested by path, so the site's versions map hashes it.@@@ -20,7 +20,7 @@ were reconciled first.| Kind | Files ||---|---|| Browser scripts, served at `/shared/<file>` (listed in `files.js`) | `navbar.js`, `nav-icons.js`, `theme-loader.js`, `footer.js`, `notification-ui.js`, `notification-live.js`, `account-switcher.js`, `user-card.js`, `ov-mark.js`, `ov-icons.js`, `history.js`, `sso-client.js`, `panels.js`, `ui.js`, `island.js`, `tooltip.js`, `release-watch.js`, `release-update.js`, `web-runtime.js`, `openvibe-sw.js` |--| Node modules (`require('openvibe-shared/<name>')`) | `index` (`.`), `analytics` (+ `analytics/{privacy,tracker,retention,schema,event,prune-cli}`), `app-icon`, `auth-client`, `brand`, `builtin-themes`, `frame` (the OpenVibe Frame on the server; `chrome-ssr` is a deprecated alias), `legal`, `middleware`, `notifications`, `seo`, `theme-sync`, `url-resolver`, `files`, `egress` (SSRF-safe addresses and connect-time DNS for outbound fetches of user-chosen hosts), `trace` (the request's W3C trace on outbound calls inside the network), `release`, `release-compat` (tests), `metrics`, `ready`, `config` (the configuration model: revisioned, validated, classified settings with last-known-good and `/api/admin/config`), `test-runner` (the `npm test` runner of every service's `test/run.js`: each `*.test.js` in its own process; a line `<label>: skipped (<why>)` makes a file skipped, listed with ○ and never counted as passed, and `--strict` fails on skips), `perf-budget` (size budgets for a page's first load, measured from the running server: HTML, same-origin scripts and stylesheets, raw and brotli; for `npm test`), `browser-harness` (real-Chrome checks of a running site: status, console errors, overflow, duplicate scripts, no-JS text, canonical, JSON-LD against visible text, axe-core, repeated-navigation growth and idle work; Node 22, Chrome); `footer`, `shipped` (the shared "shipped X ago" pill, recent list and `/updates` log, from the network changelog) and `icons` (= `ov-icons.js`) work on both sides, and `release-update` gives Node its pure `plan()` |++| Node modules (`require('openvibe-shared/<name>')`) | `index` (`.`), `analytics` (+ `analytics/{privacy,tracker,retention,schema,event,prune-cli}`), `app-icon`, `auth-client`, `brand`, `builtin-themes`, `frame` (the OpenVibe Frame on the server), `legal`, `middleware`, `notifications`, `seo`, `theme-sync`, `url-resolver`, `files`, `egress` (SSRF-safe addresses and connect-time DNS for outbound fetches of user-chosen hosts), `trace` (the request's W3C trace on outbound calls inside the network), `release`, `release-compat` (tests), `metrics`, `ready`, `config` (the configuration model: revisioned, validated, classified settings with last-known-good and `/api/admin/config`), `test-runner` (the `npm test` runner of every service's `test/run.js`: each `*.test.js` in its own process; a line `<label>: skipped (<why>)` makes a file skipped, listed with ○ and never counted as passed, and `--strict` fails on skips), `perf-budget` (size budgets for a page's first load, measured from the running server: HTML, same-origin scripts and stylesheets, raw and brotli; for `npm test`), `browser-harness` (real-Chrome checks of a running site: status, console errors, overflow, duplicate scripts, no-JS text, canonical, JSON-LD against visible text, axe-core, repeated-navigation growth and idle work; Node 22, Chrome); `footer`, `shipped` (the shared "shipped X ago" pill, recent list and `/updates` log, from the network changelog) and `icons` (= `ov-icons.js`) work on both sides, and `release-update` gives Node its pure `plan()` || Schemas | `docs/schemas/analytics-event.v1.json` (`analytics/event.v1`, exported as `openvibe-shared/analytics/event.v1.json`) || Generators | `scripts/build-nav-icons.py` (Font Awesome glyphs → `nav-icons.js`, `ov-icons.js`), `scripts/build-navbar-icons.js` (navbar.js's built-in glyphs), `scripts/build-theme-loader.js`, `scripts/build-app-icons.js` |@@@ -116,49 +116,6 @@ class OpenVibeAuthClient {return null;}}---- /**-- * Verify a token via the internal API (server-to-server).-- * Useful as a fallback or for getting fresh user data.-- * @param {string} token-- * @param {string} internalKey - X-Internal-Key header value-- * @returns {Promise<Object|null>}-- */-- async verifyTokenInternal(token, internalKey) {-- try {-- const res = await fetch(`${this.internalBase}/internal/verify-token`, {-- method: 'POST',-- headers: {-- 'Content-Type': 'application/json',-- 'X-Internal-Key': internalKey,-- },-- body: JSON.stringify({ token }),-- });-- if (!res.ok) return null;-- return res.json();-- } catch {-- return null;-- }-- }---- /**-- * Get fresh user profile data via internal API.-- * @param {number} userId-- * @param {string} internalKey-- * @returns {Promise<Object|null>}-- */-- async getUserProfile(userId, internalKey) {-- try {-- const res = await fetch(`${this.internalBase}/internal/user/${userId}/sync`, {-- method: 'POST',-- headers: { 'X-Internal-Key': internalKey },-- });-- if (!res.ok) return null;-- return res.json();-- } catch {-- return null;-- }-- }}module.exports = { OpenVibeAuthClient };ddeleted file mode 100644@@@ -1,4 +0,0 @@--'use strict';--// Deprecated alias: openvibe-shared/chrome-ssr is now openvibe-shared/frame (the OpenVibe Frame). Kept so--// sites on older code keep working; it goes away in 2.0.0.--module.exports = require('./frame');@@@ -1,6 +1,6 @@'use strict';// openvibe-shared/frame — the OpenVibe Frame (the navbar, footer and "shipped" views every OpenVibe site sits--// in): the parts that can be baked into HTML on the server. (Formerly openvibe-shared/chrome-ssr, still an alias.)++// in): the parts that can be baked into HTML on the server. (Formerly openvibe-shared/chrome-ssr; the alias was removed in 2.0.0.)// footer(cfg) the full shared footer (HTML + CSS); the browser's footer.js renders into the same element// noscriptNav(site) a plain navigation bar inside <noscript>: the JavaScript navbar cannot exist without// scripts, so visitors who block them (and text browsers) still get the brand and the network@@@ -3,7 +3,7 @@const { BRAND, BRAND_DEFAULTS, resolveBrandUrls, buildBrandFromRegistry } = require('./brand');const { OpenVibeAuthClient } = require('./auth-client');const { CSS_VARIABLES, DEFAULT_VARS, BUILTIN_THEMES, applyTheme, resolveBuiltinTheme, sanitizeCssValue, loadFromStorage, saveToStorage, syncThemeToServer } = require('./theme-sync');--const { extractToken, requireOpenVibeAuth, optionalOpenVibeAuth, internalApiAuth } = require('./middleware');++const { extractToken, requireOpenVibeAuth, optionalOpenVibeAuth } = require('./middleware');const { PRIORITY, CATEGORY, TYPES, SOUNDS, EMAIL_ELIGIBLE_CATEGORIES, createNotification, DEFAULT_NOTIFICATION_PREFS } = require('./notifications');const { AnalyticsTracker, classifyRequest, parseUserAgent, ANALYTICS_SCHEMA, BOT_USER_AGENTS, SUSPICIOUS_PATTERNS } = require('./analytics');const { URL_DEFINITIONS, normalizeValue, validateValue, resolveRegistryValues, formatRegistryEntry } = require('./url-resolver');@@@ -18,7 +18,6 @@ module.exports = {extractToken,requireOpenVibeAuth,optionalOpenVibeAuth,-- internalApiAuth,// ThemesCSS_VARIABLES,DEFAULT_VARS,@@@ -69,26 +69,8 @@ function optionalOpenVibeAuth(authClient) {};}--/**-- * Internal API authentication middleware.-- * Verifies X-Internal-Key header for server-to-server calls.-- *-- * @param {string} internalKey - Expected key value-- * @returns {Function} Express middleware-- */--function internalApiAuth(internalKey) {-- return (req, res, next) => {-- const provided = req.headers['x-internal-key'];-- if (!provided || provided !== internalKey) {-- return res.status(403).json({ error: 'Forbidden' });-- }-- next();-- };--}--module.exports = {extractToken,requireOpenVibeAuth,optionalOpenVibeAuth,-- internalApiAuth,};@@@ -1,6 +1,6 @@{"name": "openvibe-shared",-- "version": "1.30.1",++ "version": "2.0.0","description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site","main": "index.js","exports": {@@@ -20,7 +20,6 @@"./brand": "./brand.js","./browser-harness": "./browser-harness.js","./builtin-themes": "./builtin-themes.js",-- "./chrome-ssr": "./chrome-ssr.js","./config": "./config.js","./config-pg": "./config-pg.js","./egress": "./egress.js",@@@ -3,7 +3,7 @@// block for a home page and the body of a site's /updates page (shipped.js fills both).const assert = require('assert');const frame = require('../frame');--assert.strictEqual(require('../chrome-ssr'), frame, 'the old name is an alias');++assert.throws(() => require('../chrome-ssr'), /Cannot find module/, 'the chrome-ssr alias is gone (2.0.0)');const home = frame.shipped({ service: 'wiki', title: 'Recently shipped on OpenVibe.Wiki <x>' });assert.ok(home.includes('data-ov-shipped="latest" data-service="wiki" href="/updates"'));@@@ -18,11 +18,11 @@ for (const [sub, target] of Object.entries(pkg.exports)) {assert.strictEqual(require.resolve(sub === '.' ? pkg.name : `${pkg.name}/${sub.slice(2)}`), path.join(ROOT, target), `${sub} resolves`);}// Subpaths in use across Network, Live, Media, Tools, Community and Sites (2026-09-22).--for (const sub of ['analytics', 'app-icon', 'auth-client', 'brand', 'chrome-ssr', 'footer', 'icons', 'legal', 'notifications', 'seo', 'theme-sync', 'url-resolver', 'package.json', 'navbar', 'files']) {++for (const sub of ['analytics', 'app-icon', 'auth-client', 'brand', 'footer', 'icons', 'legal', 'notifications', 'seo', 'theme-sync', 'url-resolver', 'package.json', 'navbar', 'files']) {assert.doesNotThrow(() => require.resolve(`openvibe-shared/${sub}`), `openvibe-shared/${sub}`);}// Server modules load in Node; the navbar module loads too (UMD, no DOM touched at require time).--for (const sub of ['analytics', 'app-icon', 'brand', 'chrome-ssr', 'footer', 'icons', 'legal', 'notifications', 'seo', 'url-resolver', 'files', 'nav-icons', 'metrics', 'ready', 'egress', 'trace', 'config', 'browser-harness']) require(`openvibe-shared/${sub}`);++for (const sub of ['analytics', 'app-icon', 'brand', 'footer', 'icons', 'legal', 'notifications', 'seo', 'url-resolver', 'files', 'nav-icons', 'metrics', 'ready', 'egress', 'trace', 'config', 'browser-harness']) require(`openvibe-shared/${sub}`);// analytics is dependency-free: its parts require only Node built-ins and each other.for (const f of fs.readdirSync(path.join(ROOT, 'analytics'))) {const src = fs.readFileSync(path.join(ROOT, 'analytics', f), 'utf8').replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, '');@@@ -35,3 +35,12 @@ assert.strictEqual(typeof require('openvibe-shared/navbar').init, 'function');assert.ok(/^\d+\.\d+\.\d+$/.test(pkg.version), 'semver version');assert.ok(fs.readFileSync(path.join(ROOT, 'CHANGELOG.md'), 'utf8').includes(`## ${pkg.version}`), 'CHANGELOG has an entry for this version');console.log(`package: ${Object.keys(pkg.exports).length} exports resolve`);++++// 2.0.0: the X-Internal-Key helpers are gone (plan T2), and nothing exported names the key.++{++ const shared = require('..');++ assert.strictEqual(shared.internalApiAuth, undefined, 'internalApiAuth is removed');++ const { OpenVibeAuthClient } = require('../auth-client');++ assert.strictEqual(OpenVibeAuthClient.prototype.verifyTokenInternal, undefined, 'verifyTokenInternal is removed');++ assert.strictEqual(OpenVibeAuthClient.prototype.getUserProfile, undefined, 'getUserProfile is removed');++}
@@ -4,6 +4,15 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
@@ -4,6 +4,15 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
breaking change to any exported module, browser global or served file name is a new major.
breaking change to any exported module, browser global or served file name is a new major.
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
+## 2.0.0 — 2026-09-29
+
+**X-Internal-Key is gone from the shared package** (plan T2: every internal call in the estate uses a service token).
+Breaking, and nothing in the estate used any of it:
+- `internalApiAuth` (the `middleware` export and the index re-export) is removed.
+- `OpenVibeAuthClient#verifyTokenInternal` (Network's `/internal/verify-token`, deleted) and `#getUserProfile` (a route
+ Network never had) are removed; the rest of the client is unchanged.
+- The deprecated `openvibe-shared/chrome-ssr` alias is removed: use `openvibe-shared/frame`.
+
## 1.30.1 — 2026-09-28
## 1.30.1 — 2026-09-28
Page moves, measured on Live with a 400 ms network: the bar runs from the click, "Loading Content…" appears at 150 ms and follows the phase ("starting up"), the styled page fades in, and nothing shows unstyled in between. Fixes to 1.30.0: the first move after a server-rendered page is animated (the "first page" is the first `enter()` before any route change, route generation ≤ 1, not simply the first call); `route-transition.js` is fetched a few seconds after load, so it is ready for the first click; the loading line sits over the page's visible area but outside the section (a page script that re-renders its section while loading can no longer take it away); the file is requested by path, so the site's versions map hashes it.
Page moves, measured on Live with a 400 ms network: the bar runs from the click, "Loading Content…" appears at 150 ms and follows the phase ("starting up"), the styled page fades in, and nothing shows unstyled in between. Fixes to 1.30.0: the first move after a server-rendered page is animated (the "first page" is the first `enter()` before any route change, route generation ≤ 1, not simply the first call); `route-transition.js` is fetched a few seconds after load, so it is ready for the first click; the loading line sits over the page's visible area but outside the section (a page script that re-renders its section while loading can no longer take it away); the file is requested by path, so the site's versions map hashes it.
@@ -20,7 +20,7 @@ were reconciled first.
@@ -20,7 +20,7 @@ were reconciled first.
| Kind | Files |
| Kind | Files |
|---|---|
|---|---|
| Browser scripts, served at `/shared/<file>` (listed in `files.js`) | `navbar.js`, `nav-icons.js`, `theme-loader.js`, `footer.js`, `notification-ui.js`, `notification-live.js`, `account-switcher.js`, `user-card.js`, `ov-mark.js`, `ov-icons.js`, `history.js`, `sso-client.js`, `panels.js`, `ui.js`, `island.js`, `tooltip.js`, `release-watch.js`, `release-update.js`, `web-runtime.js`, `openvibe-sw.js` |
| Browser scripts, served at `/shared/<file>` (listed in `files.js`) | `navbar.js`, `nav-icons.js`, `theme-loader.js`, `footer.js`, `notification-ui.js`, `notification-live.js`, `account-switcher.js`, `user-card.js`, `ov-mark.js`, `ov-icons.js`, `history.js`, `sso-client.js`, `panels.js`, `ui.js`, `island.js`, `tooltip.js`, `release-watch.js`, `release-update.js`, `web-runtime.js`, `openvibe-sw.js` |
-| Node modules (`require('openvibe-shared/<name>')`) | `index` (`.`), `analytics` (+ `analytics/{privacy,tracker,retention,schema,event,prune-cli}`), `app-icon`, `auth-client`, `brand`, `builtin-themes`, `frame` (the OpenVibe Frame on the server; `chrome-ssr` is a deprecated alias), `legal`, `middleware`, `notifications`, `seo`, `theme-sync`, `url-resolver`, `files`, `egress` (SSRF-safe addresses and connect-time DNS for outbound fetches of user-chosen hosts), `trace` (the request's W3C trace on outbound calls inside the network), `release`, `release-compat` (tests), `metrics`, `ready`, `config` (the configuration model: revisioned, validated, classified settings with last-known-good and `/api/admin/config`), `test-runner` (the `npm test` runner of every service's `test/run.js`: each `*.test.js` in its own process; a line `<label>: skipped (<why>)` makes a file skipped, listed with ○ and never counted as passed, and `--strict` fails on skips), `perf-budget` (size budgets for a page's first load, measured from the running server: HTML, same-origin scripts and stylesheets, raw and brotli; for `npm test`), `browser-harness` (real-Chrome checks of a running site: status, console errors, overflow, duplicate scripts, no-JS text, canonical, JSON-LD against visible text, axe-core, repeated-navigation growth and idle work; Node 22, Chrome); `footer`, `shipped` (the shared "shipped X ago" pill, recent list and `/updates` log, from the network changelog) and `icons` (= `ov-icons.js`) work on both sides, and `release-update` gives Node its pure `plan()` |
+| Node modules (`require('openvibe-shared/<name>')`) | `index` (`.`), `analytics` (+ `analytics/{privacy,tracker,retention,schema,event,prune-cli}`), `app-icon`, `auth-client`, `brand`, `builtin-themes`, `frame` (the OpenVibe Frame on the server), `legal`, `middleware`, `notifications`, `seo`, `theme-sync`, `url-resolver`, `files`, `egress` (SSRF-safe addresses and connect-time DNS for outbound fetches of user-chosen hosts), `trace` (the request's W3C trace on outbound calls inside the network), `release`, `release-compat` (tests), `metrics`, `ready`, `config` (the configuration model: revisioned, validated, classified settings with last-known-good and `/api/admin/config`), `test-runner` (the `npm test` runner of every service's `test/run.js`: each `*.test.js` in its own process; a line `<label>: skipped (<why>)` makes a file skipped, listed with ○ and never counted as passed, and `--strict` fails on skips), `perf-budget` (size budgets for a page's first load, measured from the running server: HTML, same-origin scripts and stylesheets, raw and brotli; for `npm test`), `browser-harness` (real-Chrome checks of a running site: status, console errors, overflow, duplicate scripts, no-JS text, canonical, JSON-LD against visible text, axe-core, repeated-navigation growth and idle work; Node 22, Chrome); `footer`, `shipped` (the shared "shipped X ago" pill, recent list and `/updates` log, from the network changelog) and `icons` (= `ov-icons.js`) work on both sides, and `release-update` gives Node its pure `plan()` |
| Schemas | `docs/schemas/analytics-event.v1.json` (`analytics/event.v1`, exported as `openvibe-shared/analytics/event.v1.json`) |
| Schemas | `docs/schemas/analytics-event.v1.json` (`analytics/event.v1`, exported as `openvibe-shared/analytics/event.v1.json`) |
| Generators | `scripts/build-nav-icons.py` (Font Awesome glyphs → `nav-icons.js`, `ov-icons.js`), `scripts/build-navbar-icons.js` (navbar.js's built-in glyphs), `scripts/build-theme-loader.js`, `scripts/build-app-icons.js` |
| Generators | `scripts/build-nav-icons.py` (Font Awesome glyphs → `nav-icons.js`, `ov-icons.js`), `scripts/build-navbar-icons.js` (navbar.js's built-in glyphs), `scripts/build-theme-loader.js`, `scripts/build-app-icons.js` |
@@ -116,49 +116,6 @@ class OpenVibeAuthClient {
@@ -116,49 +116,6 @@ class OpenVibeAuthClient {
return null;
return null;
}
}
}
}
-
- /**
- * Verify a token via the internal API (server-to-server).
- * Useful as a fallback or for getting fresh user data.
- * @param {string} token
- * @param {string} internalKey - X-Internal-Key header value
- * @returns {Promise<Object|null>}
- */
- async verifyTokenInternal(token, internalKey) {
- try {
- const res = await fetch(`${this.internalBase}/internal/verify-token`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'X-Internal-Key': internalKey,
- },
- body: JSON.stringify({ token }),
- });
- if (!res.ok) return null;
- return res.json();
- } catch {
- return null;
- }
- }
-
- /**
- * Get fresh user profile data via internal API.
- * @param {number} userId
- * @param {string} internalKey
- * @returns {Promise<Object|null>}
- */
- async getUserProfile(userId, internalKey) {
- try {
- const res = await fetch(`${this.internalBase}/internal/user/${userId}/sync`, {
- method: 'POST',
- headers: { 'X-Internal-Key': internalKey },
- });
- if (!res.ok) return null;
- return res.json();
- } catch {
- return null;
- }
- }
}
}
module.exports = { OpenVibeAuthClient };
module.exports = { OpenVibeAuthClient };
deleted file mode 100644
deleted file mode 100644
@@ -1,4 +0,0 @@
@@ -1,4 +0,0 @@
-'use strict';
-// Deprecated alias: openvibe-shared/chrome-ssr is now openvibe-shared/frame (the OpenVibe Frame). Kept so
-// sites on older code keep working; it goes away in 2.0.0.
-module.exports = require('./frame');
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
'use strict';
'use strict';
// openvibe-shared/frame — the OpenVibe Frame (the navbar, footer and "shipped" views every OpenVibe site sits
// openvibe-shared/frame — the OpenVibe Frame (the navbar, footer and "shipped" views every OpenVibe site sits
-// in): the parts that can be baked into HTML on the server. (Formerly openvibe-shared/chrome-ssr, still an alias.)
+// in): the parts that can be baked into HTML on the server. (Formerly openvibe-shared/chrome-ssr; the alias was removed in 2.0.0.)
// footer(cfg) the full shared footer (HTML + CSS); the browser's footer.js renders into the same element
// footer(cfg) the full shared footer (HTML + CSS); the browser's footer.js renders into the same element
// noscriptNav(site) a plain navigation bar inside <noscript>: the JavaScript navbar cannot exist without
// noscriptNav(site) a plain navigation bar inside <noscript>: the JavaScript navbar cannot exist without
// scripts, so visitors who block them (and text browsers) still get the brand and the network
// scripts, so visitors who block them (and text browsers) still get the brand and the network
@@ -3,7 +3,7 @@
@@ -3,7 +3,7 @@
const { BRAND, BRAND_DEFAULTS, resolveBrandUrls, buildBrandFromRegistry } = require('./brand');
const { BRAND, BRAND_DEFAULTS, resolveBrandUrls, buildBrandFromRegistry } = require('./brand');
const { OpenVibeAuthClient } = require('./auth-client');
const { OpenVibeAuthClient } = require('./auth-client');
const { CSS_VARIABLES, DEFAULT_VARS, BUILTIN_THEMES, applyTheme, resolveBuiltinTheme, sanitizeCssValue, loadFromStorage, saveToStorage, syncThemeToServer } = require('./theme-sync');
const { CSS_VARIABLES, DEFAULT_VARS, BUILTIN_THEMES, applyTheme, resolveBuiltinTheme, sanitizeCssValue, loadFromStorage, saveToStorage, syncThemeToServer } = require('./theme-sync');
-const { extractToken, requireOpenVibeAuth, optionalOpenVibeAuth, internalApiAuth } = require('./middleware');
+const { extractToken, requireOpenVibeAuth, optionalOpenVibeAuth } = require('./middleware');
const { PRIORITY, CATEGORY, TYPES, SOUNDS, EMAIL_ELIGIBLE_CATEGORIES, createNotification, DEFAULT_NOTIFICATION_PREFS } = require('./notifications');
const { PRIORITY, CATEGORY, TYPES, SOUNDS, EMAIL_ELIGIBLE_CATEGORIES, createNotification, DEFAULT_NOTIFICATION_PREFS } = require('./notifications');
const { AnalyticsTracker, classifyRequest, parseUserAgent, ANALYTICS_SCHEMA, BOT_USER_AGENTS, SUSPICIOUS_PATTERNS } = require('./analytics');
const { AnalyticsTracker, classifyRequest, parseUserAgent, ANALYTICS_SCHEMA, BOT_USER_AGENTS, SUSPICIOUS_PATTERNS } = require('./analytics');
const { URL_DEFINITIONS, normalizeValue, validateValue, resolveRegistryValues, formatRegistryEntry } = require('./url-resolver');
const { URL_DEFINITIONS, normalizeValue, validateValue, resolveRegistryValues, formatRegistryEntry } = require('./url-resolver');
@@ -18,7 +18,6 @@ module.exports = {
@@ -18,7 +18,6 @@ module.exports = {
extractToken,
extractToken,
requireOpenVibeAuth,
requireOpenVibeAuth,
optionalOpenVibeAuth,
optionalOpenVibeAuth,
- internalApiAuth,
// Themes
// Themes
CSS_VARIABLES,
CSS_VARIABLES,
DEFAULT_VARS,
DEFAULT_VARS,
@@ -69,26 +69,8 @@ function optionalOpenVibeAuth(authClient) {
@@ -69,26 +69,8 @@ function optionalOpenVibeAuth(authClient) {
};
};
}
}
-/**
- * Internal API authentication middleware.
- * Verifies X-Internal-Key header for server-to-server calls.
- *
- * @param {string} internalKey - Expected key value
- * @returns {Function} Express middleware
- */
-function internalApiAuth(internalKey) {
- return (req, res, next) => {
- const provided = req.headers['x-internal-key'];
- if (!provided || provided !== internalKey) {
- return res.status(403).json({ error: 'Forbidden' });
- }
- next();
- };
-}
-
module.exports = {
module.exports = {
extractToken,
extractToken,
requireOpenVibeAuth,
requireOpenVibeAuth,
optionalOpenVibeAuth,
optionalOpenVibeAuth,
- internalApiAuth,
};
};
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "1.30.1",
+ "version": "2.0.0",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"main": "index.js",
"exports": {
"exports": {
@@ -20,7 +20,6 @@
@@ -20,7 +20,6 @@
"./brand": "./brand.js",
"./brand": "./brand.js",
"./browser-harness": "./browser-harness.js",
"./browser-harness": "./browser-harness.js",
"./builtin-themes": "./builtin-themes.js",
"./builtin-themes": "./builtin-themes.js",
- "./chrome-ssr": "./chrome-ssr.js",
"./config": "./config.js",
"./config": "./config.js",
"./config-pg": "./config-pg.js",
"./config-pg": "./config-pg.js",
"./egress": "./egress.js",
"./egress": "./egress.js",
@@ -3,7 +3,7 @@
@@ -3,7 +3,7 @@
// block for a home page and the body of a site's /updates page (shipped.js fills both).
// block for a home page and the body of a site's /updates page (shipped.js fills both).
const assert = require('assert');
const assert = require('assert');
const frame = require('../frame');
const frame = require('../frame');
-assert.strictEqual(require('../chrome-ssr'), frame, 'the old name is an alias');
+assert.throws(() => require('../chrome-ssr'), /Cannot find module/, 'the chrome-ssr alias is gone (2.0.0)');
const home = frame.shipped({ service: 'wiki', title: 'Recently shipped on OpenVibe.Wiki <x>' });
const home = frame.shipped({ service: 'wiki', title: 'Recently shipped on OpenVibe.Wiki <x>' });
assert.ok(home.includes('data-ov-shipped="latest" data-service="wiki" href="/updates"'));
assert.ok(home.includes('data-ov-shipped="latest" data-service="wiki" href="/updates"'));
@@ -18,11 +18,11 @@ for (const [sub, target] of Object.entries(pkg.exports)) {
@@ -18,11 +18,11 @@ for (const [sub, target] of Object.entries(pkg.exports)) {
assert.strictEqual(require.resolve(sub === '.' ? pkg.name : `${pkg.name}/${sub.slice(2)}`), path.join(ROOT, target), `${sub} resolves`);
assert.strictEqual(require.resolve(sub === '.' ? pkg.name : `${pkg.name}/${sub.slice(2)}`), path.join(ROOT, target), `${sub} resolves`);
}
}
// Subpaths in use across Network, Live, Media, Tools, Community and Sites (2026-09-22).
// Subpaths in use across Network, Live, Media, Tools, Community and Sites (2026-09-22).
-for (const sub of ['analytics', 'app-icon', 'auth-client', 'brand', 'chrome-ssr', 'footer', 'icons', 'legal', 'notifications', 'seo', 'theme-sync', 'url-resolver', 'package.json', 'navbar', 'files']) {
+for (const sub of ['analytics', 'app-icon', 'auth-client', 'brand', 'footer', 'icons', 'legal', 'notifications', 'seo', 'theme-sync', 'url-resolver', 'package.json', 'navbar', 'files']) {
assert.doesNotThrow(() => require.resolve(`openvibe-shared/${sub}`), `openvibe-shared/${sub}`);
assert.doesNotThrow(() => require.resolve(`openvibe-shared/${sub}`), `openvibe-shared/${sub}`);
}
}
// Server modules load in Node; the navbar module loads too (UMD, no DOM touched at require time).
// Server modules load in Node; the navbar module loads too (UMD, no DOM touched at require time).
-for (const sub of ['analytics', 'app-icon', 'brand', 'chrome-ssr', 'footer', 'icons', 'legal', 'notifications', 'seo', 'url-resolver', 'files', 'nav-icons', 'metrics', 'ready', 'egress', 'trace', 'config', 'browser-harness']) require(`openvibe-shared/${sub}`);
+for (const sub of ['analytics', 'app-icon', 'brand', 'footer', 'icons', 'legal', 'notifications', 'seo', 'url-resolver', 'files', 'nav-icons', 'metrics', 'ready', 'egress', 'trace', 'config', 'browser-harness']) require(`openvibe-shared/${sub}`);
// analytics is dependency-free: its parts require only Node built-ins and each other.
// analytics is dependency-free: its parts require only Node built-ins and each other.
for (const f of fs.readdirSync(path.join(ROOT, 'analytics'))) {
for (const f of fs.readdirSync(path.join(ROOT, 'analytics'))) {
const src = fs.readFileSync(path.join(ROOT, 'analytics', f), 'utf8').replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, '');
const src = fs.readFileSync(path.join(ROOT, 'analytics', f), 'utf8').replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, '');
@@ -35,3 +35,12 @@ assert.strictEqual(typeof require('openvibe-shared/navbar').init, 'function');
@@ -35,3 +35,12 @@ assert.strictEqual(typeof require('openvibe-shared/navbar').init, 'function');
assert.ok(/^\d+\.\d+\.\d+$/.test(pkg.version), 'semver version');
assert.ok(/^\d+\.\d+\.\d+$/.test(pkg.version), 'semver version');
assert.ok(fs.readFileSync(path.join(ROOT, 'CHANGELOG.md'), 'utf8').includes(`## ${pkg.version}`), 'CHANGELOG has an entry for this version');
assert.ok(fs.readFileSync(path.join(ROOT, 'CHANGELOG.md'), 'utf8').includes(`## ${pkg.version}`), 'CHANGELOG has an entry for this version');
console.log(`package: ${Object.keys(pkg.exports).length} exports resolve`);
console.log(`package: ${Object.keys(pkg.exports).length} exports resolve`);
+
+// 2.0.0: the X-Internal-Key helpers are gone (plan T2), and nothing exported names the key.
+{
+ const shared = require('..');
+ assert.strictEqual(shared.internalApiAuth, undefined, 'internalApiAuth is removed');
+ const { OpenVibeAuthClient } = require('../auth-client');
+ assert.strictEqual(OpenVibeAuthClient.prototype.verifyTokenInternal, undefined, 'verifyTokenInternal is removed');
+ assert.strictEqual(OpenVibeAuthClient.prototype.getUserProfile, undefined, 'getUserProfile is removed');
+}