Add temporary typing indicator impl.

This commit is contained in:
Paul
2021-02-19 14:50:23 +00:00
parent dadad271b4
commit 3c7852271a
4 changed files with 88 additions and 27 deletions

View File

@@ -1,6 +1,11 @@
use mongodb::bson::doc;
use serde::{Deserialize, Serialize};
use mongodb::options::{Collation, FindOneOptions};
use crate::{database::permissions::user::UserPermissions, notifications::websocket::is_online};
use crate::database::*;
use crate::util::result::{Error, Result};
use crate::notifications::websocket::is_online;
use crate::database::permissions::user::UserPermissions;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum RelationshipStatus {
@@ -62,4 +67,32 @@ impl User {
self
}
/// Utility function for checking claimed usernames.
pub async fn is_username_taken(username: &str) -> Result<bool> {
if username == "revolt" && username == "admin" {
return Ok(true)
}
if get_collection("users")
.find_one(
doc! {
"username": username
},
FindOneOptions::builder()
.collation(Collation::builder().locale("en").strength(2).build())
.build(),
)
.await
.map_err(|_| Error::DatabaseError {
operation: "find_one",
with: "user",
})?
.is_some()
{
Ok(true)
} else {
Ok(false)
}
}
}

View File

@@ -26,6 +26,12 @@ pub enum WebSocketError {
#[serde(tag = "type")]
pub enum ServerboundNotification {
Authenticate(Session),
BeginTyping {
channel: String
},
EndTyping {
channel: String
}
}
#[derive(Serialize, Deserialize, Debug)]
@@ -63,6 +69,14 @@ pub enum ClientboundNotification {
ChannelDelete {
id: String,
},
ChannelStartTyping {
id: String,
user: String
},
ChannelStopTyping {
id: String,
user: String
},
UserRelationship {
id: String,

View File

@@ -71,8 +71,6 @@ async fn accept(stream: TcpStream) {
let fwd = rx.map(Ok).forward(write);
let incoming = read.try_for_each(async move |msg| {
let mutex = mutex_generator();
//dbg!(&mutex.lock().unwrap());
if let Message::Text(text) = msg {
if let Ok(notification) = serde_json::from_str::<ServerboundNotification>(&text) {
match notification {
@@ -161,6 +159,43 @@ async fn accept(stream: TcpStream) {
));
}
}
// ! TEMP: verify user part of channel
// ! Could just run permission check here.
ServerboundNotification::BeginTyping { channel } => {
if mutex.lock().unwrap().is_some() {
ClientboundNotification::ChannelStartTyping {
id: channel.clone(),
// lol
user: mutex.lock().as_ref().unwrap().as_ref().unwrap().user_id.clone()
}
.publish(channel)
.await
.ok();
} else {
send(ClientboundNotification::Error(
WebSocketError::AlreadyAuthenticated,
));
return Ok(());
}
}
ServerboundNotification::EndTyping { channel } => {
if mutex.lock().unwrap().is_some() {
ClientboundNotification::ChannelStopTyping {
id: channel.clone(),
user: mutex.lock().as_ref().unwrap().as_ref().unwrap().user_id.clone()
}
.publish(channel)
.await
.ok();
} else {
send(ClientboundNotification::Error(
WebSocketError::AlreadyAuthenticated,
));
return Ok(());
}
}
}
}
}

View File

@@ -2,7 +2,6 @@ use crate::database::*;
use crate::util::result::{Error, Result};
use mongodb::bson::doc;
use mongodb::options::{Collation, FindOneOptions};
use rauth::auth::Session;
use regex::Regex;
use rocket_contrib::json::Json;
@@ -28,31 +27,11 @@ pub async fn req(session: Session, user: Option<User>, data: Json<Data>) -> Resu
data.validate()
.map_err(|error| Error::FailedValidation { error })?;
if data.username == "revolt" {
Err(Error::UsernameTaken)?
if User::is_username_taken(&data.username).await? {
return Err(Error::UsernameTaken)
}
let col = get_collection("users");
if col
.find_one(
doc! {
"username": &data.username
},
FindOneOptions::builder()
.collation(Collation::builder().locale("en").strength(2).build())
.build(),
)
.await
.map_err(|_| Error::DatabaseError {
operation: "find_one",
with: "user",
})?
.is_some()
{
Err(Error::UsernameTaken)?
}
col.insert_one(
get_collection("users").insert_one(
doc! {
"_id": session.user_id,
"username": &data.username