openvibers/openvibe.space Commits

openvibe.website: "--" hosts are OpenVibe Connect's; Connect's names reserved (#186)

OP OpenVibers committed 11 days ago · cde341a098 · 3 files, +37 −2

<label>--<user>.openvibe.website is an OpenVibe Connect share (ADR-057, reviewed 2026-11-02). A site's name can never
contain "--", so the tenant vhost's server_name becomes a pattern that leaves those hosts out (nginx prefers a
wildcard to any pattern, so Connect's own pattern could not win against *.openvibe.website). connect, hooks, share,
shares and tunnel are reserved site names.

Changes

ddiff --git a/deploy/nginx/openvibe.website.conf b/deploy/nginx/openvibe.website.conf
iindex 1c9c68a..3eb15ff 100644
---- a/deploy/nginx/openvibe.website.conf
++++ b/deploy/nginx/openvibe.website.conf
@@@ -1,10 +1,15 @@
# Reference wildcard tenant vhost for OpenVibe.Space. Install only with a wildcard certificate
# for openvibe.website and the matching DNS; custom-domain TLS vhosts are generated separately.
++#
++# Every *.openvibe.website host except those with "--" in the name: <label>--<user>.openvibe.website is an
++# OpenVibe Connect share (OpenVibe.Connect deploy/nginx/connect.openvibe.website.conf). A site's name can never
++# contain "--" (server/domain/sites.js NAME_RE), so no site is left out. connect.openvibe.website is Connect's exact
++# name and is reserved here.
limit_req_zone $binary_remote_addr zone=ovspace_sites:20m rate=50r/s;
server {
listen 80;
listen [::]:80;
-- server_name *.openvibe.website;
++ server_name ~^(?!.*--).+\.openvibe\.website$;
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location / { return 301 https://$host$request_uri; }
}
@@@ -12,7 +17,7 @@ server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
-- server_name *.openvibe.website;
++ server_name ~^(?!.*--).+\.openvibe\.website$;
include snippets/security-txt.conf;
ssl_certificate /etc/letsencrypt/live/openvibe.website/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openvibe.website/privkey.pem;
ddiff --git a/server/domain/sites.js b/server/domain/sites.js
iindex f75367e..c81578d 100644
---- a/server/domain/sites.js
++++ b/server/domain/sites.js
@@@ -18,6 +18,8 @@ const RESERVED = new Set([
'docs', 'blog', 'news', 'security', 'abuse', 'postmaster', 'hostmaster', 'webmaster', 'openvibe', 'openvibers', 'network', 'live',
'media', 'community', 'events', 'chat', 'tools', 'codes', 'sites', 'sandbox', 'staging', 'test', 'internal', 'localhost', 'wpad',
'autoconfig', 'autodiscover', 'isatap', 'acme', 'well-known',
++ // OpenVibe Connect's own host and the names its plan keeps (ADR-057): connect.openvibe.website, hooks, shares.
++ 'connect', 'hooks', 'share', 'shares', 'tunnel',
]);
const HOLD_MS = 30 * 24 * 3600 * 1000;
ddiff --git a/test/connect-hosts.test.js b/test/connect-hosts.test.js
nnew file mode 100644
iindex 0000000..4fa43b1
---- /dev/null
++++ b/test/connect-hosts.test.js
@@@ -0,0 +1,28 @@
++'use strict';
++/**
++ * openvibe.website is shared with OpenVibe Connect (ADR-057, 2026-11-02): <label>--<user>.openvibe.website is a
++ * Connect share and connect.openvibe.website is Connect's own host. A site's name can never contain "--", Connect's
++ * names are reserved here, and this repo's vhost leaves every "--" host to Connect.
++ *
++ * node test/connect-hosts.test.js
++ */
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++const { NAME_RE, RESERVED } = require('../server/domain/sites');
++
++['agents--alex', 'a--b', 'x---y'].forEach((n) => assert.ok(!NAME_RE.test(n), `${n} is never a site's name`));
++['my-site', 'abc'].forEach((n) => assert.ok(NAME_RE.test(n), `${n} still is`));
++['connect', 'hooks', 'share', 'shares', 'tunnel'].forEach((n) => assert.ok(RESERVED.has(n), `${n} is reserved`));
++
++const conf = fs.readFileSync(path.join(__dirname, '..', 'deploy', 'nginx', 'openvibe.website.conf'), 'utf8');
++const names = [...conf.matchAll(/server_name\s+([^;]+);/g)].map((m) => m[1].trim());
++assert.ok(!names.includes('*.openvibe.website'), 'no wildcard that would take Connect\'s share hosts');
++const pattern = names.find((n) => n.startsWith('~'));
++assert.ok(pattern, 'the tenant blocks use a pattern');
++const re = new RegExp(pattern.slice(1));
++assert.ok(re.test('my-site.openvibe.website'));
++assert.ok(re.test('preview.my-site.openvibe.website'));
++assert.ok(!re.test('agents--alex.openvibe.website'), 'a share host is Connect\'s');
++assert.ok(!re.test('openvibe.website'));
++console.log('connect hosts: "--" hosts are Connect\'s; Connect\'s names are reserved');