Skip to content

feat: web installer, setup mode, doctor command and Docker-first deploy#1763

Open
confuser wants to merge 1 commit intomasterfrom
feat/easier-setup-web-installer
Open

feat: web installer, setup mode, doctor command and Docker-first deploy#1763
confuser wants to merge 1 commit intomasterfrom
feat/easier-setup-web-installer

Conversation

@confuser
Copy link
Copy Markdown
Member

Summary

Adds a first-run web installer at /setup so new operators can complete configuration from the browser without hand-editing .env, plus a companion bmwebui doctor command and production Docker compose stacks. The CLI setup wizard gains BanManager config auto-detection and transactional admin creation.

The intent is to let a brand-new user go from docker compose up (or npm start) → browser → working WebUI in a few minutes, with the same UX available to bare-metal/CLI users.

What's new

Setup mode

  • The server now boots even without keys/DB and serves only /setup, /health and the installer assets.
  • The main UI is gated until configuration is complete.
  • /health reports setup_required vs ok (consumed by Docker / orchestrators).

Web installer

  • Vanilla JS wizard (HTML / CSS / JS shipped from server/setup/static/) walks through env vars, DB connection, schema migration, BanManager server registration and admin user creation.
  • Atomic finalize: server + admin user inserts are wrapped in a single Knex transaction, so a partial failure never leaves an orphan bm_web_servers row.
  • Same theme/icon as the main WebUI (no Google Fonts; offline-friendly).

bmwebui doctor

  • Validates env, DB connection, migration status, admin presence, and pings each configured BanManager server (with encrypted-password decryption).
  • Exits non-zero if anything is wrong, suitable for cron / monitoring hooks.

bmwebui setup enhancements

  • Optional auto-detect from BanManager plugin folder (config.yml + console.yml).
  • Reuses the WebUI database when desired (skips re-prompting for connection details).
  • Uses shared createAdminUser helper for transactional admin + role inserts.

Reverse-proxy generators

  • bmwebui setup apache and bmwebui setup caddy emit ready-to-use config from validated domain/subdirectory inputs.

Docker

  • Multi-arch image build (linux/amd64, linux/arm64) with GHA cache.
  • docker-entrypoint.js auto-generates missing keys on first run.
  • New docker-compose.prod.yml (with bundled MySQL) and docker-compose.prod-no-db.yml (BYO DB).
  • New CI smoke job stands up the compose stack and asserts /health reports setup_required or ok.

Dev tooling

  • scripts/seed.js now generates dev keys on first run and refuses to run with NODE_ENV=production.
  • bmwebui update shares the new migration helper.

Security hardening

  • Timing-safe comparison for SETUP_TOKEN.
  • Same-origin (Origin / Referer) check on /api/setup/* writes (CSRF protection).
  • Strict regex validation for domain/subdirectory passed to apachectl / caddy validate.
  • parseBanManagerConfig restricted to config.yml / console.yml only (no path traversal).
  • BASE_PATH validated and HTML/JSON-escaped before injection into installer HTML.
  • MySQL healthcheck password moved out of CLI args via MYSQL_PWD.
  • docker-compose.prod.yml requires explicit DB credentials (no silent defaults).

Tests

  • 8 new server-side test suites (real DB, no mocks): setup state, finalize atomicity, env validation, key generation, parse-config, mode boot, basepath handling, admin creation.
  • New server/test/lib/setup-fresh.js harness applies WebUI + BanManager migrations against an isolated DB so installer code can run end-to-end.
  • bmwebui doctor covered with both negative (nothing configured) and positive (fully-seeded install) paths.
  • Existing CLI setup / update tests updated for the new "Done" output.

Test plan

  • npm test (lint + Jest) — full suite is green locally (561 pass, 1 intentionally skipped; 2 known mutation tests are pre-existing parallelism flakes that pass in isolation).
  • CI smoke_docker job runs compose stack and verifies /health reports setup_required.
  • Manual web installer walkthrough on a fresh DB:
    • Visit /setup with no env → wizard renders.
    • Submit env / DB / BM server / admin → finalize succeeds.
    • Visit / → main UI works, /setup redirects away.
  • npx bmwebui doctor reports PASS on the seeded install.
  • npx bmwebui setup auto-detects an existing BanManager plugin folder.
  • npx bmwebui setup apache / caddy emit valid configs.

Notes

  • The web installer is intentionally unauthenticated by default (matches Ghost / WordPress first-run UX). Operators can set SETUP_TOKEN to require a bearer token if they need to expose /setup over the public internet during install.
  • 5 unrelated IP-mutation test files were stashed locally for feat/ips; they are not part of this PR.

Adds a first-run web installer at /setup so new operators can complete
configuration from the browser without hand-editing .env, plus a
companion `bmwebui doctor` command and Docker compose stacks for
production. The CLI setup wizard gains BanManager config auto-detection
and transactional admin creation, and the seed/update commands share
the same migration helper.

Highlights
- Setup mode: server boots without keys/DB and serves only /setup,
  /health and the installer assets. Refuses to expose the main UI
  until configuration is complete.
- Web installer: vanilla JS wizard (HTML/CSS/JS shipped from
  server/setup/static) walks through env vars, DB connection, schema
  migration, BanManager server registration and admin user creation.
  Atomic finalize wraps server + admin creation in a single Knex tx.
- bmwebui doctor: validates env, DB connection, migration status,
  admin presence, and pings each configured BanManager server (with
  encrypted password decryption).
- bmwebui setup: optional auto-detect from BanManager plugin folder
  (config.yml + console.yml), reuses WebUI database when desired,
  shared createAdminUser helper, transactional inserts.
- Apache + Caddy reverse-proxy generators (`bmwebui setup apache` /
  `bmwebui setup caddy`) with validated domain/subdirectory inputs.
- Docker: multi-arch image build, docker-entrypoint.js auto-generates
  missing keys, docker-compose.prod.yml + docker-compose.prod-no-db.yml,
  /health endpoint reports setup_required vs ok for orchestration.
- /health endpoint reuses the existing dbPool to avoid opening a
  new connection per request.

Security hardening
- Timing-safe comparison for SETUP_TOKEN.
- Same-origin (Origin/Referer) check on /api/setup/* writes.
- Strict regex validation for domain/subdirectory passed to shell.
- parseBanManagerConfig restricted to config.yml/console.yml only.
- BASE_PATH validated and HTML/JSON-escaped before injection.
- MySQL healthcheck password moved out of CLI args via MYSQL_PWD.
- docker-compose.prod.yml requires explicit DB credentials (no
  silent defaults).

Tests
- 8 new server-side suites covering setup state, finalize atomicity,
  env validation, key generation, parse-config, mode boot,
  basepath handling, and admin creation.
- New test/lib/setup-fresh.js harness applies WebUI + BanManager
  migrations against an isolated DB so installer code can run in
  realistic conditions without mocks.
- doctor positive/negative paths covered.
@cypress
Copy link
Copy Markdown

cypress bot commented Apr 18, 2026

BanManager-WebUI    Run #10178

Run Properties:  status check passed Passed #10178  •  git commit 028dfdd137 ℹ️: Merge c6fe04c5d592b3f3e88e6eb2dc3bac9941042463 into 46fd192ddb0ef37e7c23a1ff5907...
Project BanManager-WebUI
Branch Review feat/easier-setup-web-installer
Run status status check passed Passed #10178
Run duration 00m 44s
Commit git commit 028dfdd137 ℹ️: Merge c6fe04c5d592b3f3e88e6eb2dc3bac9941042463 into 46fd192ddb0ef37e7c23a1ff5907...
Committer James Mortemore
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 26
View all changes introduced in this branch ↗︎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant