openvibers/openvibe.search Commits

The OpenVibe Frame from this site's own pinned copy: /shared/* is served by openvibe-shared/serve (1.12.0) and every page references it by content hash (/shared/<file>?v=<hash>), so this site's pin decides what its pages run and its navbar and footer keep working while openvibe.network is down

OP OpenVibers committed 24 Sept 2026 · ae9408617b · 6 files, +15 −9


Changes

ddiff --git a/deploy/nginx/search.openvibe.network.conf b/deploy/nginx/search.openvibe.network.conf
iindex 9589215..265efa6 100644
---- a/deploy/nginx/search.openvibe.network.conf
++++ b/deploy/nginx/search.openvibe.network.conf
@@@ -81,6 +81,8 @@ server {
location = /robots.txt { proxy_pass http://127.0.0.1:4710; }
# The OpenVibe Frame's same-origin init script, and what shipped on this site (the shared log).
location = /frame-init.js { limit_except GET { deny all; } proxy_pass http://127.0.0.1:4710; }
++ # This site's own pinned copy of the Frame's browser files (openvibe-shared/serve).
++ location ^~ /shared/ { limit_except GET { deny all; } proxy_pass http://127.0.0.1:4710; }
location = /updates {
limit_except GET { deny all; }
limit_req zone=ovsearch_query burst=40 nodelay;
ddiff --git a/package-lock.json b/package-lock.json
iindex c12ecd8..e8874b4 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -15,7 +15,7 @@
"dotenv": "^16.4.7",
"express": "^4.21.2",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.33.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.1"
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.12.0"
},
"engines": {
"node": ">=22.0.0"
@@@ -985,9 +985,9 @@
}
},
"node_modules/openvibe-shared": {
-- "version": "1.11.1",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.1",
-- "integrity": "sha512-hBaZlZRVZjkGfsPQE16rQIou2lUuusADea3Evx1tVjB84FTHGHS7ZALfcXaNOk7dR53HOVTJrQ0njmScdreUiw==",
++ "version": "1.12.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.12.0",
++ "integrity": "sha512-Qpy4YVoPMs1q/0/08/5ZODI0+7ev+Krk75nsRPsTjNCm7Eu91tt1LPnUNLt4kYfRj6duS+N9icm02gksnlMiyA==",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0"
ddiff --git a/package.json b/package.json
iindex f50c467..6f53113 100644
---- a/package.json
++++ b/package.json
@@@ -21,7 +21,7 @@
"dotenv": "^16.4.7",
"express": "^4.21.2",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.33.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.1"
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.12.0"
},
"engines": {
"node": ">=22.0.0"
ddiff --git a/server/app.js b/server/app.js
iindex 2ad6e7b..5a00cad 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -32,6 +32,8 @@ function createApp({ config, db, store, engine, auth, keys, outbox, relay, purge
});
// The webhook reads its raw body itself (the signature covers the exact bytes).
++ // This site's own pinned copy of the OpenVibe Frame's browser files (openvibe-shared/serve).
++ app.use('/shared', require('openvibe-shared/serve').handler());
app.use(webhookRouter({ config, db, store, relay, log, now }));
app.use('/api', express.json({ limit: config.maxBodyBytes, type: ['application/json', 'application/*+json'] }));
ddiff --git a/server/web/page.js b/server/web/page.js
iindex f4dbc34..94e7c3f 100644
---- a/server/web/page.js
++++ b/server/web/page.js
@@@ -11,6 +11,7 @@
* pages are noindex. Clients that do not ask for HTML get the plain-text route index at /.
*/
const express = require('express');
++const ovServe = require('openvibe-shared/serve');
const { AuthError, ANONYMOUS } = require('../auth');
const { QueryError, one } = require('../api/query');
@@@ -80,9 +81,9 @@ function layout({ title, q, owner, type, body, noindex }) {
${noindex ? '<meta name="robots" content="noindex, nofollow">\n' : ''}<meta name="description" content="Search what the OpenVibe network's services have published.">
<meta name="color-scheme" content="light dark">
${require('openvibe-shared/app-icon').headTags({ site: 'network', iconBase: `${NETWORK}/assets` }).split('\n').filter((l) => l.startsWith('<link')).join('\n')}
--<script src="${NETWORK}/shared/theme-loader.js" defer></script>
--<script src="${NETWORK}/shared/navbar.js" defer></script>
--<script src="${NETWORK}/shared/footer.js" defer></script>
++<script src="${ovServe.url('theme-loader.js')}" defer></script>
++<script src="${ovServe.url('navbar.js')}" defer></script>
++<script src="${ovServe.url('footer.js')}" defer></script>
<script src="/frame-init.js" defer></script>
<style>
:root { --bg: #fff; --fg: #1a1a1a; --muted: #5c5c66; --line: #dcdce3; --accent: #2456d6; --mark: #fff2a8; }
@@@ -155,7 +156,7 @@ function pageRouter({ searcher, auth }) {
res.setHeader('Content-Security-Policy', CSP);
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Cache-Control', 'public, max-age=60');
-- res.type('html').send(layout({ title: 'What shipped on OpenVibe.Search', q: '', owner: '', type: '', body: frame.updatesBody({ service: 'search', siteName: 'OpenVibe.Search' }) + frame.shippedScript() }));
++ res.type('html').send(layout({ title: 'What shipped on OpenVibe.Search', q: '', owner: '', type: '', body: frame.updatesBody({ service: 'search', siteName: 'OpenVibe.Search' }) + `<script src="${ovServe.url('shipped.js')}" defer></script>` }));
});
router.get('/robots.txt', (_req, res) => {
ddiff --git a/test/vhost.test.js b/test/vhost.test.js
iindex 34ef594..ef149a7 100644
---- a/test/vhost.test.js
++++ b/test/vhost.test.js
@@@ -29,6 +29,7 @@ t('/metrics is 404; owner API, webhook and document writes are loopback-only', (
assert.match(conf, /location = \/metrics \{ return 404; \}/);
assert.match(conf, /location = \/frame-init\.js \{ limit_except GET \{ deny all; \} proxy_pass http:\/\/127\.0\.0\.1:4710; \}/, 'the Frame init script');
assert.match(block('location = /updates'), /limit_except GET \{ deny all; \}/, 'the update log, GET only');
++ assert.match(conf, /location \^~ \/shared\/ \{ limit_except GET \{ deny all; \} proxy_pass http:\/\/127\.0\.0\.1:4710; \}/, 'the site\'s own Frame files');
assert.match(block('location ^~ /internal/'), loopbackOnly);
assert.match(block('location ^~ /api/v1/owners/'), loopbackOnly);
assert.match(block('location ^~ /api/v1/documents/'), /limit_except GET \{\s*allow 127\.0\.0\.1;\s*allow ::1;\s*deny all;/);