diff --git a/crates/delta/src/routes/onboard/complete.rs b/crates/delta/src/routes/onboard/complete.rs index b8388304..1098091b 100644 --- a/crates/delta/src/routes/onboard/complete.rs +++ b/crates/delta/src/routes/onboard/complete.rs @@ -32,13 +32,10 @@ pub async fn req( data.validate() .map_err(|error| Error::FailedValidation { error })?; - if db.is_username_taken(&data.username).await? { - return Err(Error::UsernameTaken); - } - + let username = User::validate_username(db, data.username).await?; let user = User { id: session.user_id, - username: data.username, + username, ..Default::default() }; diff --git a/crates/delta/src/util/regex.rs b/crates/delta/src/util/regex.rs index abe11520..d580db38 100644 --- a/crates/delta/src/util/regex.rs +++ b/crates/delta/src/util/regex.rs @@ -6,4 +6,4 @@ use regex::Regex; /// Block zero width space /// Block lookalike characters pub static RE_USERNAME: Lazy = - Lazy::new(|| Regex::new(r"^[^\u200BА-Яа-яΑ-Ωα-ω]+$").unwrap()); + Lazy::new(|| Regex::new(r"^[^\u200BА-Яа-яΑ-Ωα-ω@#:\n]+$").unwrap()); diff --git a/crates/quark/src/impl/generic/users/user.rs b/crates/quark/src/impl/generic/users/user.rs index e0e04aa6..1fea5b90 100644 --- a/crates/quark/src/impl/generic/users/user.rs +++ b/crates/quark/src/impl/generic/users/user.rs @@ -150,8 +150,8 @@ impl User { Ok(db.fetch_server_count(&self.id).await? <= 100) } - /// Update a user's username - pub async fn update_username(&mut self, db: &Database, username: String) -> Result<()> { + /// Sanitise and validate a username can be used + pub async fn validate_username(db: &Database, username: String) -> Result { // Trim surrounding spaces let username = username.trim().to_string(); @@ -173,7 +173,7 @@ impl User { } // Ensure none of the following substrings show up in the username - const BLOCKED_SUBSTRINGS: &[&str] = &["@", "#", ":", "```", "\n"]; + const BLOCKED_SUBSTRINGS: &[&str] = &["```"]; for substr in BLOCKED_SUBSTRINGS { if username_lowercase.contains(substr) { @@ -186,10 +186,15 @@ impl User { return Err(Error::UsernameTaken); } + Ok(username) + } + + /// Update a user's username + pub async fn update_username(&mut self, db: &Database, username: String) -> Result<()> { self.update( db, PartialUser { - username: Some(username), + username: Some(User::validate_username(db, username).await?), ..Default::default() }, vec![],