From 929dadbb080d86b0194bff6f49f3a4cb17279574 Mon Sep 17 00:00:00 2001 From: qaz741wsd856 Date: Sun, 28 Dec 2025 16:51:25 +0000 Subject: [PATCH] fix: restructure frontend asset handling and add UI overrides - Updated `.gitignore` to reflect new directory structure for frontend assets under `public/web-vault/`. - Modified `README.md` to include instructions for applying UI overrides and updated deployment notes. - Adjusted `wrangler.toml` to point to the new asset directory. - Updated GitHub workflows to remove large source maps to satisfy Cloudflare static asset per-file limits. - Introduced `vaultwarden.css` for lightweight UI tweaks and added a script to apply these overrides during deployment. - Updated deployment documentation to reflect changes in asset management and optional UI customization. --- .github/workflows/deploy-dev.yaml | 30 +++++++---- .github/workflows/push-cloudflare.yaml | 32 ++++++----- .gitignore | 4 +- README.md | 6 +++ docs/deployment.md | 16 +++--- public/css/vaultwarden.css | 75 ++++++++++++++++++++++++++ scripts/apply-web-vault-overrides.sh | 42 +++++++++++++++ wrangler.toml | 4 +- 8 files changed, 175 insertions(+), 34 deletions(-) create mode 100644 public/css/vaultwarden.css create mode 100644 scripts/apply-web-vault-overrides.sh diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml index f76c7bf..a4d28b8 100644 --- a/.github/workflows/deploy-dev.yaml +++ b/.github/workflows/deploy-dev.yaml @@ -58,23 +58,31 @@ jobs: # Download the web vault release wget -q "https://github.com/dani-garcia/bw_web_builds/releases/download/$LATEST_TAG/bw_web_${LATEST_TAG}.tar.gz" - # Create public directory and extract - mkdir -p public + # Extract to public/web-vault tar -xzf bw_web_${LATEST_TAG}.tar.gz -C public/ - - # bw_web_builds extracts with a web-vault folder, move contents out - if [ -d "public/web-vault" ]; then - shopt -s dotglob - mv public/web-vault/* public/ - shopt -u dotglob - rmdir public/web-vault + + # bw_web_builds extracts into a web-vault folder (expected) + if [ ! -d "public/web-vault" ]; then + echo "❌ Expected ./public/web-vault after extracting bw_web_builds" >&2 + ls -la public/ | head -50 || true + exit 1 fi + + # Remove large source maps to satisfy Cloudflare static asset per-file limits + find public/web-vault -type f -name '*.map' -delete # Cleanup rm -f bw_web_${LATEST_TAG}.tar.gz - echo "✅ Frontend files extracted to ./public" - ls -la public/ | head -20 + echo "✅ Frontend files extracted to ./public/web-vault" + ls -la public/web-vault/ | head -20 + + - name: Apply web vault overrides (vaultwarden.css) + env: + # Optional: control build-time UI tweaks (defaults to hiding signup unless explicitly set to "false") + DISABLE_USER_REGISTRATION: ${{ vars.DISABLE_USER_REGISTRATION_DEV }} + run: | + bash scripts/apply-web-vault-overrides.sh public/web-vault - name: Replace D1_DATABASE_ID_DEV in wrangler.toml run: sed -i "s/\${D1_DATABASE_ID_DEV}/${{ secrets.D1_DATABASE_ID_DEV }}/g" wrangler.toml diff --git a/.github/workflows/push-cloudflare.yaml b/.github/workflows/push-cloudflare.yaml index 0af5de5..861fc6e 100644 --- a/.github/workflows/push-cloudflare.yaml +++ b/.github/workflows/push-cloudflare.yaml @@ -68,23 +68,31 @@ jobs: # Download the web vault release wget -q "https://github.com/dani-garcia/bw_web_builds/releases/download/$LATEST_TAG/bw_web_${LATEST_TAG}.tar.gz" - # Create public directory and extract - mkdir -p public + # Extract to public/web-vault tar -xzf bw_web_${LATEST_TAG}.tar.gz -C public/ - - # bw_web_builds extracts with a web-vault folder, move contents out - if [ -d "public/web-vault" ]; then - shopt -s dotglob - mv public/web-vault/* public/ - shopt -u dotglob - rmdir public/web-vault + + # bw_web_builds extracts into a web-vault folder (expected) + if [ ! -d "public/web-vault" ]; then + echo "❌ Expected ./public/web-vault after extracting bw_web_builds" >&2 + ls -la public/ | head -50 || true + exit 1 fi - + + # Remove large source maps to satisfy Cloudflare static asset per-file limits + find public/web-vault -type f -name '*.map' -delete + # Cleanup rm -f bw_web_${LATEST_TAG}.tar.gz - echo "✅ Frontend files extracted to ./public" - ls -la public/ | head -20 + echo "✅ Frontend files extracted to ./public/web-vault" + ls -la public/web-vault/ | head -20 + + - name: Apply web vault overrides (vaultwarden.css) + env: + # Optional: control build-time UI tweaks (defaults to hiding signup unless explicitly set to "false") + DISABLE_USER_REGISTRATION: ${{ vars.DISABLE_USER_REGISTRATION }} + run: | + bash scripts/apply-web-vault-overrides.sh public/web-vault - name: Replace D1_DATABASE_ID in wrangler.toml run: sed -i "s/\${D1_DATABASE_ID}/${{ secrets.D1_DATABASE_ID }}/g" wrangler.toml diff --git a/.gitignore b/.gitignore index c8b2c2a..968dd52 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,8 @@ node_modules .wrangler .env # Frontend files (downloaded during deployment/development) -public/ +public/web-vault/ # reference repos vaultwarden/ -bw_web_builds/ \ No newline at end of file +bw_web_builds/ diff --git a/README.md b/README.md index 4faa1f2..719ef66 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,12 @@ The frontend is bundled with the Worker using [Cloudflare Workers Static Assets] - API requests (`/api/*`, `/identity/*`) are routed to the Rust Worker. - No separate Pages deployment or domain configuration needed. +**UI overrides (optional):** +- This project ships a small set of "lightweight self-host" UI tweaks in `public/css/`. +- In CI/CD (and optionally locally), we apply them after extracting `bw_web_builds`: + - `bash scripts/apply-web-vault-overrides.sh public/web-vault` + - The script can read `DISABLE_USER_REGISTRATION` to decide whether to additionally hide the signup entry in the web vault UI. + > [!NOTE] > Migrating from separate frontend deployment? If you previously deployed the frontend separately to Cloudflare Pages, you can delete the `warden-frontend` Pages project and re-setup the router for the worker. The frontend is now bundled with the Worker and no longer requires a separate deployment. diff --git a/docs/deployment.md b/docs/deployment.md index 8ba2708..45ac0c4 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -63,15 +63,17 @@ This page covers the two deployment paths. Pick the one that fits your workflow # Download and extract wget "https://github.com/dani-garcia/bw_web_builds/releases/download/$LATEST_TAG/bw_web_${LATEST_TAG}.tar.gz" - mkdir -p public tar -xzf bw_web_${LATEST_TAG}.tar.gz -C public/ - - # Move files from web-vault subfolder - shopt -s dotglob - mv public/web-vault/* public/ - shopt -u dotglob - rmdir public/web-vault rm bw_web_${LATEST_TAG}.tar.gz + + # Remove large source maps to satisfy Cloudflare static asset per-file limits + find public/web-vault -type f -name '*.map' -delete + ``` + + **Optional:** Apply lightweight UI overrides to generate `public/web-vault/css/vaultwarden.css`: + + ```bash + bash scripts/apply-web-vault-overrides.sh public/web-vault ``` 6. **Set up database and deploy the worker:** diff --git a/public/css/vaultwarden.css b/public/css/vaultwarden.css new file mode 100644 index 0000000..2d9c1cf --- /dev/null +++ b/public/css/vaultwarden.css @@ -0,0 +1,75 @@ +/* + Vaultwarden compatibility stylesheet for Bitwarden Web Vault. + + Design goals: + - Only perform UI hiding/patching needed for "lightweight self-use" projects to avoid confusion from unsupported features. + - Not dynamically generated during Worker runtime (saves Cloudflare Worker CPU/request quotas). + + Usage: + - After CI/CD or local download of bw_web_builds and extraction, keep `public/web-vault/` as the static resource root directory. + - Run: `bash scripts/apply-web-vault-overrides.sh public/web-vault` + which will copy this file (public/css/vaultwarden.css) to `public/web-vault/css/vaultwarden.css`. + + Switch description (build-time): + - Registration button hiding: The script decides whether to append CSS hiding registration entries based on the environment variable `DISABLE_USER_REGISTRATION` + (hidden by default; only not hidden when "false"), + consistent with backend `src/handlers/config.rs` logic. +*/ + +/* Hide unsupported UI elements */ +.vw-hide, +bit-nav-item[route="settings/subscription"], +a[href$="/settings/sponsored-families"], + +/* SSO UI (newer builds, if present) */ +.vw-email-sso, +.vw-sso-login, +.vw-or-text, +.vw-other-login, + +/* Passkey/WebAuthn login UI (newer builds, if present) */ +.vw-passkey-login, + +/* Legacy selectors for older web vault builds (< 2025.5.1) */ +app-root ng-component > form > div:nth-child(1) > div > button[buttontype="secondary"].\!tw-text-primary-600:nth-child(4), +app-root ng-component > form > div:nth-child(1) > div > button[buttontype="secondary"].\!tw-text-primary-600:nth-child(3), +app-root ng-component > form > div:nth-child(1) > div:nth-child(3) > div:nth-child(2), + +/* Org-related / enterprise UI */ +app-organization-plans > form > bit-section:nth-child(2), +app-org-account form.ng-untouched:nth-child(5), +app-org-reports-home > app-report-list > div.tw-inline-grid > div:nth-child(6), +bit-dialog div.tw-ml-4:has(bit-form-control input), +bit-dialog div.tw-col-span-4:has(input[formcontrolname*="access"], input[formcontrolname*="manage"]), + +/* Device verification / protection UI (not supported) */ +app-security > app-two-factor-setup > form, +app-user-layout app-danger-zone button:nth-child(1), + +/* Two-factor providers (hide unsupported ones; keep authenticator/TOTP visible) */ +.providers-2fa-1, +.providers-2fa-3, +.providers-2fa-7, + +/* Emergency access & Sends (not supported) */ +bit-nav-item[route="settings/emergency-access"], +bit-nav-item[route="sends"], + +/* Passkey settings (not supported) */ +app-user-layout app-password-settings app-webauthn-login-settings { + display: none !important; +} + +/* Change collapsed menu icon to Vaultwarden */ +bit-nav-logo bit-nav-item a:before { + content: ""; + background-image: url("../images/icon-white.svg"); + background-repeat: no-repeat; + background-position: center center; + height: 32px; + display: block; +} + +bit-nav-logo bit-nav-item .bwi-shield { + display: none !important; +} diff --git a/scripts/apply-web-vault-overrides.sh b/scripts/apply-web-vault-overrides.sh new file mode 100644 index 0000000..1d2b34d --- /dev/null +++ b/scripts/apply-web-vault-overrides.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -euo pipefail + +WEB_VAULT_DIR="${1:-public/web-vault}" +WEB_VAULT_DIR="${WEB_VAULT_DIR%/}" + +SRC_CSS="public/css/vaultwarden.css" +DST_CSS="${WEB_VAULT_DIR}/css/vaultwarden.css" + +if [[ ! -f "${SRC_CSS}" ]]; then + echo "❌ Missing source CSS: ${SRC_CSS}" >&2 + exit 1 +fi + +if [[ ! -d "${WEB_VAULT_DIR}" ]]; then + echo "❌ Missing web vault directory: ${WEB_VAULT_DIR}" >&2 + echo " (Expected bw_web_builds to extract into a 'web-vault' folder.)" >&2 + exit 1 +fi + +mkdir -p "$(dirname "${DST_CSS}")" +cp "${SRC_CSS}" "${DST_CSS}" + +# Keep behavior consistent with backend src/handlers/config.rs: +# - Defaults to true if not set +# - Only "false" disables it +disable_user_registration="${DISABLE_USER_REGISTRATION:-}" +disable_user_registration="$(printf '%s' "${disable_user_registration}" | tr '[:upper:]' '[:lower:]')" + +if [[ -z "${disable_user_registration}" || "${disable_user_registration}" != "false" ]]; then + cat >> "${DST_CSS}" <<'EOF' + +/* Build-time option: hide signup/register UI when DISABLE_USER_REGISTRATION != "false" */ +app-root a[routerlink="/signup"], +app-login form div + div + div + div + hr, +app-login form div + div + div + div + hr + p { + display: none !important; +} +EOF +fi + +echo "✅ Installed override CSS: ${DST_CSS}" diff --git a/wrangler.toml b/wrangler.toml index e715633..3f55d42 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -34,9 +34,9 @@ namespace_id = "1001" simple = { limit = 5, period = 60 } # Static assets configuration for serving frontend -# Frontend files should be placed in ./public directory before deployment +# Frontend files (bw_web_builds) are expected under ./public/web-vault before deployment [assets] -directory = "./public" +directory = "./public/web-vault" not_found_handling = "404-page" html_handling = "auto-trailing-slash" # Only invoke Worker for API and Identity routes, serve static files directly for other routes