diff --git a/Cargo.lock b/Cargo.lock index e5d06758..0c6d9570 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1995,9 +1995,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "opaque-debug" @@ -2792,6 +2792,7 @@ dependencies = [ "nanoid", "num_enum", "okapi", + "once_cell", "optional_struct", "pretty_env_logger", "rauth", diff --git a/crates/delta/src/routes/servers/roles_edit.rs b/crates/delta/src/routes/servers/roles_edit.rs index 39422e86..71fd6cb7 100644 --- a/crates/delta/src/routes/servers/roles_edit.rs +++ b/crates/delta/src/routes/servers/roles_edit.rs @@ -3,7 +3,9 @@ use revolt_quark::{ server::{FieldsRole, PartialRole, Role}, User, }, - perms, Db, Error, Permission, Ref, Result, + perms, + util::regex::RE_COLOUR, + Db, Error, Permission, Ref, Result, }; use rocket::serde::json::Json; @@ -17,7 +19,7 @@ pub struct DataEditRole { #[validate(length(min = 1, max = 32))] name: Option, /// Role colour - #[validate(length(min = 1, max = 32))] + #[validate(length(min = 1, max = 128), regex = "RE_COLOUR")] colour: Option, /// Whether this role should be displayed separately hoist: Option, diff --git a/crates/quark/Cargo.toml b/crates/quark/Cargo.toml index 86b6fd8e..b8e33148 100644 --- a/crates/quark/Cargo.toml +++ b/crates/quark/Cargo.toml @@ -68,6 +68,7 @@ impl_ops = "0.1.1" num_enum = "0.5.6" reqwest = "0.11.10" bitfield = "0.13.2" +once_cell = "1.13.0" lazy_static = "1.4.0" lru = { version = "0.7.6", optional = true } diff --git a/crates/quark/src/models/channels/message.rs b/crates/quark/src/models/channels/message.rs index 93f0d007..e5ed7172 100644 --- a/crates/quark/src/models/channels/message.rs +++ b/crates/quark/src/models/channels/message.rs @@ -1,3 +1,5 @@ +use crate::util::regex::RE_COLOUR; + use serde::{Deserialize, Serialize}; use validator::Validate; @@ -33,7 +35,7 @@ pub struct SendableEmbed { #[validate(length(min = 1, max = 2000))] pub description: Option, pub media: Option, - #[validate(length(min = 1, max = 64))] + #[validate(length(min = 1, max = 128), regex = "RE_COLOUR")] pub colour: Option, } diff --git a/crates/quark/src/util/mod.rs b/crates/quark/src/util/mod.rs index cd623b05..bb83ded1 100644 --- a/crates/quark/src/util/mod.rs +++ b/crates/quark/src/util/mod.rs @@ -3,6 +3,7 @@ pub mod manipulation; pub mod pfp; pub mod rauth; pub mod r#ref; +pub mod regex; pub mod result; pub mod value; pub mod variables; diff --git a/crates/quark/src/util/regex.rs b/crates/quark/src/util/regex.rs new file mode 100644 index 00000000..93aad99f --- /dev/null +++ b/crates/quark/src/util/regex.rs @@ -0,0 +1,18 @@ +use once_cell::sync::Lazy; +use regex::Regex; + +/// Regex for valid role colours +/// +/// Allows the use of named colours, rgb(a), variables and all gradients. +/// +/// Source: +/// ```regex +/// VALUE = [a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+ +/// ADDITIONAL_VALUE = \d+deg +/// STOP = ([ ]+(\d{1,3}%|0))? +/// +/// ^(?:VALUE|(repeating-)?(linear|conic|radial)-gradient\((VALUE|ADDITIONAL_VALUE)STOP(,[ ]*(VALUE)STOP)+\))$ +/// ``` +pub static RE_COLOUR: Lazy = Lazy::new(|| { + Regex::new(r"^(?:[a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|(repeating-)?(linear|conic|radial)-gradient\(([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|\d+deg)([ ]+(\d{1,3}%|0))?(,[ ]*([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+)([ ]+(\d{1,3}%|0))?)+\))$").unwrap() +});