From 9c3b190373ce7636d782a73966183409adbe1788 Mon Sep 17 00:00:00 2001 From: Jacobtread Date: Wed, 3 Jul 2024 10:23:45 +1200 Subject: [PATCH] feat: system messages are now divide using newlines This way older clients will still be able to see a plain text version rather than a JSON payload if they don't support it. Server divides the payload using new lines which hides the parts after a newline --- src/routes/auth.rs | 65 ++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/routes/auth.rs b/src/routes/auth.rs index 56562de..8ded174 100644 --- a/src/routes/auth.rs +++ b/src/routes/auth.rs @@ -1,7 +1,14 @@ use std::sync::Arc; use crate::{ - config::RuntimeConfig, database::entities::{Player, PlayerRole}, services::sessions::Sessions, session::{models::messaging::MessageNotify, packet::Packet}, utils::{components::messaging, hashing::{hash_password, verify_password}} + config::RuntimeConfig, + database::entities::{Player, PlayerRole}, + services::sessions::Sessions, + session::{models::messaging::MessageNotify, packet::Packet}, + utils::{ + components::messaging, + hashing::{hash_password, verify_password}, + }, }; use axum::{ http::StatusCode, @@ -50,11 +57,11 @@ pub enum AuthError { /// Session is not active #[error("This player is not currently connected, please connect to the server and visit the main menu in-game before attempting this action.")] SessionNotActive, - + /// Failed to create login code #[error("Failed to generate login code")] FailedGenerateCode, - + /// Failed to create login code #[error("The provided login code was incorrect")] InvalidCode, @@ -162,7 +169,6 @@ pub async fn create( Ok(Json(TokenResponse { token })) } - /// Request structure for requesting a login code #[derive(Deserialize)] pub struct RequestLoginCodeRequest { @@ -171,7 +177,7 @@ pub struct RequestLoginCodeRequest { } /// POST /api/auth/request-code -/// +/// /// Requests a login code be sent to a active session to be used /// for logging in without a password pub async fn handle_request_login_code( @@ -190,23 +196,33 @@ pub async fn handle_request_login_code( .ok_or(AuthError::SessionNotActive)?; // Generate the login code - let login_code = sessions.create_login_code(player.id).map_err(|_|AuthError::FailedGenerateCode)?; + let login_code = sessions + .create_login_code(player.id) + .map_err(|_| AuthError::FailedGenerateCode)?; + + let small_message = + format!("Login confirmation code: {login_code}"); + let full_message = format!("Your login confirmation code is {login_code}, enter this on the dashboard to login"); // Create and serialize the message let origin_message = serde_json::to_string(&SystemMessage { - title : "Login Confirmation Code".to_string(), - message: format!("Your login confirmation code is {login_code}, enter this on the dashboard to login"), + title: "Login Confirmation Code".to_string(), + message: full_message, image: "".to_string(), - ty:0, + ty: 0, tracking_id: -1, - priority: 1 - }).map_err(|_|AuthError::FailedGenerateCode)?; - + priority: 1, + }) + .map_err(|_| AuthError::FailedGenerateCode)?; + + // Craft the payload with new lines so outdated clients don't see the JSON + let game_message = format!("{small_message}\n[SYSTEM_TERMINAL]{origin_message}\n"); + let notify_origin = Packet::notify( messaging::COMPONENT, messaging::SEND_MESSAGE, MessageNotify { - message: format!("[SYSTEM_TERMINAL]{origin_message}"), + message: game_message, player_id: player.id, }, ); @@ -214,7 +230,6 @@ pub async fn handle_request_login_code( // Send the message session.notify_handle().notify(notify_origin); - Ok(StatusCode::OK) } @@ -236,30 +251,34 @@ pub struct RequestExchangeLoginCode { } /// POST /api/auth/exchange-code -/// +/// /// Requests a login code be sent to a active session to be used /// for logging in without a password pub async fn handle_exchange_login_code( Extension(sessions): Extension>, Json(RequestExchangeLoginCode { login_code }): Json, -) -> AuthRes { - +) -> AuthRes { // Exchange the code for a token - let token = sessions.exchange_login_code(&login_code).ok_or(AuthError::InvalidCode)?; + let token = sessions + .exchange_login_code(&login_code) + .ok_or(AuthError::InvalidCode)?; Ok(Json(TokenResponse { token })) } - /// Response implementation for auth errors impl IntoResponse for AuthError { fn into_response(self) -> Response { let status_code = match &self { - Self::Database(_) | Self::PasswordHash(_) | Self::FailedGenerateCode => StatusCode::INTERNAL_SERVER_ERROR, - Self::InvalidCredentials | Self::OriginAccess => StatusCode::UNAUTHORIZED, - Self::EmailTaken | Self::InvalidUsername | Self::SessionNotActive | Self::NoMatchingAccount | Self::InvalidCode => { - StatusCode::BAD_REQUEST + Self::Database(_) | Self::PasswordHash(_) | Self::FailedGenerateCode => { + StatusCode::INTERNAL_SERVER_ERROR } + Self::InvalidCredentials | Self::OriginAccess => StatusCode::UNAUTHORIZED, + Self::EmailTaken + | Self::InvalidUsername + | Self::SessionNotActive + | Self::NoMatchingAccount + | Self::InvalidCode => StatusCode::BAD_REQUEST, Self::RegistrationDisabled => StatusCode::FORBIDDEN, };