openvibers/openvibe.network Commits
Park the seven 11-07 domains; they join OWNED_ZONES (#638)
Changes
@@@ -21,6 +21,8 @@# openvibe.cam left on 2026-10-28: OpenVibe.Cam serves it (OpenVibe.Cam deploy/nginx/openvibe.cam.conf).# 2026-10-28: the thirteen domains bought that day (open.shoes and twelve openvibe.*) are parked here, each sent to# where its capability lives today, until its room's own vhost takes the name (plan: OpenVibe_New_Domains_Plan).++# 2026-11-07: the seven bought that day (openvibe.computer, .email, .link, .locker, .my, .party, .studio) are parked++# here the same way, each sent to where its capability lives today (plan: OpenVibe_Seven_Domains_Plan §1).## Install: sudo ov-vhost-install deploy/nginx/parked-domains.conf parked-domains.conf# after removing Sites' vhost for each name. Each name uses its own certificate (a vhost must use its own@@@ -63,3 +65,135 @@ server {# openvibe.cam is served by OpenVibe.Cam since 2026-10-28 (its own vhost, deploy/nginx/openvibe.cam.conf).++# openvibe.my: parked, sent to Network's account hub (everything that's yours) until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.my www.openvibe.my;++ return 302 https://openvibe.network/my;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.my www.openvibe.my;++ ssl_certificate /etc/letsencrypt/live/openvibe.my/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.my/privkey.pem;++ access_log off;++ return 302 https://openvibe.network/my;++}++++# openvibe.link: parked, sent to OpenVibe Node, the Link core until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.link www.openvibe.link;++ return 302 https://node.openvibe.network/;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.link www.openvibe.link;++ ssl_certificate /etc/letsencrypt/live/openvibe.link/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.link/privkey.pem;++ access_log off;++ return 302 https://node.openvibe.network/;++}++++# openvibe.computer: parked, sent to agent desks and cloud sessions until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.computer www.openvibe.computer;++ return 302 https://openvibe.run/;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.computer www.openvibe.computer;++ ssl_certificate /etc/letsencrypt/live/openvibe.computer/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.computer/privkey.pem;++ access_log off;++ return 302 https://openvibe.run/;++}++++# openvibe.party: parked, sent to Chat's party rooms until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.party www.openvibe.party;++ return 302 https://openvibe.chat/;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.party www.openvibe.party;++ ssl_certificate /etc/letsencrypt/live/openvibe.party/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.party/privkey.pem;++ access_log off;++ return 302 https://openvibe.chat/;++}++++# openvibe.email: parked, sent to Chat's messages and inbox (no mailbox service yet) until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.email www.openvibe.email;++ return 302 https://openvibe.chat/;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.email www.openvibe.email;++ ssl_certificate /etc/letsencrypt/live/openvibe.email/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.email/privkey.pem;++ access_log off;++ return 302 https://openvibe.chat/;++}++++# openvibe.locker: parked, sent to share links with locks until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.locker www.openvibe.locker;++ return 302 https://openvibe.download/;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.locker www.openvibe.locker;++ ssl_certificate /etc/letsencrypt/live/openvibe.locker/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.locker/privkey.pem;++ access_log off;++ return 302 https://openvibe.download/;++}++++# openvibe.studio: parked, sent to Video's editor and the creative tools until its own vhost takes the name (2026-11-07).++server {++ listen 80;++ listen [::]:80;++ server_name openvibe.studio www.openvibe.studio;++ return 302 https://openvibe.video/;++}++++server {++ listen 443 ssl;++ listen [::]:443 ssl;++ http2 on;++ server_name openvibe.studio www.openvibe.studio;++ ssl_certificate /etc/letsencrypt/live/openvibe.studio/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/openvibe.studio/privkey.pem;++ access_log off;++ return 302 https://openvibe.video/;++}@@@ -649,7 +649,7 @@ function ripple(btn, e) {// safe-redirect:begin// Where a sign-in may send the browser: a path on this site, this origin, or https on a zone// OpenVibe owns (server/auth/sso-owned.js). Never javascript:/data:, never another host.--const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design'];++const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design', 'openvibe.computer', 'openvibe.email', 'openvibe.link', 'openvibe.locker', 'openvibe.my', 'openvibe.party', 'openvibe.studio'];const OV_USER_CONTENT_ZONES = ['openvibe.host']; // tenant sites: only the apex is oursfunction safeReturnUrl(raw) {const s = String(raw == null ? '' : raw);@@@ -81,7 +81,7 @@ li.now .dot i{animation:breathe 1.2s var(--ov-ease-in-out, ease-in-out) infinite// safe-redirect:begin// Where a sign-in may send the browser: a path on this site, this origin, or https on a zone// OpenVibe owns (server/auth/sso-owned.js). Never javascript:/data:, never another host.-- const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design'];++ const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design', 'openvibe.computer', 'openvibe.email', 'openvibe.link', 'openvibe.locker', 'openvibe.my', 'openvibe.party', 'openvibe.studio'];const OV_USER_CONTENT_ZONES = ['openvibe.host']; // tenant sites: only the apex is oursfunction safeNext(raw) {const s = String(raw == null ? '' : raw);@@@ -7,6 +7,8 @@ const OWNED_ZONES = ['openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons','openre.stream','open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design',++ // 2026-11-07: the seven bought that day (parked in deploy/nginx/parked-domains.conf until their products serve them).++ 'openvibe.computer', 'openvibe.email', 'openvibe.link', 'openvibe.locker', 'openvibe.my', 'openvibe.party', 'openvibe.studio',];// Zones whose subdomains are people's own content (OpenVibe.Host tenant sites, <site>.openvibe.host,// which run the tenant's JS): only the apex is OpenVibe's. Domain validation still refuses them as
@@ -21,6 +21,8 @@
@@ -21,6 +21,8 @@
# openvibe.cam left on 2026-10-28: OpenVibe.Cam serves it (OpenVibe.Cam deploy/nginx/openvibe.cam.conf).
# openvibe.cam left on 2026-10-28: OpenVibe.Cam serves it (OpenVibe.Cam deploy/nginx/openvibe.cam.conf).
# 2026-10-28: the thirteen domains bought that day (open.shoes and twelve openvibe.*) are parked here, each sent to
# 2026-10-28: the thirteen domains bought that day (open.shoes and twelve openvibe.*) are parked here, each sent to
# where its capability lives today, until its room's own vhost takes the name (plan: OpenVibe_New_Domains_Plan).
# where its capability lives today, until its room's own vhost takes the name (plan: OpenVibe_New_Domains_Plan).
+# 2026-11-07: the seven bought that day (openvibe.computer, .email, .link, .locker, .my, .party, .studio) are parked
+# here the same way, each sent to where its capability lives today (plan: OpenVibe_Seven_Domains_Plan §1).
#
#
# Install: sudo ov-vhost-install deploy/nginx/parked-domains.conf parked-domains.conf
# Install: sudo ov-vhost-install deploy/nginx/parked-domains.conf parked-domains.conf
# after removing Sites' vhost for each name. Each name uses its own certificate (a vhost must use its own
# after removing Sites' vhost for each name. Each name uses its own certificate (a vhost must use its own
@@ -63,3 +65,135 @@ server {
@@ -63,3 +65,135 @@ server {
# openvibe.cam is served by OpenVibe.Cam since 2026-10-28 (its own vhost, deploy/nginx/openvibe.cam.conf).
# openvibe.cam is served by OpenVibe.Cam since 2026-10-28 (its own vhost, deploy/nginx/openvibe.cam.conf).
+# openvibe.my: parked, sent to Network's account hub (everything that's yours) until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.my www.openvibe.my;
+ return 302 https://openvibe.network/my;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.my www.openvibe.my;
+ ssl_certificate /etc/letsencrypt/live/openvibe.my/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.my/privkey.pem;
+ access_log off;
+ return 302 https://openvibe.network/my;
+}
+
+# openvibe.link: parked, sent to OpenVibe Node, the Link core until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.link www.openvibe.link;
+ return 302 https://node.openvibe.network/;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.link www.openvibe.link;
+ ssl_certificate /etc/letsencrypt/live/openvibe.link/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.link/privkey.pem;
+ access_log off;
+ return 302 https://node.openvibe.network/;
+}
+
+# openvibe.computer: parked, sent to agent desks and cloud sessions until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.computer www.openvibe.computer;
+ return 302 https://openvibe.run/;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.computer www.openvibe.computer;
+ ssl_certificate /etc/letsencrypt/live/openvibe.computer/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.computer/privkey.pem;
+ access_log off;
+ return 302 https://openvibe.run/;
+}
+
+# openvibe.party: parked, sent to Chat's party rooms until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.party www.openvibe.party;
+ return 302 https://openvibe.chat/;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.party www.openvibe.party;
+ ssl_certificate /etc/letsencrypt/live/openvibe.party/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.party/privkey.pem;
+ access_log off;
+ return 302 https://openvibe.chat/;
+}
+
+# openvibe.email: parked, sent to Chat's messages and inbox (no mailbox service yet) until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.email www.openvibe.email;
+ return 302 https://openvibe.chat/;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.email www.openvibe.email;
+ ssl_certificate /etc/letsencrypt/live/openvibe.email/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.email/privkey.pem;
+ access_log off;
+ return 302 https://openvibe.chat/;
+}
+
+# openvibe.locker: parked, sent to share links with locks until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.locker www.openvibe.locker;
+ return 302 https://openvibe.download/;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.locker www.openvibe.locker;
+ ssl_certificate /etc/letsencrypt/live/openvibe.locker/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.locker/privkey.pem;
+ access_log off;
+ return 302 https://openvibe.download/;
+}
+
+# openvibe.studio: parked, sent to Video's editor and the creative tools until its own vhost takes the name (2026-11-07).
+server {
+ listen 80;
+ listen [::]:80;
+ server_name openvibe.studio www.openvibe.studio;
+ return 302 https://openvibe.video/;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ http2 on;
+ server_name openvibe.studio www.openvibe.studio;
+ ssl_certificate /etc/letsencrypt/live/openvibe.studio/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/openvibe.studio/privkey.pem;
+ access_log off;
+ return 302 https://openvibe.video/;
+}
@@ -649,7 +649,7 @@ function ripple(btn, e) {
@@ -649,7 +649,7 @@ function ripple(btn, e) {
// safe-redirect:begin
// safe-redirect:begin
// Where a sign-in may send the browser: a path on this site, this origin, or https on a zone
// Where a sign-in may send the browser: a path on this site, this origin, or https on a zone
// OpenVibe owns (server/auth/sso-owned.js). Never javascript:/data:, never another host.
// OpenVibe owns (server/auth/sso-owned.js). Never javascript:/data:, never another host.
-const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design'];
+const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design', 'openvibe.computer', 'openvibe.email', 'openvibe.link', 'openvibe.locker', 'openvibe.my', 'openvibe.party', 'openvibe.studio'];
const OV_USER_CONTENT_ZONES = ['openvibe.host']; // tenant sites: only the apex is ours
const OV_USER_CONTENT_ZONES = ['openvibe.host']; // tenant sites: only the apex is ours
function safeReturnUrl(raw) {
function safeReturnUrl(raw) {
const s = String(raw == null ? '' : raw);
const s = String(raw == null ? '' : raw);
@@ -81,7 +81,7 @@ li.now .dot i{animation:breathe 1.2s var(--ov-ease-in-out, ease-in-out) infinite
@@ -81,7 +81,7 @@ li.now .dot i{animation:breathe 1.2s var(--ov-ease-in-out, ease-in-out) infinite
// safe-redirect:begin
// safe-redirect:begin
// Where a sign-in may send the browser: a path on this site, this origin, or https on a zone
// Where a sign-in may send the browser: a path on this site, this origin, or https on a zone
// OpenVibe owns (server/auth/sso-owned.js). Never javascript:/data:, never another host.
// OpenVibe owns (server/auth/sso-owned.js). Never javascript:/data:, never another host.
- const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design'];
+ const OV_OWNED_ZONES = ['openvibe.network', 'openvibe.live', 'openvibe.tools', 'openvibe.media', 'openvibe.games', 'openvibe.community', 'openvibe.space', 'openvibe.chat', 'openvibe.codes', 'openvibe.blog', 'openvibe.wiki', 'openvibe.news', 'openvibe.reviews', 'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons', 'openre.stream', 'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design', 'openvibe.computer', 'openvibe.email', 'openvibe.link', 'openvibe.locker', 'openvibe.my', 'openvibe.party', 'openvibe.studio'];
const OV_USER_CONTENT_ZONES = ['openvibe.host']; // tenant sites: only the apex is ours
const OV_USER_CONTENT_ZONES = ['openvibe.host']; // tenant sites: only the apex is ours
function safeNext(raw) {
function safeNext(raw) {
const s = String(raw == null ? '' : raw);
const s = String(raw == null ? '' : raw);
@@ -7,6 +7,8 @@ const OWNED_ZONES = [
@@ -7,6 +7,8 @@ const OWNED_ZONES = [
'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons',
'openvibe.tips', 'openvibe.vip', 'openvibe.trade', 'openvibe.host', 'openvibe.deals', 'openvibe.coupons',
'openre.stream',
'openre.stream',
'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design',
'open.shoes', 'openvibe.today', 'openvibe.vision', 'openvibe.domains', 'openvibe.report', 'openvibe.meme', 'openvibe.casino', 'openvibe.surf', 'openvibe.fun', 'openvibe.tours', 'openvibe.exchange', 'openvibe.cam', 'openvibe.design',
+ // 2026-11-07: the seven bought that day (parked in deploy/nginx/parked-domains.conf until their products serve them).
+ 'openvibe.computer', 'openvibe.email', 'openvibe.link', 'openvibe.locker', 'openvibe.my', 'openvibe.party', 'openvibe.studio',
];
];
// Zones whose subdomains are people's own content (OpenVibe.Host tenant sites, <site>.openvibe.host,
// Zones whose subdomains are people's own content (OpenVibe.Host tenant sites, <site>.openvibe.host,
// which run the tenant's JS): only the apex is OpenVibe's. Domain validation still refuses them as
// which run the tenant's JS): only the apex is OpenVibe's. Domain validation still refuses them as