openvibers/openvibe.space Commits
openvibe.website: "--" hosts are OpenVibe Connect's; Connect's names reserved (#186)
Changes
@@@ -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;@@@ -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;nnew file mode 100644@@@ -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');
@@ -1,10 +1,15 @@
@@ -1,10 +1,15 @@
# Reference wildcard tenant vhost for OpenVibe.Space. Install only with a wildcard certificate
# 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.
# 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;
limit_req_zone $binary_remote_addr zone=ovspace_sites:20m rate=50r/s;
server {
server {
listen 80;
listen 80;
listen [::]:80;
listen [::]:80;
- server_name *.openvibe.website;
+ server_name ~^(?!.*--).+\.openvibe\.website$;
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location / { return 301 https://$host$request_uri; }
location / { return 301 https://$host$request_uri; }
}
}
@@ -12,7 +17,7 @@ server {
@@ -12,7 +17,7 @@ server {
listen 443 ssl;
listen 443 ssl;
listen [::]:443 ssl;
listen [::]:443 ssl;
http2 on;
http2 on;
- server_name *.openvibe.website;
+ server_name ~^(?!.*--).+\.openvibe\.website$;
include snippets/security-txt.conf;
include snippets/security-txt.conf;
ssl_certificate /etc/letsencrypt/live/openvibe.website/fullchain.pem;
ssl_certificate /etc/letsencrypt/live/openvibe.website/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openvibe.website/privkey.pem;
ssl_certificate_key /etc/letsencrypt/live/openvibe.website/privkey.pem;
@@ -18,6 +18,8 @@ const RESERVED = new Set([
@@ -18,6 +18,8 @@ const RESERVED = new Set([
'docs', 'blog', 'news', 'security', 'abuse', 'postmaster', 'hostmaster', 'webmaster', 'openvibe', 'openvibers', 'network', 'live',
'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',
'media', 'community', 'events', 'chat', 'tools', 'codes', 'sites', 'sandbox', 'staging', 'test', 'internal', 'localhost', 'wpad',
'autoconfig', 'autodiscover', 'isatap', 'acme', 'well-known',
'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;
const HOLD_MS = 30 * 24 * 3600 * 1000;
new file mode 100644
new file mode 100644
@@ -0,0 +1,28 @@
@@ -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');