This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
/result
|
/result
|
||||||
/uploads
|
/uploads
|
||||||
|
*.swp
|
||||||
|
|||||||
+4
-4
@@ -24,7 +24,7 @@ pub fn hash_password(password: &str) -> Result<String, APIError> {
|
|||||||
.hash_password(password.as_bytes(), &salt)
|
.hash_password(password.as_bytes(), &salt)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
.map(|ph| ph.to_string())
|
.map(|ph| ph.to_string())
|
||||||
.map_err(|e| APIError::Internal(e))
|
.map_err(APIError::Internal)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_password(hash: &str, password: &str) -> bool {
|
pub fn verify_password(hash: &str, password: &str) -> bool {
|
||||||
@@ -67,15 +67,15 @@ pub fn verify_jwt(headers: HeaderMap) -> Result<Claims, APIError> {
|
|||||||
.and_then(|s| s.strip_prefix("Bearer "))
|
.and_then(|s| s.strip_prefix("Bearer "))
|
||||||
.ok_or(APIError::MissingToken)?;
|
.ok_or(APIError::MissingToken)?;
|
||||||
|
|
||||||
verify_jwt_string(&token.to_string())
|
verify_jwt_string(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_jwt_string(token: &String) -> Result<Claims, APIError> {
|
pub fn verify_jwt_string(token: &str) -> Result<Claims, APIError> {
|
||||||
let secret =
|
let secret =
|
||||||
std::env::var("FRANGIPANE_JWT_SECRET").unwrap_or_else(|_| DEFAULT_SECRET_KEY.to_string());
|
std::env::var("FRANGIPANE_JWT_SECRET").unwrap_or_else(|_| DEFAULT_SECRET_KEY.to_string());
|
||||||
|
|
||||||
decode::<Claims>(
|
decode::<Claims>(
|
||||||
token.as_str(),
|
token,
|
||||||
&DecodingKey::from_secret(secret.as_ref()),
|
&DecodingKey::from_secret(secret.as_ref()),
|
||||||
&Validation::default(),
|
&Validation::default(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ impl RealtimeMessages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for RealtimeMessages {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RealTimeVoices {
|
impl RealTimeVoices {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -63,3 +69,9 @@ impl RealTimeVoices {
|
|||||||
self.rooms.retain(|_, sender| sender.receiver_count() > 0);
|
self.rooms.retain(|_, sender| sender.receiver_count() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for RealTimeVoices {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+18
-14
@@ -171,14 +171,14 @@ async fn create_message(
|
|||||||
.bind(room_id)
|
.bind(room_id)
|
||||||
.bind(&payload.message_type)
|
.bind(&payload.message_type)
|
||||||
.bind(&payload.content)
|
.bind(&payload.content)
|
||||||
.bind(&uuid)
|
.bind(uuid)
|
||||||
.fetch_one(&db)
|
.fetch_one(&db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let sender_name = username_from_uuid(&db, claims.sub).await?;
|
let sender_name = username_from_uuid(&db, claims.sub).await?;
|
||||||
|
|
||||||
let message = Message {
|
let message = Message {
|
||||||
uuid: uuid,
|
uuid,
|
||||||
room_uuid,
|
room_uuid,
|
||||||
sender: sender_name,
|
sender: sender_name,
|
||||||
sender_uuid: claims.sub,
|
sender_uuid: claims.sub,
|
||||||
@@ -263,12 +263,12 @@ async fn handle_message_socket(
|
|||||||
// Receive broadcast messages and send to client (any room)
|
// Receive broadcast messages and send to client (any room)
|
||||||
msg = receiver.recv() => {
|
msg = receiver.recv() => {
|
||||||
if let Ok(msg) = msg {
|
if let Ok(msg) = msg {
|
||||||
if let Ok(json) = serde_json::to_string(&msg) {
|
if let Ok(json) = serde_json::to_string(&msg)
|
||||||
if socket.send(WsMessage::Text(json.into())).await.is_err() {
|
&& socket.send(WsMessage::Text(json.into())).await.is_err()
|
||||||
|
{
|
||||||
tracing::error!("Failed to send message to {who}, closing connection");
|
tracing::error!("Failed to send message to {who}, closing connection");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -287,20 +287,24 @@ async fn handle_message_socket(
|
|||||||
// Get incoming messages from client
|
// Get incoming messages from client
|
||||||
client_msg = socket.recv() => {
|
client_msg = socket.recv() => {
|
||||||
if let Some(Ok(msg)) = client_msg {
|
if let Some(Ok(msg)) = client_msg {
|
||||||
match msg {
|
// match msg {
|
||||||
// WsMessage::Pong(_) => {
|
// // WsMessage::Pong(_) => {
|
||||||
// tracing::debug!("Received Pong from {who}");
|
// // tracing::debug!("Received Pong from {who}");
|
||||||
|
// // }
|
||||||
|
// // WsMessage::Ping(_) => {
|
||||||
|
// // tracing::info!("Received Ping from client");
|
||||||
|
// // }
|
||||||
|
// // WsMessage::Text(_) => {}
|
||||||
|
// WsMessage::Close(_) => {
|
||||||
|
// tracing::debug!("Client disconnected");
|
||||||
|
// break;
|
||||||
// }
|
// }
|
||||||
// WsMessage::Ping(_) => {
|
// _ => {}
|
||||||
// tracing::info!("Received Ping from client");
|
|
||||||
// }
|
// }
|
||||||
// WsMessage::Text(_) => {}
|
if let WsMessage::Close(_) = msg {
|
||||||
WsMessage::Close(_) => {
|
|
||||||
tracing::debug!("Client disconnected");
|
tracing::debug!("Client disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!("Client {who} abruptly disconnected");
|
tracing::debug!("Client {who} abruptly disconnected");
|
||||||
break;
|
break;
|
||||||
|
|||||||
+2
-4
@@ -95,9 +95,6 @@ async fn list_rooms(
|
|||||||
Extension(db): Extension<PgPool>,
|
Extension(db): Extension<PgPool>,
|
||||||
) -> Result<Json<Vec<Room>>, APIError> {
|
) -> Result<Json<Vec<Room>>, APIError> {
|
||||||
let claims = verify_jwt(headers)?;
|
let claims = verify_jwt(headers)?;
|
||||||
if claims.sub != claims.sub {
|
|
||||||
return Err(APIError::InvalidToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||||
|
|
||||||
@@ -142,7 +139,8 @@ async fn create_room(
|
|||||||
|
|
||||||
{
|
{
|
||||||
let room_name_length = payload.name.len();
|
let room_name_length = payload.name.len();
|
||||||
if room_name_length > MAX_ROOM_NAME_LENGTH || room_name_length < 1 {
|
// if room_name_length > MAX_ROOM_NAME_LENGTH || room_name_length < 1 {
|
||||||
|
if !(1..=MAX_ROOM_NAME_LENGTH).contains(&room_name_length) {
|
||||||
return Err(APIError::RoomNameLength);
|
return Err(APIError::RoomNameLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-7
@@ -137,7 +137,8 @@ pub async fn register_user(
|
|||||||
|
|
||||||
{
|
{
|
||||||
let username_length = payload.username.len();
|
let username_length = payload.username.len();
|
||||||
if username_length > MAX_USERNAME_LENGTH || username_length < 1 {
|
// if username_length > MAX_USERNAME_LENGTH || username_length < 1 {
|
||||||
|
if !(1..MAX_USERNAME_LENGTH).contains(&username_length) {
|
||||||
return Err(APIError::UsernameLength);
|
return Err(APIError::UsernameLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,15 +162,15 @@ pub async fn register_user(
|
|||||||
.execute(&db)
|
.execute(&db)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
if let Some(db_err) = e.as_database_error() {
|
if let Some(db_err) = e.as_database_error()
|
||||||
if db_err.code().map(|c| c == "23505").unwrap_or(false) {
|
&& db_err.code().map(|c| c == "23505").unwrap_or(false)
|
||||||
|
{
|
||||||
match db_err.constraint() {
|
match db_err.constraint() {
|
||||||
Some("user__username_key") => return APIError::UsernameTaken,
|
Some("user__username_key") => return APIError::UsernameTaken,
|
||||||
Some("user__email_key") => return APIError::EmailTaken,
|
Some("user__email_key") => return APIError::EmailTaken,
|
||||||
_ => return APIError::Internal("".to_string()), // TODO: handle this case
|
_ => return APIError::Internal("".to_string()), // TODO: handle this case
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
APIError::DatabaseError(e)
|
APIError::DatabaseError(e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -226,15 +227,15 @@ pub async fn update_user(
|
|||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
if let Some(db_err) = e.as_database_error() {
|
if let Some(db_err) = e.as_database_error()
|
||||||
if db_err.code().map(|c| c == "23505").unwrap_or(false) {
|
&& db_err.code().map(|c| c == "23505").unwrap_or(false)
|
||||||
|
{
|
||||||
match db_err.constraint() {
|
match db_err.constraint() {
|
||||||
Some("user__username_key") => return APIError::UsernameTaken,
|
Some("user__username_key") => return APIError::UsernameTaken,
|
||||||
Some("user__email_key") => return APIError::EmailTaken,
|
Some("user__email_key") => return APIError::EmailTaken,
|
||||||
_ => return APIError::Internal("".to_string()), // TODO: handle this case
|
_ => return APIError::Internal("".to_string()), // TODO: handle this case
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
APIError::DatabaseError(e)
|
APIError::DatabaseError(e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -81,25 +81,25 @@ async fn handle_voice_socket(
|
|||||||
select! {
|
select! {
|
||||||
// Receive audio from other users and send to client
|
// Receive audio from other users and send to client
|
||||||
voice_packet = rx.recv() => {
|
voice_packet = rx.recv() => {
|
||||||
if let Ok((speaker_uuid, audio_data)) = voice_packet {
|
if let Ok((speaker_uuid, audio_data)) = voice_packet
|
||||||
if speaker_uuid != my_uuid {
|
&& speaker_uuid != my_uuid
|
||||||
|
{
|
||||||
let mut msg = BytesMut::with_capacity(16 + audio_data.len());
|
let mut msg = BytesMut::with_capacity(16 + audio_data.len());
|
||||||
msg.put(speaker_uuid.as_bytes().as_slice());
|
msg.put(speaker_uuid.as_bytes().as_slice());
|
||||||
msg.put(audio_data);
|
msg.put(audio_data);
|
||||||
|
|
||||||
if socket.send(Message::Binary(msg.freeze().into())).await.is_err() {
|
if socket.send(Message::Binary(msg.freeze())).await.is_err() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Receive audio from alient and broadcast to room
|
// Receive audio from alient and broadcast to room
|
||||||
client_msg = socket.recv() => {
|
client_msg = socket.recv() => {
|
||||||
if let Some(Ok(msg)) = client_msg {
|
if let Some(Ok(msg)) = client_msg {
|
||||||
match msg {
|
match msg {
|
||||||
Message::Binary(data) => {
|
Message::Binary(data) => {
|
||||||
let _ = tx.send((my_uuid, Bytes::from(data)));
|
let _ = tx.send((my_uuid, data));
|
||||||
}
|
}
|
||||||
Message::Close(_) => {
|
Message::Close(_) => {
|
||||||
tracing::debug!("Voice client {} disconnected", who);
|
tracing::debug!("Voice client {} disconnected", who);
|
||||||
|
|||||||
Reference in New Issue
Block a user