Module subdomains: redirect non-Browser visitors to www.bcos.cloud (drop "Browser Required" gate) #4

Open
opened 2026-06-30 15:46:38 -04:00 by hiveiq · 2 comments
Owner

Problem

When a user opens a module subdomain (e.g. profile.bcos.cloud, msp.bcos.cloud, aria.bcos.cloud, etc.) in a normal web browser instead of the HiveOps desktop Browser, the SPA renders a hardcoded Browser Required gate that links to https://cdn.bcos.cloud/downloads/. This:

  • is replicated/hardcoded across 13 SPAs + the template (maintenance smell)
  • on bcos.dev sends users to the production CDN/browser (cross-environment bug)
  • some module subdomains (e.g. profile) have no gate and just half-load

Desired behavior

Do not show a Browser Required page. Instead, redirect (302) non-Browser visitors to https://www.bcos.cloud for all module subdomains, in every environment (dev included). No browser download is offered from the module subdomains.

Approach (nginx, server-side)

The desktop Browser injects an explicit header on every module request (hiveops-browser/src/main/main.js:196 and :1209):

X-HiveIQ-Browser: true

A normal browser never carries it. So nginx can decide server-side, in the SPA location of each module server block:

if ($http_x_hiveiq_browser != "true") { return 302 https://www.bcos.cloud; }

Edge cases

  • Exclude the marketing site (web.bcos.cloud / www) — must stay viewable in a normal browser; avoid redirect loop
  • Exclude /api/, /health, and auth — only the SPA document path redirects (logins, API calls, uptime checks untouched)
  • Scope to module subdomains only: msp, aria, profile, devices, fleet, incident, analytics, claims, recon, reports, transactions, vault, dashboard

Benefits over editing the SPAs

  • One place per environment (nginx config) instead of 13 frontend rebuilds/redeploys
  • Uniform coverage incl. profile (which has no gate today)
  • True forward (instant 302, no page flash); Browser Required screen never renders

Plan

  1. bcos.dev first — add a shared include to the dev module server blocks (hiveiq-ops/.../instances/dev/nginx/conf.d/), reload nginx, verify with curl (with/without X-HiveIQ-Browser header → 200 vs 302→www.bcos.cloud)
  2. Production (bcos.cloud) — same change via PR + approval (separate, not in this dev-only pass)

Dev-only verification is in scope here; production rollout follows the normal PR/approval flow.

## Problem When a user opens a module subdomain (e.g. profile.bcos.cloud, msp.bcos.cloud, aria.bcos.cloud, etc.) in a **normal** web browser instead of the HiveOps desktop Browser, the SPA renders a hardcoded **Browser Required** gate that links to `https://cdn.bcos.cloud/downloads/`. This: - is replicated/hardcoded across 13 SPAs + the template (maintenance smell) - on **bcos.dev** sends users to the **production** CDN/browser (cross-environment bug) - some module subdomains (e.g. profile) have no gate and just half-load ## Desired behavior Do **not** show a Browser Required page. Instead, **redirect (302) non-Browser visitors to `https://www.bcos.cloud`** for all module subdomains, in every environment (dev included). No browser download is offered from the module subdomains. ## Approach (nginx, server-side) The desktop Browser injects an explicit header on every module request (`hiveops-browser/src/main/main.js:196` and `:1209`): ``` X-HiveIQ-Browser: true ``` A normal browser never carries it. So nginx can decide server-side, in the SPA location of each module server block: ```nginx if ($http_x_hiveiq_browser != "true") { return 302 https://www.bcos.cloud; } ``` ### Edge cases - Exclude the marketing site (web.bcos.cloud / www) — must stay viewable in a normal browser; avoid redirect loop - Exclude `/api/`, `/health`, and auth — only the SPA document path redirects (logins, API calls, uptime checks untouched) - Scope to module subdomains only: msp, aria, profile, devices, fleet, incident, analytics, claims, recon, reports, transactions, vault, dashboard ### Benefits over editing the SPAs - One place per environment (nginx config) instead of 13 frontend rebuilds/redeploys - Uniform coverage incl. profile (which has no gate today) - True forward (instant 302, no page flash); Browser Required screen never renders ## Plan 1. **bcos.dev first** — add a shared include to the dev module server blocks (`hiveiq-ops/.../instances/dev/nginx/conf.d/`), reload nginx, verify with curl (with/without `X-HiveIQ-Browser` header → 200 vs 302→www.bcos.cloud) 2. **Production (bcos.cloud)** — same change via PR + approval (separate, not in this dev-only pass) Dev-only verification is in scope here; production rollout follows the normal PR/approval flow.
Author
Owner

Deployed + verified on bcos.dev

Implemented as an nginx server-side redirect (no SPA changes). Added shared snippet nginx/conf.d/snippets/browser-gate.conf:

if ($http_x_hiveiq_browser != "true") { return 302 https://www.bcos.cloud; }

…included into the location / of all 13 module confs (msp, aria, profile, devices, fleet, incident, analytics, claims, recon, reports, transactions, vault, dashboard). nginx -t OK, reloaded.

Verification (live, bcos.dev):

  • All 13 module subdomains, normal browser (no header) → 302 → https://www.bcos.cloud/
  • msp/profile/dashboard with X-HiveIQ-Browser: true200, no redirect (SPA served)
  • msp/health (no header) → 200, not redirected
  • devices/api/devices (no header) → 401 (backend reached, not 302)
  • api.bcos.dev, auth.bcos.dev → unaffected

Change mirrored into the repo copy (hiveiq-openmetal-prod/.../instances/dev/nginx/conf.d/).

Production (bcos.cloud) is NOT done — it will follow via the normal PR + approval flow (same snippet + includes against the production nginx confs, plus excluding the marketing site there to avoid a redirect loop).

### Deployed + verified on bcos.dev Implemented as an nginx server-side redirect (no SPA changes). Added shared snippet `nginx/conf.d/snippets/browser-gate.conf`: ```nginx if ($http_x_hiveiq_browser != "true") { return 302 https://www.bcos.cloud; } ``` …included into the `location /` of all 13 module confs (msp, aria, profile, devices, fleet, incident, analytics, claims, recon, reports, transactions, vault, dashboard). `nginx -t` OK, reloaded. **Verification (live, bcos.dev):** - All 13 module subdomains, normal browser (no header) → **302 → https://www.bcos.cloud/** ✅ - `msp`/`profile`/`dashboard` with `X-HiveIQ-Browser: true` → **200**, no redirect (SPA served) ✅ - `msp/health` (no header) → 200, not redirected ✅ - `devices/api/devices` (no header) → 401 (backend reached, **not** 302) ✅ - `api.bcos.dev`, `auth.bcos.dev` → unaffected ✅ Change mirrored into the repo copy (`hiveiq-openmetal-prod/.../instances/dev/nginx/conf.d/`). **Production (bcos.cloud) is NOT done** — it will follow via the normal PR + approval flow (same snippet + includes against the production nginx confs, plus excluding the marketing site there to avoid a redirect loop).
Author
Owner

Dev change merged: hiveiq-openmetal-prod PR #17 (merge 65d68d99). bcos.dev is live + verified.

Keeping this issue open for the production (bcos.cloud) rollout — same snippet + includes against the prod nginx confs, plus excluding the marketing site (web/www) to avoid a redirect loop.

Dev change merged: hiveiq-openmetal-prod PR #17 (merge `65d68d99`). bcos.dev is live + verified. Keeping this issue **open** for the production (bcos.cloud) rollout — same snippet + includes against the prod nginx confs, plus excluding the marketing site (web/www) to avoid a redirect loop.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hiveiq-src/hiveiq-ops#4