diff --git a/.github/workflows/deploy-frontend.yml b/.github/workflows/deploy-frontend.yml new file mode 100644 index 0000000..11f9c78 --- /dev/null +++ b/.github/workflows/deploy-frontend.yml @@ -0,0 +1,43 @@ +name: Deploy Frontend + +on: + workflow_dispatch: # Manual trigger +# schedule: +# - cron: '0 2 * * 0' # Check for updates every Sunday + +jobs: + deploy-pages: + runs-on: ubuntu-latest + name: Deploy to Cloudflare Pages + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download latest web-vault release + run: | + # Get latest version tag + LATEST_TAG=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | jq -r .tag_name) + echo "Downloading version: $LATEST_TAG" + + # Download corresponding tar.gz package (Note: bw_web_builds releases are typically named bw_web_tag.tar.gz) + wget "https://github.com/dani-garcia/bw_web_builds/releases/download/$LATEST_TAG/bw_web_${LATEST_TAG}.tar.gz" + + # Extract to public directory (Cloudflare Pages default deployment directory) + mkdir public + tar -xvf bw_web_${LATEST_TAG}.tar.gz -C public/ + + # Fix: bw_web_builds usually extracts with a web-vault folder, need to move contents out + # Adjust based on actual extraction structure, usually contains index.html etc. + if [ -d "public/web-vault" ]; then + shopt -s dotglob + mv public/web-vault/* public/ + shopt -u dotglob + rmdir public/web-vault + fi + + - name: Deploy to Cloudflare Pages + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy public --project-name=warden-frontend --branch=main \ No newline at end of file diff --git a/README.md b/README.md index f49a33a..8219cfd 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,14 @@ You can configure the following environment variables in `wrangler.toml` under t * Defaults to `30` records per batch if not specified * Example: `IMPORT_BATCH_SIZE = "50"` to process 50 records per batch +* **`DISABLE_USER_REGISTRATION`** (Optional, Default: `true`) + + Controls whether the "Create Account" / registration button is displayed in the Bitwarden client UI. + + * Set to `false` to show the registration button + * Defaults to `true` (hide registration button) + * **Note:** This setting only affects the client UI display. It does NOT affect the actual registration functionality on the server side. + ### Scheduled Tasks (Cron) The worker includes a scheduled task that runs automatically to clean up soft-deleted items. By default, this task runs daily at 03:00 UTC. diff --git a/src/handlers/config.rs b/src/handlers/config.rs index bf16671..635828a 100644 --- a/src/handlers/config.rs +++ b/src/handlers/config.rs @@ -1,9 +1,24 @@ -use axum::Json; +use axum::{extract::State, Extension, Json}; use serde_json::{json, Value}; +use std::sync::Arc; +use worker::Env; + +use crate::BaseUrl; + +/// Get the disable_user_registration setting from environment variable. +/// Defaults to true if not set. Only "false" will disable it. +fn get_disable_user_registration(env: &Env) -> bool { + env.var("DISABLE_USER_REGISTRATION") + .ok() + .map(|v| v.to_string().to_lowercase() != "false") + .unwrap_or(true) +} #[worker::send] -pub async fn config() -> Json { - // let domain = crate::CONFIG.domain(); +pub async fn config( + State(env): State>, + Extension(BaseUrl(domain)): Extension, +) -> Json { // Official available feature flags can be found here: // Server (v2025.6.2): https://github.com/bitwarden/server/blob/d094be3267f2030bd0dc62106bc6871cf82682f5/src/Core/Constants.cs#L103 // Client (web-v2025.6.1): https://github.com/bitwarden/clients/blob/747c2fd6a1c348a57a76e4a7de8128466ffd3c01/libs/common/src/enums/feature-flag.enum.ts#L12 @@ -16,8 +31,9 @@ pub async fn config() -> Json { // feature_states.insert("unauth-ui-refresh".to_string(), true); // feature_states.insert("enable-pm-flight-recorder".to_string(), true); // feature_states.insert("mobile-error-reporting".to_string(), true); + + let disable_user_registration = get_disable_user_registration(&env); - let domain = "https://warden-worker.deepgauravraj.workers.dev"; Json(json!({ // Note: The clients use this version to handle backwards compatibility concerns // This means they expect a version that closely matches the Bitwarden server version @@ -31,7 +47,7 @@ pub async fn config() -> Json { "url": "https://github.com/dani-garcia/vaultwarden" }, "settings": { - "disableUserRegistration": true, + "disableUserRegistration": disable_user_registration, }, "environment": { "vault": domain, diff --git a/src/lib.rs b/src/lib.rs index 7bf3e20..b464b1a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +use axum::Extension; use tower_http::cors::{Any, CorsLayer}; use tower_service::Service; use worker::*; @@ -10,6 +11,10 @@ mod handlers; mod models; mod router; +/// Base URL extracted from the incoming request, used for config endpoint. +#[derive(Clone)] +pub struct BaseUrl(pub String); + #[event(fetch)] pub async fn main( req: HttpRequest, @@ -20,6 +25,14 @@ pub async fn main( console_error_panic_hook::set_once(); let _ = console_log::init_with_level(log::Level::Debug); + // Extract base URL from request URI + let uri = req.uri(); + let base_url = format!( + "{}://{}", + uri.scheme_str().unwrap_or("https"), + uri.authority().map(|a| a.as_str()).unwrap_or("localhost") + ); + // Ensure database schema is up to date (adds password_salt column if missing) db::ensure_schema(&env).await; @@ -29,7 +42,9 @@ pub async fn main( .allow_headers(Any) .allow_origin(Any); - let mut app = router::api_router(env).layer(cors); + let mut app = router::api_router(env) + .layer(Extension(BaseUrl(base_url))) + .layer(cors); Ok(app.call(req).await?) }