From acc1474394e430a45ab6d3cde2455c6165b02b30 Mon Sep 17 00:00:00 2001 From: BlackDex Date: Wed, 11 Jan 2023 21:45:11 +0100 Subject: [PATCH] Add avatar color support The new web-vault v2023.1.0 supports a custom color for the avatar. https://github.com/bitwarden/server/pull/2330 This PR adds this feature. --- .../down.sql | 0 .../2023-01-11-205851_add_avatar_color/up.sql | 2 ++ .../down.sql | 0 .../2023-01-11-205851_add_avatar_color/up.sql | 2 ++ .../down.sql | 0 .../2023-01-11-205851_add_avatar_color/up.sql | 2 ++ src/api/core/accounts.rs | 27 +++++++++++++++++++ src/db/models/user.rs | 5 ++++ src/db/schemas/mysql/schema.rs | 1 + src/db/schemas/postgresql/schema.rs | 1 + src/db/schemas/sqlite/schema.rs | 1 + src/main.rs | 2 +- 12 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 migrations/mysql/2023-01-11-205851_add_avatar_color/down.sql create mode 100644 migrations/mysql/2023-01-11-205851_add_avatar_color/up.sql create mode 100644 migrations/postgresql/2023-01-11-205851_add_avatar_color/down.sql create mode 100644 migrations/postgresql/2023-01-11-205851_add_avatar_color/up.sql create mode 100644 migrations/sqlite/2023-01-11-205851_add_avatar_color/down.sql create mode 100644 migrations/sqlite/2023-01-11-205851_add_avatar_color/up.sql diff --git a/migrations/mysql/2023-01-11-205851_add_avatar_color/down.sql b/migrations/mysql/2023-01-11-205851_add_avatar_color/down.sql new file mode 100644 index 00000000..e69de29b diff --git a/migrations/mysql/2023-01-11-205851_add_avatar_color/up.sql b/migrations/mysql/2023-01-11-205851_add_avatar_color/up.sql new file mode 100644 index 00000000..8f8e7205 --- /dev/null +++ b/migrations/mysql/2023-01-11-205851_add_avatar_color/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE users +ADD COLUMN avatar_color VARCHAR(7); diff --git a/migrations/postgresql/2023-01-11-205851_add_avatar_color/down.sql b/migrations/postgresql/2023-01-11-205851_add_avatar_color/down.sql new file mode 100644 index 00000000..e69de29b diff --git a/migrations/postgresql/2023-01-11-205851_add_avatar_color/up.sql b/migrations/postgresql/2023-01-11-205851_add_avatar_color/up.sql new file mode 100644 index 00000000..cf3ef9f7 --- /dev/null +++ b/migrations/postgresql/2023-01-11-205851_add_avatar_color/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE users +ADD COLUMN avatar_color TEXT; diff --git a/migrations/sqlite/2023-01-11-205851_add_avatar_color/down.sql b/migrations/sqlite/2023-01-11-205851_add_avatar_color/down.sql new file mode 100644 index 00000000..e69de29b diff --git a/migrations/sqlite/2023-01-11-205851_add_avatar_color/up.sql b/migrations/sqlite/2023-01-11-205851_add_avatar_color/up.sql new file mode 100644 index 00000000..cf3ef9f7 --- /dev/null +++ b/migrations/sqlite/2023-01-11-205851_add_avatar_color/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE users +ADD COLUMN avatar_color TEXT; diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index 1f932f69..758d9028 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -39,6 +39,7 @@ pub fn routes() -> Vec { api_key, rotate_api_key, get_known_device, + put_avatar, ] } @@ -228,6 +229,32 @@ async fn post_profile(data: JsonUpcase, headers: Headers, mut conn: Ok(Json(user.to_json(&mut conn).await)) } +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct AvatarData { + AvatarColor: Option, +} + +#[put("/accounts/avatar", data = "")] +async fn put_avatar(data: JsonUpcase, headers: Headers, mut conn: DbConn) -> JsonResult { + let data: AvatarData = data.into_inner().data; + + // It looks like it only supports the 6 hex color format. + // If you try to add the short value it will not show that color. + // Check and force 7 chars, including the #. + if let Some(color) = &data.AvatarColor { + if color.len() != 7 { + err!("The field AvatarColor must be a HTML/Hex color code with a length of 7 characters") + } + } + + let mut user = headers.user; + user.avatar_color = data.AvatarColor; + + user.save(&mut conn).await?; + Ok(Json(user.to_json(&mut conn).await)) +} + #[get("/users//public-key")] async fn get_public_keys(uuid: String, _headers: Headers, mut conn: DbConn) -> JsonResult { let user = match User::find_by_uuid(&uuid, &mut conn).await { diff --git a/src/db/models/user.rs b/src/db/models/user.rs index b59f10b8..611c4ebb 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -46,6 +46,8 @@ db_object! { pub client_kdf_iter: i32, pub api_key: Option, + + pub avatar_color: Option, } #[derive(Identifiable, Queryable, Insertable)] @@ -113,6 +115,8 @@ impl User { client_kdf_iter: Self::CLIENT_KDF_ITER_DEFAULT, api_key: None, + + avatar_color: None, } } @@ -226,6 +230,7 @@ impl User { "Providers": [], "ProviderOrganizations": [], "ForcePasswordReset": false, + "AvatarColor": self.avatar_color, "Object": "profile", }) } diff --git a/src/db/schemas/mysql/schema.rs b/src/db/schemas/mysql/schema.rs index 0073a9d5..27cd24c3 100644 --- a/src/db/schemas/mysql/schema.rs +++ b/src/db/schemas/mysql/schema.rs @@ -200,6 +200,7 @@ table! { client_kdf_type -> Integer, client_kdf_iter -> Integer, api_key -> Nullable, + avatar_color -> Nullable, } } diff --git a/src/db/schemas/postgresql/schema.rs b/src/db/schemas/postgresql/schema.rs index 1421513c..0233e0c9 100644 --- a/src/db/schemas/postgresql/schema.rs +++ b/src/db/schemas/postgresql/schema.rs @@ -200,6 +200,7 @@ table! { client_kdf_type -> Integer, client_kdf_iter -> Integer, api_key -> Nullable, + avatar_color -> Nullable, } } diff --git a/src/db/schemas/sqlite/schema.rs b/src/db/schemas/sqlite/schema.rs index 0fedcf1d..391e6700 100644 --- a/src/db/schemas/sqlite/schema.rs +++ b/src/db/schemas/sqlite/schema.rs @@ -200,6 +200,7 @@ table! { client_kdf_type -> Integer, client_kdf_iter -> Integer, api_key -> Nullable, + avatar_color -> Nullable, } } diff --git a/src/main.rs b/src/main.rs index 8a5f53da..3c648231 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,7 @@ // The more key/value pairs there are the more recursion occurs. // We want to keep this as low as possible, but not higher then 128. // If you go above 128 it will cause rust-analyzer to fail, -#![recursion_limit = "94"] +#![recursion_limit = "97"] // When enabled use MiMalloc as malloc instead of the default malloc #[cfg(feature = "enable_mimalloc")]