openvibers/openvibe.host Commits
openvibe-contracts v0.112.0 (was v0.107.0) (#32)
Changes
@@@ -564,7 +564,7 @@ review is [docs/threat-review.md](docs/threat-review.md). The launch has not beePart of the [OpenVibe network](https://openvibe.network). Built in the open by [OpenVibers](https://github.com/OpenVibers).<!-- versions:start -->--- openvibe-contracts: v0.107.0++- openvibe-contracts: v0.112.0- openvibe-sdk: v0.26.0- openvibe-shared: v2.13.0<!-- versions:end -->@@@ -14,7 +14,7 @@"port": 4910,"domain": "openvibe.host","tenantDomain": "*.openvibe.host",-- "contracts": "openvibe-contracts v0.107.0",++ "contracts": "openvibe-contracts v0.112.0","sdk": "openvibe-sdk v0.26.0","shared": "openvibe-shared v2.13.0","packages": [@@@ -24,7 +24,7 @@ function readTemplate(name) {return fs.readFileSync(path.join(TEMPLATE_DIR, name), 'utf8');}--/** openvibe.network for events.openvibe.network: the host's certificates are per registrable domain (wildcards). */++/** openvibe.network for api.openvibe.network: the host's certificates are per registrable domain (wildcards). */function defaultCertName(domain) {return domain.split('.').slice(-2).join('.');}@@@ -63,6 +63,10 @@ function render(inv, svc, { variant, manifestFile } = {}) {locations = paths.map((p) => fill(readTemplate('location-websocket.tmpl'), { ...base, path: safePath(p) })).join('');}const name = n.vhost || `${primary}.conf`;++ // One server block, one certificate: without an explicit certName it names only the domains under the++ // primary's registrable domain (a wildcard covers them); another registrable domain needs its own vhost.++ const certName = n.certName || defaultCertName(primary);++ const serverNames = n.certName ? domains : domains.filter((d) => defaultCertName(d) === certName);const text = fill(readTemplate('vhost.conf.tmpl'), {...base,primary,@@@ -72,8 +76,8 @@ function render(inv, svc, { variant, manifestFile } = {}) {variant: v,vhost: name,sitesAvailable: inv.nginx.sitesAvailable,-- serverNames: domains.join(' '),-- certName: n.certName || defaultCertName(primary),++ serverNames: serverNames.join(' '),++ certName,maxBody: n.maxBody || '2m',locations,httpContext,@@@ -17,7 +17,7 @@"express": "^4.21.2","express-rate-limit": "^7.5.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.112.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.13.0","pg": "^8.23.0"@@@ -1501,9 +1501,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.107.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0",-- "integrity": "sha512-bttjTDLzCfHFtq5h0EkBaPspVV6U934jj5Hz7RViIh2UTiC2Xzy3d6AnHLsEomVyTwaiwg9veNiO+eZTZ0lxsg==",++ "version": "0.112.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.112.0",++ "integrity": "sha512-ujIdCjv+oHfwg/+Hw0tyt2erVnornjDiKVPN8snHvybfysR/DBZQ2G32bQj8oAaK90s12ADEpdrXT1eust3eAw==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -33,7 +33,7 @@"express": "^4.21.2","express-rate-limit": "^7.5.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.112.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.13.0","pg": "^8.23.0"@@@ -55,8 +55,9 @@ runTests([const host = scenario();const ev = await host.cli('nginx', 'render', 'events');assert.strictEqual(ev.code, 0, ev.out);-- assert.match(ev.out, /server_name events\.openvibe\.network;/);-- assert.match(ev.out, /ssl_certificate +\/etc\/letsencrypt\/live\/openvibe\.network\/fullchain\.pem;/, 'wildcard certificate of the registrable domain');++ assert.match(ev.out, /server_name openvibe\.events;/, 'only the domains the certificate covers');++ assert.ok(!/events\.openvibe\.network/.test(ev.out.split('\n').filter((l) => /server_name/.test(l)).join('\n')), 'the other registrable domain gets its own vhost');++ assert.match(ev.out, /ssl_certificate +\/etc\/letsencrypt\/live\/openvibe\.events\/fullchain\.pem;/, 'the certificate of the registrable domain');assert.match(ev.out, /location = \/realtime\/stream \{[\s\S]*proxy_buffering off;[\s\S]*proxy_read_timeout 1h;/);assert.match(ev.out, /proxy_pass http:\/\/127\.0\.0\.1:4300;/);const live = await host.cli('nginx', 'render', 'live');@@@ -67,7 +68,7 @@ runTests([const plain = await host.cli('nginx', 'render', 'media', '--variant', 'http');assert.match(plain.out, /server_name openvibe\.media;/);assert.ok(!/proxy_buffering off/.test(plain.out));-- assert.strictEqual(host.read('/etc/nginx/sites-available/events.openvibe.network.conf'), null, 'render alone writes nothing');++ assert.strictEqual(host.read('/etc/nginx/sites-available/openvibe.events.conf'), null, 'render alone writes nothing');assert.ok(!host.calls.some((c) => c.cmd === 'nginx' || (c.cmd === 'systemctl' && c.args[0] === 'reload')));}),@@@ -75,18 +76,18 @@ runTests([const host = scenario();const ok = await host.cli('nginx', 'render', 'events', '--install');assert.strictEqual(ok.code, 0, ok.out);-- const installed = host.read('/etc/nginx/sites-available/events.openvibe.network.conf');-- assert.match(installed, /events\.openvibe\.network/);-- assert.ok(host.files.get('/etc/nginx/sites-enabled/events.openvibe.network.conf'));++ const installed = host.read('/etc/nginx/sites-available/openvibe.events.conf');++ assert.match(installed, /server_name openvibe\.events;/);++ assert.ok(host.files.get('/etc/nginx/sites-enabled/openvibe.events.conf'));assert.ok(host.calls.some((c) => c.cmd === 'systemctl' && c.args[0] === 'reload' && c.args[1] === 'nginx.service'));-- host.put('/etc/nginx/sites-available/events.openvibe.network.conf', '# hand-edited previous version\n');++ host.put('/etc/nginx/sites-available/openvibe.events.conf', '# hand-edited previous version\n');host.nginxTest = () => ({ code: 1, stderr: 'nginx: [emerg] duplicate zone' });const reloadsBefore = host.calls.filter((c) => c.cmd === 'systemctl' && c.args[0] === 'reload').length;const bad = await host.cli('nginx', 'render', 'events', '--install');assert.strictEqual(bad.code, 2, bad.out);assert.match(bad.out, /nginx -t failed; the previous vhost files were restored/);-- assert.strictEqual(host.read('/etc/nginx/sites-available/events.openvibe.network.conf'), '# hand-edited previous version\n');++ assert.strictEqual(host.read('/etc/nginx/sites-available/openvibe.events.conf'), '# hand-edited previous version\n');assert.strictEqual(host.calls.filter((c) => c.cmd === 'systemctl' && c.args[0] === 'reload').length, reloadsBefore, 'no reload after a failed test');// A brand-new vhost that fails the test is removed again, link included.@@@ -22,10 +22,8 @@ const { EVENT_TYPES } = require('../server/events/outbox');for (const [i, c] of caps.entries()) {assert.ok(c, `${ids[i]} is not in openvibe-contracts`);assert.strictEqual(c.owner, 'host');-- // host.resource.read is `planned` in the released manifest on purpose: Host ships the index-- // (server/registry/resource-index.js) but OpenVibe.Contracts flips the capability to `active`,-- // with the implementedBy routes, only after the deploy. Every other capability is active.-- assert.strictEqual(c.status, c.id === 'host.resource.read' ? 'planned' : 'active', c.id);++ // Every capability Host guards is active (host.resource.read since openvibe-contracts 0.108.0).++ assert.strictEqual(c.status, 'active', c.id);}});
@@ -564,7 +564,7 @@ review is [docs/threat-review.md](docs/threat-review.md). The launch has not bee
@@ -564,7 +564,7 @@ review is [docs/threat-review.md](docs/threat-review.md). The launch has not bee
Part of the [OpenVibe network](https://openvibe.network). Built in the open by [OpenVibers](https://github.com/OpenVibers).
Part of the [OpenVibe network](https://openvibe.network). Built in the open by [OpenVibers](https://github.com/OpenVibers).
<!-- versions:start -->
<!-- versions:start -->
-- openvibe-contracts: v0.107.0
+- openvibe-contracts: v0.112.0
- openvibe-sdk: v0.26.0
- openvibe-sdk: v0.26.0
- openvibe-shared: v2.13.0
- openvibe-shared: v2.13.0
<!-- versions:end -->
<!-- versions:end -->
@@ -14,7 +14,7 @@
@@ -14,7 +14,7 @@
"port": 4910,
"port": 4910,
"domain": "openvibe.host",
"domain": "openvibe.host",
"tenantDomain": "*.openvibe.host",
"tenantDomain": "*.openvibe.host",
- "contracts": "openvibe-contracts v0.107.0",
+ "contracts": "openvibe-contracts v0.112.0",
"sdk": "openvibe-sdk v0.26.0",
"sdk": "openvibe-sdk v0.26.0",
"shared": "openvibe-shared v2.13.0",
"shared": "openvibe-shared v2.13.0",
"packages": [
"packages": [
@@ -24,7 +24,7 @@ function readTemplate(name) {
@@ -24,7 +24,7 @@ function readTemplate(name) {
return fs.readFileSync(path.join(TEMPLATE_DIR, name), 'utf8');
return fs.readFileSync(path.join(TEMPLATE_DIR, name), 'utf8');
}
}
-/** openvibe.network for events.openvibe.network: the host's certificates are per registrable domain (wildcards). */
+/** openvibe.network for api.openvibe.network: the host's certificates are per registrable domain (wildcards). */
function defaultCertName(domain) {
function defaultCertName(domain) {
return domain.split('.').slice(-2).join('.');
return domain.split('.').slice(-2).join('.');
}
}
@@ -63,6 +63,10 @@ function render(inv, svc, { variant, manifestFile } = {}) {
@@ -63,6 +63,10 @@ function render(inv, svc, { variant, manifestFile } = {}) {
locations = paths.map((p) => fill(readTemplate('location-websocket.tmpl'), { ...base, path: safePath(p) })).join('');
locations = paths.map((p) => fill(readTemplate('location-websocket.tmpl'), { ...base, path: safePath(p) })).join('');
}
}
const name = n.vhost || `${primary}.conf`;
const name = n.vhost || `${primary}.conf`;
+ // One server block, one certificate: without an explicit certName it names only the domains under the
+ // primary's registrable domain (a wildcard covers them); another registrable domain needs its own vhost.
+ const certName = n.certName || defaultCertName(primary);
+ const serverNames = n.certName ? domains : domains.filter((d) => defaultCertName(d) === certName);
const text = fill(readTemplate('vhost.conf.tmpl'), {
const text = fill(readTemplate('vhost.conf.tmpl'), {
...base,
...base,
primary,
primary,
@@ -72,8 +76,8 @@ function render(inv, svc, { variant, manifestFile } = {}) {
@@ -72,8 +76,8 @@ function render(inv, svc, { variant, manifestFile } = {}) {
variant: v,
variant: v,
vhost: name,
vhost: name,
sitesAvailable: inv.nginx.sitesAvailable,
sitesAvailable: inv.nginx.sitesAvailable,
- serverNames: domains.join(' '),
- certName: n.certName || defaultCertName(primary),
+ serverNames: serverNames.join(' '),
+ certName,
maxBody: n.maxBody || '2m',
maxBody: n.maxBody || '2m',
locations,
locations,
httpContext,
httpContext,
@@ -17,7 +17,7 @@
@@ -17,7 +17,7 @@
"express": "^4.21.2",
"express": "^4.21.2",
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"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.112.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.13.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"
@@ -1501,9 +1501,9 @@
@@ -1501,9 +1501,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.107.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.107.0",
- "integrity": "sha512-bttjTDLzCfHFtq5h0EkBaPspVV6U934jj5Hz7RViIh2UTiC2Xzy3d6AnHLsEomVyTwaiwg9veNiO+eZTZ0lxsg==",
+ "version": "0.112.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.112.0",
+ "integrity": "sha512-ujIdCjv+oHfwg/+Hw0tyt2erVnornjDiKVPN8snHvybfysR/DBZQ2G32bQj8oAaK90s12ADEpdrXT1eust3eAw==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -33,7 +33,7 @@
@@ -33,7 +33,7 @@
"express": "^4.21.2",
"express": "^4.21.2",
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"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.112.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.13.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"
@@ -55,8 +55,9 @@ runTests([
@@ -55,8 +55,9 @@ runTests([
const host = scenario();
const host = scenario();
const ev = await host.cli('nginx', 'render', 'events');
const ev = await host.cli('nginx', 'render', 'events');
assert.strictEqual(ev.code, 0, ev.out);
assert.strictEqual(ev.code, 0, ev.out);
- assert.match(ev.out, /server_name events\.openvibe\.network;/);
- assert.match(ev.out, /ssl_certificate +\/etc\/letsencrypt\/live\/openvibe\.network\/fullchain\.pem;/, 'wildcard certificate of the registrable domain');
+ assert.match(ev.out, /server_name openvibe\.events;/, 'only the domains the certificate covers');
+ assert.ok(!/events\.openvibe\.network/.test(ev.out.split('\n').filter((l) => /server_name/.test(l)).join('\n')), 'the other registrable domain gets its own vhost');
+ assert.match(ev.out, /ssl_certificate +\/etc\/letsencrypt\/live\/openvibe\.events\/fullchain\.pem;/, 'the certificate of the registrable domain');
assert.match(ev.out, /location = \/realtime\/stream \{[\s\S]*proxy_buffering off;[\s\S]*proxy_read_timeout 1h;/);
assert.match(ev.out, /location = \/realtime\/stream \{[\s\S]*proxy_buffering off;[\s\S]*proxy_read_timeout 1h;/);
assert.match(ev.out, /proxy_pass http:\/\/127\.0\.0\.1:4300;/);
assert.match(ev.out, /proxy_pass http:\/\/127\.0\.0\.1:4300;/);
const live = await host.cli('nginx', 'render', 'live');
const live = await host.cli('nginx', 'render', 'live');
@@ -67,7 +68,7 @@ runTests([
@@ -67,7 +68,7 @@ runTests([
const plain = await host.cli('nginx', 'render', 'media', '--variant', 'http');
const plain = await host.cli('nginx', 'render', 'media', '--variant', 'http');
assert.match(plain.out, /server_name openvibe\.media;/);
assert.match(plain.out, /server_name openvibe\.media;/);
assert.ok(!/proxy_buffering off/.test(plain.out));
assert.ok(!/proxy_buffering off/.test(plain.out));
- assert.strictEqual(host.read('/etc/nginx/sites-available/events.openvibe.network.conf'), null, 'render alone writes nothing');
+ assert.strictEqual(host.read('/etc/nginx/sites-available/openvibe.events.conf'), null, 'render alone writes nothing');
assert.ok(!host.calls.some((c) => c.cmd === 'nginx' || (c.cmd === 'systemctl' && c.args[0] === 'reload')));
assert.ok(!host.calls.some((c) => c.cmd === 'nginx' || (c.cmd === 'systemctl' && c.args[0] === 'reload')));
}),
}),
@@ -75,18 +76,18 @@ runTests([
@@ -75,18 +76,18 @@ runTests([
const host = scenario();
const host = scenario();
const ok = await host.cli('nginx', 'render', 'events', '--install');
const ok = await host.cli('nginx', 'render', 'events', '--install');
assert.strictEqual(ok.code, 0, ok.out);
assert.strictEqual(ok.code, 0, ok.out);
- const installed = host.read('/etc/nginx/sites-available/events.openvibe.network.conf');
- assert.match(installed, /events\.openvibe\.network/);
- assert.ok(host.files.get('/etc/nginx/sites-enabled/events.openvibe.network.conf'));
+ const installed = host.read('/etc/nginx/sites-available/openvibe.events.conf');
+ assert.match(installed, /server_name openvibe\.events;/);
+ assert.ok(host.files.get('/etc/nginx/sites-enabled/openvibe.events.conf'));
assert.ok(host.calls.some((c) => c.cmd === 'systemctl' && c.args[0] === 'reload' && c.args[1] === 'nginx.service'));
assert.ok(host.calls.some((c) => c.cmd === 'systemctl' && c.args[0] === 'reload' && c.args[1] === 'nginx.service'));
- host.put('/etc/nginx/sites-available/events.openvibe.network.conf', '# hand-edited previous version\n');
+ host.put('/etc/nginx/sites-available/openvibe.events.conf', '# hand-edited previous version\n');
host.nginxTest = () => ({ code: 1, stderr: 'nginx: [emerg] duplicate zone' });
host.nginxTest = () => ({ code: 1, stderr: 'nginx: [emerg] duplicate zone' });
const reloadsBefore = host.calls.filter((c) => c.cmd === 'systemctl' && c.args[0] === 'reload').length;
const reloadsBefore = host.calls.filter((c) => c.cmd === 'systemctl' && c.args[0] === 'reload').length;
const bad = await host.cli('nginx', 'render', 'events', '--install');
const bad = await host.cli('nginx', 'render', 'events', '--install');
assert.strictEqual(bad.code, 2, bad.out);
assert.strictEqual(bad.code, 2, bad.out);
assert.match(bad.out, /nginx -t failed; the previous vhost files were restored/);
assert.match(bad.out, /nginx -t failed; the previous vhost files were restored/);
- assert.strictEqual(host.read('/etc/nginx/sites-available/events.openvibe.network.conf'), '# hand-edited previous version\n');
+ assert.strictEqual(host.read('/etc/nginx/sites-available/openvibe.events.conf'), '# hand-edited previous version\n');
assert.strictEqual(host.calls.filter((c) => c.cmd === 'systemctl' && c.args[0] === 'reload').length, reloadsBefore, 'no reload after a failed test');
assert.strictEqual(host.calls.filter((c) => c.cmd === 'systemctl' && c.args[0] === 'reload').length, reloadsBefore, 'no reload after a failed test');
// A brand-new vhost that fails the test is removed again, link included.
// A brand-new vhost that fails the test is removed again, link included.
@@ -22,10 +22,8 @@ const { EVENT_TYPES } = require('../server/events/outbox');
@@ -22,10 +22,8 @@ const { EVENT_TYPES } = require('../server/events/outbox');
for (const [i, c] of caps.entries()) {
for (const [i, c] of caps.entries()) {
assert.ok(c, `${ids[i]} is not in openvibe-contracts`);
assert.ok(c, `${ids[i]} is not in openvibe-contracts`);
assert.strictEqual(c.owner, 'host');
assert.strictEqual(c.owner, 'host');
- // host.resource.read is `planned` in the released manifest on purpose: Host ships the index
- // (server/registry/resource-index.js) but OpenVibe.Contracts flips the capability to `active`,
- // with the implementedBy routes, only after the deploy. Every other capability is active.
- assert.strictEqual(c.status, c.id === 'host.resource.read' ? 'planned' : 'active', c.id);
+ // Every capability Host guards is active (host.resource.read since openvibe-contracts 0.108.0).
+ assert.strictEqual(c.status, 'active', c.id);
}
}
});
});