openvibers/openvibe.host Commits
Events moves to openvibe.events: the dashboard's connect-src and shared 2.13.0 (plan T7) (#30)
Changes
@@@ -52,7 +52,7 @@ Stage A adds a few safety rules of its own:- OpenVibe.Contracts (`openvibe-contracts` v0.107.0; `host.*` capabilities and the `host` manifest were released in v0.24.0, v0.32.0 added the takedown routes to `host.site.manage`, v0.83.0 added `host.site.config`, and v0.107.0 adds the planned `host.resource.read` and the git-source routes to `host.site.manage`/`host.deploy.create`): service manifests (vhost rendering, snapshots, the first-party domain list), ids, problem+json, service-token verification, capability checks, the `common.resource-summary@1`/`common.resource-list-result@1` schemas and the `contracts.resources` OVRN helpers (ADR-048).- OpenVibe.Network (Stage B): SSO for the dashboard, the JWKS that verifies user and service tokens, client-credentials tokens for the outbox relay.- OpenVibe.Events (Stage B): `host.*` events through the `openvibe-sdk` v0.26.0 transactional outbox (openvibe-sdk/limits for the per-actor limits).--- `openvibe-shared` v2.12.0 (Stage B): shared chrome (Host's own pages are composed with `openvibe-shared/shell`), legal pages, `/release.json`, `/metrics`, `/api/ready`.++- `openvibe-shared` v2.13.0 (Stage B): shared chrome (Host's own pages are composed with `openvibe-shared/shell`), legal pages, `/release.json`, `/metrics`, `/api/ready`.- OpenVibe.Media (Stage B, opt-in): with `HOST_OBJECT_STORE=media`, deploy objects are written through to Media's Object API v2 (`openvibe-sdk/media`) and local disk becomes the read cache; unset keeps them on local disk (see [Storage](#storage)).## Capabilities@@@ -441,7 +441,7 @@ These tenant events have subject `deploy` and visibility `internal`; `host.deplo### Dashboard--Server-rendered pages with the shared chrome (`openvibe-shared` v2.12.0 `shell.page`: navbar and theme loader from the Network, `<noscript>` navigation, SSR footer, app icon, legal pages). Every action is a plain form, so it works without JavaScript: projects, quotas and usage, members, sites, folder or archive upload, deploys with activate/rollback/delete, activation history, upload logs and file lists, domains with their DNS records and a "check DNS now" button. Pages are `private, no-store`, `noindex`, `frame-ancestors 'none'`.++Server-rendered pages with the shared chrome (`openvibe-shared` v2.13.0 `shell.page`: navbar and theme loader from the Network, `<noscript>` navigation, SSR footer, app icon, legal pages). Every action is a plain form, so it works without JavaScript: projects, quotas and usage, members, sites, folder or archive upload, deploys with activate/rollback/delete, activation history, upload logs and file lists, domains with their DNS records and a "check DNS now" button. Pages are `private, no-store`, `noindex`, `frame-ancestors 'none'`.### Observability@@@ -566,5 +566,5 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by [<!-- versions:start -->- openvibe-contracts: v0.107.0- openvibe-sdk: v0.26.0--- openvibe-shared: v2.12.0++- openvibe-shared: v2.13.0<!-- versions:end -->@@@ -16,11 +16,11 @@"tenantDomain": "*.openvibe.host","contracts": "openvibe-contracts v0.107.0","sdk": "openvibe-sdk v0.26.0",-- "shared": "openvibe-shared v2.12.0",++ "shared": "openvibe-shared v2.13.0","packages": ["openvibe-contracts v0.107.0","openvibe-sdk v0.26.0",-- "openvibe-shared v2.12.0"++ "openvibe-shared v2.13.0"],"capabilities": ["host.site.manage",@@@ -130,7 +130,7 @@ All commands run on the production host. None of them prints a secret.## Before a site pins openvibe-shared 1.17.0The tab's EventSource is subject to the site's Content-Security-Policy, so `connect-src` must allow--`https://events.openvibe.network`. As of 2026-09-26, every site whose pages load release-watch under a CSP++`https://openvibe.events`. As of 2026-09-26, every site whose pages load release-watch under a CSPallows it: Live and Community first, then, with their 1.17.1 pins, Network, Wiki, Blog, Codes, Search, Reviews,VIP, Tips, Host (Stage B dashboard), News, Deals, Coupons, Trade and the Tools apps. Chat, Media, Games,OpenRe.Stream and Sites send no CSP with those pages. A new site needs it too. Without it, the@@@ -142,7 +142,7 @@ moves the pin, or set `data-events="off"` on the `ov-release` meta tag.1. Subscribe the way a signed-out browser does, from any machine:```-- curl -N 'https://events.openvibe.network/realtime/stream?topics=host.release.published'++ curl -N 'https://openvibe.events/realtime/stream?topics=host.release.published'```The stream starts with `retry: 3000` and `: connected anonymous`, then sends a `: hb` comment every25 s.@@@ -19,7 +19,7 @@"iovalkey": "^0.4.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.0","pg": "^8.23.0"},"bin": {@@@ -1546,9 +1546,9 @@}},"node_modules/openvibe-shared": {-- "version": "2.12.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",-- "integrity": "sha512-GQpNFs2h61OKKNLexQwCfSJTLzNQ7fSbwqvrerB4oNdoxUgDvmdD43SELWycrb9DX8lkje4cR3ARznYIINnR8Q==",++ "version": "2.13.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.0",++ "integrity": "sha512-0Lvo+bBWVGWREkp92tY4cGI32ZO124WTOjthDNTB96U161odl+npnYEWy3dV2IcgZC4HAX5DSzx4ThgNS2V/sA==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0"@@@ -35,7 +35,7 @@"iovalkey": "^0.4.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.0","pg": "^8.23.0"},"engines": {@@@ -58,8 +58,8 @@ const DASHBOARD_CSP = {'style-src': ["'self'", "'unsafe-inline'", 'https://openvibe.network', 'https://fonts.googleapis.com', 'https://cdnjs.cloudflare.com'],'font-src': ["'self'", 'data:', 'https://fonts.gstatic.com', 'https://cdnjs.cloudflare.com'],'img-src': ["'self'", 'data:', 'https:'],-- // events.openvibe.network: release notifications (release-watch's EventSource, openvibe-shared 1.17).-- 'connect-src': ["'self'", 'https://openvibe.network', 'https://events.openvibe.network'],++ // openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 1.17).++ 'connect-src': ["'self'", 'https://openvibe.network', 'https://openvibe.events'],'frame-src': ["'self'", 'https://openvibe.network'],'frame-ancestors': ["'none'"],'object-src': ["'none'"],@@@ -84,7 +84,7 @@ const DAY = 24 * 3600 * 1000;});await check('OpenVibe domains, the sites domain and non-hostnames can never be claimed', async () => {-- for (const h of ['openvibe.live', 'evil.openvibe.network', 'x.openvibe.host', 'openvibe.host', 'openvibe.xyz', 'a.b.openvibe.media', 'events.openvibe.network', 'openre.stream', 'play.openvibe.games',++ for (const h of ['openvibe.live', 'evil.openvibe.network', 'x.openvibe.host', 'openvibe.host', 'openvibe.xyz', 'a.b.openvibe.media', 'openvibe.events', 'openre.stream', 'play.openvibe.games','localhost', '127.0.0.1', 'example', '-bad.example.org', 'a_b.example.org', 'ex ample.org', 'xn--.example.org']) {const r = await t.api('POST', `/api/v1/sites/${sa.id}/domains`, { as: alice, json: { hostname: h } });assert.strictEqual(r.status, 422, `${h} → ${r.status} ${r.text}`);@@@ -61,7 +61,7 @@ const ORIGIN = 'https://openvibe.host';assert.match(r.text, /href="\/shared\/showcase\.css\?v=[0-9a-f]{12}"/);assert.match(r.headers['content-security-policy'], /frame-ancestors 'none'/);// Release notifications: release-watch's EventSource on the Events realtime stream (openvibe-shared 1.17).-- assert.match(r.headers['content-security-policy'], /connect-src 'self' https:\/\/openvibe\.network https:\/\/events\.openvibe\.network;/);++ assert.match(r.headers['content-security-policy'], /connect-src 'self' https:\/\/openvibe\.network https:\/\/openvibe\.events;/);assert.strictEqual(r.headers['x-frame-options'], 'DENY');assert.strictEqual(r.headers['cache-control'], 'private, no-store');// The public front page is indexable, with a canonical URL; nothing behind sign-in is.
@@ -52,7 +52,7 @@ Stage A adds a few safety rules of its own:
@@ -52,7 +52,7 @@ Stage A adds a few safety rules of its own:
- OpenVibe.Contracts (`openvibe-contracts` v0.107.0; `host.*` capabilities and the `host` manifest were released in v0.24.0, v0.32.0 added the takedown routes to `host.site.manage`, v0.83.0 added `host.site.config`, and v0.107.0 adds the planned `host.resource.read` and the git-source routes to `host.site.manage`/`host.deploy.create`): service manifests (vhost rendering, snapshots, the first-party domain list), ids, problem+json, service-token verification, capability checks, the `common.resource-summary@1`/`common.resource-list-result@1` schemas and the `contracts.resources` OVRN helpers (ADR-048).
- OpenVibe.Contracts (`openvibe-contracts` v0.107.0; `host.*` capabilities and the `host` manifest were released in v0.24.0, v0.32.0 added the takedown routes to `host.site.manage`, v0.83.0 added `host.site.config`, and v0.107.0 adds the planned `host.resource.read` and the git-source routes to `host.site.manage`/`host.deploy.create`): service manifests (vhost rendering, snapshots, the first-party domain list), ids, problem+json, service-token verification, capability checks, the `common.resource-summary@1`/`common.resource-list-result@1` schemas and the `contracts.resources` OVRN helpers (ADR-048).
- OpenVibe.Network (Stage B): SSO for the dashboard, the JWKS that verifies user and service tokens, client-credentials tokens for the outbox relay.
- OpenVibe.Network (Stage B): SSO for the dashboard, the JWKS that verifies user and service tokens, client-credentials tokens for the outbox relay.
- OpenVibe.Events (Stage B): `host.*` events through the `openvibe-sdk` v0.26.0 transactional outbox (openvibe-sdk/limits for the per-actor limits).
- OpenVibe.Events (Stage B): `host.*` events through the `openvibe-sdk` v0.26.0 transactional outbox (openvibe-sdk/limits for the per-actor limits).
-- `openvibe-shared` v2.12.0 (Stage B): shared chrome (Host's own pages are composed with `openvibe-shared/shell`), legal pages, `/release.json`, `/metrics`, `/api/ready`.
+- `openvibe-shared` v2.13.0 (Stage B): shared chrome (Host's own pages are composed with `openvibe-shared/shell`), legal pages, `/release.json`, `/metrics`, `/api/ready`.
- OpenVibe.Media (Stage B, opt-in): with `HOST_OBJECT_STORE=media`, deploy objects are written through to Media's Object API v2 (`openvibe-sdk/media`) and local disk becomes the read cache; unset keeps them on local disk (see [Storage](#storage)).
- OpenVibe.Media (Stage B, opt-in): with `HOST_OBJECT_STORE=media`, deploy objects are written through to Media's Object API v2 (`openvibe-sdk/media`) and local disk becomes the read cache; unset keeps them on local disk (see [Storage](#storage)).
## Capabilities
## Capabilities
@@ -441,7 +441,7 @@ These tenant events have subject `deploy` and visibility `internal`; `host.deplo
@@ -441,7 +441,7 @@ These tenant events have subject `deploy` and visibility `internal`; `host.deplo
### Dashboard
### Dashboard
-Server-rendered pages with the shared chrome (`openvibe-shared` v2.12.0 `shell.page`: navbar and theme loader from the Network, `<noscript>` navigation, SSR footer, app icon, legal pages). Every action is a plain form, so it works without JavaScript: projects, quotas and usage, members, sites, folder or archive upload, deploys with activate/rollback/delete, activation history, upload logs and file lists, domains with their DNS records and a "check DNS now" button. Pages are `private, no-store`, `noindex`, `frame-ancestors 'none'`.
+Server-rendered pages with the shared chrome (`openvibe-shared` v2.13.0 `shell.page`: navbar and theme loader from the Network, `<noscript>` navigation, SSR footer, app icon, legal pages). Every action is a plain form, so it works without JavaScript: projects, quotas and usage, members, sites, folder or archive upload, deploys with activate/rollback/delete, activation history, upload logs and file lists, domains with their DNS records and a "check DNS now" button. Pages are `private, no-store`, `noindex`, `frame-ancestors 'none'`.
### Observability
### Observability
@@ -566,5 +566,5 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by [
@@ -566,5 +566,5 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by [
<!-- versions:start -->
<!-- versions:start -->
- openvibe-contracts: v0.107.0
- openvibe-contracts: v0.107.0
- openvibe-sdk: v0.26.0
- openvibe-sdk: v0.26.0
-- openvibe-shared: v2.12.0
+- openvibe-shared: v2.13.0
<!-- versions:end -->
<!-- versions:end -->
@@ -16,11 +16,11 @@
@@ -16,11 +16,11 @@
"tenantDomain": "*.openvibe.host",
"tenantDomain": "*.openvibe.host",
"contracts": "openvibe-contracts v0.107.0",
"contracts": "openvibe-contracts v0.107.0",
"sdk": "openvibe-sdk v0.26.0",
"sdk": "openvibe-sdk v0.26.0",
- "shared": "openvibe-shared v2.12.0",
+ "shared": "openvibe-shared v2.13.0",
"packages": [
"packages": [
"openvibe-contracts v0.107.0",
"openvibe-contracts v0.107.0",
"openvibe-sdk v0.26.0",
"openvibe-sdk v0.26.0",
- "openvibe-shared v2.12.0"
+ "openvibe-shared v2.13.0"
],
],
"capabilities": [
"capabilities": [
"host.site.manage",
"host.site.manage",
@@ -130,7 +130,7 @@ All commands run on the production host. None of them prints a secret.
@@ -130,7 +130,7 @@ All commands run on the production host. None of them prints a secret.
## Before a site pins openvibe-shared 1.17.0
## Before a site pins openvibe-shared 1.17.0
The tab's EventSource is subject to the site's Content-Security-Policy, so `connect-src` must allow
The tab's EventSource is subject to the site's Content-Security-Policy, so `connect-src` must allow
-`https://events.openvibe.network`. As of 2026-09-26, every site whose pages load release-watch under a CSP
+`https://openvibe.events`. As of 2026-09-26, every site whose pages load release-watch under a CSP
allows it: Live and Community first, then, with their 1.17.1 pins, Network, Wiki, Blog, Codes, Search, Reviews,
allows it: Live and Community first, then, with their 1.17.1 pins, Network, Wiki, Blog, Codes, Search, Reviews,
VIP, Tips, Host (Stage B dashboard), News, Deals, Coupons, Trade and the Tools apps. Chat, Media, Games,
VIP, Tips, Host (Stage B dashboard), News, Deals, Coupons, Trade and the Tools apps. Chat, Media, Games,
OpenRe.Stream and Sites send no CSP with those pages. A new site needs it too. Without it, the
OpenRe.Stream and Sites send no CSP with those pages. A new site needs it too. Without it, the
@@ -142,7 +142,7 @@ moves the pin, or set `data-events="off"` on the `ov-release` meta tag.
@@ -142,7 +142,7 @@ moves the pin, or set `data-events="off"` on the `ov-release` meta tag.
1. Subscribe the way a signed-out browser does, from any machine:
1. Subscribe the way a signed-out browser does, from any machine:
```
```
- curl -N 'https://events.openvibe.network/realtime/stream?topics=host.release.published'
+ curl -N 'https://openvibe.events/realtime/stream?topics=host.release.published'
```
```
The stream starts with `retry: 3000` and `: connected anonymous`, then sends a `: hb` comment every
The stream starts with `retry: 3000` and `: connected anonymous`, then sends a `: hb` comment every
25 s.
25 s.
@@ -19,7 +19,7 @@
@@ -19,7 +19,7 @@
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
},
},
"bin": {
"bin": {
@@ -1546,9 +1546,9 @@
@@ -1546,9 +1546,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "2.12.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",
- "integrity": "sha512-GQpNFs2h61OKKNLexQwCfSJTLzNQ7fSbwqvrerB4oNdoxUgDvmdD43SELWycrb9DX8lkje4cR3ARznYIINnR8Q==",
+ "version": "2.13.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.0",
+ "integrity": "sha512-0Lvo+bBWVGWREkp92tY4cGI32ZO124WTOjthDNTB96U161odl+npnYEWy3dV2IcgZC4HAX5DSzx4ThgNS2V/sA==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0"
@@ -35,7 +35,7 @@
@@ -35,7 +35,7 @@
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.13.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
},
},
"engines": {
"engines": {
@@ -58,8 +58,8 @@ const DASHBOARD_CSP = {
@@ -58,8 +58,8 @@ const DASHBOARD_CSP = {
'style-src': ["'self'", "'unsafe-inline'", 'https://openvibe.network', 'https://fonts.googleapis.com', 'https://cdnjs.cloudflare.com'],
'style-src': ["'self'", "'unsafe-inline'", 'https://openvibe.network', 'https://fonts.googleapis.com', 'https://cdnjs.cloudflare.com'],
'font-src': ["'self'", 'data:', 'https://fonts.gstatic.com', 'https://cdnjs.cloudflare.com'],
'font-src': ["'self'", 'data:', 'https://fonts.gstatic.com', 'https://cdnjs.cloudflare.com'],
'img-src': ["'self'", 'data:', 'https:'],
'img-src': ["'self'", 'data:', 'https:'],
- // events.openvibe.network: release notifications (release-watch's EventSource, openvibe-shared 1.17).
- 'connect-src': ["'self'", 'https://openvibe.network', 'https://events.openvibe.network'],
+ // openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 1.17).
+ 'connect-src': ["'self'", 'https://openvibe.network', 'https://openvibe.events'],
'frame-src': ["'self'", 'https://openvibe.network'],
'frame-src': ["'self'", 'https://openvibe.network'],
'frame-ancestors': ["'none'"],
'frame-ancestors': ["'none'"],
'object-src': ["'none'"],
'object-src': ["'none'"],
@@ -84,7 +84,7 @@ const DAY = 24 * 3600 * 1000;
@@ -84,7 +84,7 @@ const DAY = 24 * 3600 * 1000;
});
});
await check('OpenVibe domains, the sites domain and non-hostnames can never be claimed', async () => {
await check('OpenVibe domains, the sites domain and non-hostnames can never be claimed', async () => {
- for (const h of ['openvibe.live', 'evil.openvibe.network', 'x.openvibe.host', 'openvibe.host', 'openvibe.xyz', 'a.b.openvibe.media', 'events.openvibe.network', 'openre.stream', 'play.openvibe.games',
+ for (const h of ['openvibe.live', 'evil.openvibe.network', 'x.openvibe.host', 'openvibe.host', 'openvibe.xyz', 'a.b.openvibe.media', 'openvibe.events', 'openre.stream', 'play.openvibe.games',
'localhost', '127.0.0.1', 'example', '-bad.example.org', 'a_b.example.org', 'ex ample.org', 'xn--.example.org']) {
'localhost', '127.0.0.1', 'example', '-bad.example.org', 'a_b.example.org', 'ex ample.org', 'xn--.example.org']) {
const r = await t.api('POST', `/api/v1/sites/${sa.id}/domains`, { as: alice, json: { hostname: h } });
const r = await t.api('POST', `/api/v1/sites/${sa.id}/domains`, { as: alice, json: { hostname: h } });
assert.strictEqual(r.status, 422, `${h} → ${r.status} ${r.text}`);
assert.strictEqual(r.status, 422, `${h} → ${r.status} ${r.text}`);
@@ -61,7 +61,7 @@ const ORIGIN = 'https://openvibe.host';
@@ -61,7 +61,7 @@ const ORIGIN = 'https://openvibe.host';
assert.match(r.text, /href="\/shared\/showcase\.css\?v=[0-9a-f]{12}"/);
assert.match(r.text, /href="\/shared\/showcase\.css\?v=[0-9a-f]{12}"/);
assert.match(r.headers['content-security-policy'], /frame-ancestors 'none'/);
assert.match(r.headers['content-security-policy'], /frame-ancestors 'none'/);
// Release notifications: release-watch's EventSource on the Events realtime stream (openvibe-shared 1.17).
// Release notifications: release-watch's EventSource on the Events realtime stream (openvibe-shared 1.17).
- assert.match(r.headers['content-security-policy'], /connect-src 'self' https:\/\/openvibe\.network https:\/\/events\.openvibe\.network;/);
+ assert.match(r.headers['content-security-policy'], /connect-src 'self' https:\/\/openvibe\.network https:\/\/openvibe\.events;/);
assert.strictEqual(r.headers['x-frame-options'], 'DENY');
assert.strictEqual(r.headers['x-frame-options'], 'DENY');
assert.strictEqual(r.headers['cache-control'], 'private, no-store');
assert.strictEqual(r.headers['cache-control'], 'private, no-store');
// The public front page is indexable, with a canonical URL; nothing behind sign-in is.
// The public front page is indexable, with a canonical URL; nothing behind sign-in is.