Skip to content

Commit

Permalink
Allow customizing the featureStates (#4168)
Browse files Browse the repository at this point in the history
* Allow customizing the featureStates

Use a comma separated list of features to enable using the FEATURE_FLAGS env variable

* Move feature flag parsing to util

* Fix formatting

* Update supported feature flags

* Rename feature_flags to experimental_client_feature_flags

Additionally, use a caret (^) instead of an exclamation mark (!) to disable features

* Fix formatting issue.

* Add documentation to env template

* Remove functionality to disable feature flags

* Fix JSON key for feature states

* Convert error to warning when feature flag is unrecognized

* Simplify parsing of feature flags

* Fix default value of feature flags in env template

* Fix formatting
  • Loading branch information
PKizzle authored Jan 1, 2024
1 parent 76a3f0f commit 98b2178
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 11 deletions.
11 changes: 11 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,17 @@
## In any case, if a code has been used it can not be used again, also codes which predates it will be invalid.
# AUTHENTICATOR_DISABLE_TIME_DRIFT=false

## Client Settings
## Enable experimental feature flags for clients.
## This is a comma-separated list of flags, e.g. "flag1,flag2,flag3".
##
## The following flags are available:
## - "autofill-overlay": Add an overlay menu to form fields for quick access to credentials.
## - "autofill-v2": Use the new autofill implementation.
## - "browser-fileless-import": Directly import credentials from other providers without a file.
## - "fido2-vault-credentials": Enable the use of FIDO2 security keys as second factor.
## EXPERIMENTAL_CLIENT_FEATURE_FLAGS=fido2-vault-credentials

## Rocket specific settings
## See https://rocket.rs/v0.4/guide/configuration/ for more details.
# ROCKET_ADDRESS=0.0.0.0
Expand Down
14 changes: 4 additions & 10 deletions src/api/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,14 @@ pub fn events_routes() -> Vec<Route> {
//
// Move this somewhere else
//
use rocket::{serde::json::Json, Catcher, Route};
use serde_json::Value;
use rocket::{serde::json::Json, serde::json::Value, Catcher, Route};

use crate::{
api::{JsonResult, JsonUpcase, Notify, UpdateType},
auth::Headers,
db::DbConn,
error::Error,
util::get_reqwest_client,
util::{get_reqwest_client, parse_experimental_client_feature_flags},
};

#[derive(Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -192,6 +191,7 @@ fn version() -> Json<&'static str> {
#[get("/config")]
fn config() -> Json<Value> {
let domain = crate::CONFIG.domain();
let feature_states = parse_experimental_client_feature_flags(&crate::CONFIG.experimental_client_feature_flags());
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
Expand All @@ -212,13 +212,7 @@ fn config() -> Json<Value> {
"notifications": format!("{domain}/notifications"),
"sso": "",
},
"featureStates": {
// Any feature flags that we want the clients to use
// Can check the enabled ones at:
// https://vault.bitwarden.com/api/config
"fido2-vault-credentials": true, // Passkey support
"autofill-v2": false, // Disabled because it is causing issues https://github.com/dani-garcia/vaultwarden/discussions/4052
},
"featureStates": feature_states,
"object": "config",
}))
}
Expand Down
13 changes: 12 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use reqwest::Url;
use crate::{
db::DbConnType,
error::Error,
util::{get_env, get_env_bool},
util::{get_env, get_env_bool, parse_experimental_client_feature_flags},
};

static CONFIG_FILE: Lazy<String> = Lazy::new(|| {
Expand Down Expand Up @@ -547,6 +547,9 @@ make_config! {
/// TOTP codes of the previous and next 30 seconds will be invalid.
authenticator_disable_time_drift: bool, true, def, false;

/// Customize the enabled feature flags on the clients |> This is a comma separated list of feature flags to enable.
experimental_client_feature_flags: String, false, def, "fido2-vault-credentials".to_string();

/// Require new device emails |> When a user logs in an email is required to be sent.
/// If sending the email fails the login attempt will fail.
require_device_email: bool, true, def, false;
Expand Down Expand Up @@ -751,6 +754,14 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
)
}

const KNOWN_FLAGS: &[&str] =
&["autofill-overlay", "autofill-v2", "browser-fileless-import", "fido2-vault-credentials"];
for flag in parse_experimental_client_feature_flags(&cfg.experimental_client_feature_flags).keys() {
if !KNOWN_FLAGS.contains(&flag.as_str()) {
warn!("The experimental client feature flag {flag:?} is unrecognized. Please ensure the feature flag is spelled correctly and that it is supported in this version.");
}
}

if cfg._enable_duo
&& (cfg.duo_host.is_some() || cfg.duo_ikey.is_some() || cfg.duo_skey.is_some())
&& !(cfg.duo_host.is_some() && cfg.duo_ikey.is_some() && cfg.duo_skey.is_some())
Expand Down
9 changes: 9 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Web Headers and caching
//
use std::{
collections::HashMap,
io::{Cursor, ErrorKind},
ops::Deref,
};
Expand Down Expand Up @@ -747,3 +748,11 @@ pub fn convert_json_key_lcase_first(src_json: Value) -> Value {
value => value,
}
}

/// Parses the experimental client feature flags string into a HashMap.
pub fn parse_experimental_client_feature_flags(experimental_client_feature_flags: &str) -> HashMap<String, bool> {
let feature_states =
experimental_client_feature_flags.to_lowercase().split(',').map(|f| (f.trim().to_owned(), true)).collect();

feature_states
}

0 comments on commit 98b2178

Please sign in to comment.