diff --git a/services/appflowy-collaborate/src/api.rs b/services/appflowy-collaborate/src/api.rs index 45cd94bf..36b6ba5c 100644 --- a/services/appflowy-collaborate/src/api.rs +++ b/services/appflowy-collaborate/src/api.rs @@ -18,6 +18,7 @@ use tokio_stream::StreamExt; use tracing::{debug, error, event, instrument, trace}; use app_error::AppError; +use authentication::jwt::{authorization_from_token, UserUuid}; use collab_rt_entity::user::{AFUserChange, RealtimeUser, UserMessage}; use collab_rt_entity::{HttpRealtimeMessage, RealtimeMessage}; use shared_entity::response::{AppResponse, AppResponseError}; @@ -31,7 +32,6 @@ use crate::compression::{ decompress, CompressionType, X_COMPRESSION_BUFFER_SIZE, X_COMPRESSION_TYPE, }; use crate::state::AppState; -use authentication::jwt::{authorization_from_token, UserUuid}; pub fn ws_scope() -> Scope { web::scope("/ws").service(web::resource("/v1").route(web::get().to(establish_ws_connection_v1))) @@ -76,6 +76,10 @@ pub async fn establish_ws_connection_v1( }, }; + if client_version < state.config.websocket.min_client_version { + return Err(AppError::Connect("Client version is too low".to_string()).into()); + } + start_connect( &request, payload, diff --git a/services/appflowy-collaborate/src/config.rs b/services/appflowy-collaborate/src/config.rs index fe807f62..a595f887 100644 --- a/services/appflowy-collaborate/src/config.rs +++ b/services/appflowy-collaborate/src/config.rs @@ -3,6 +3,7 @@ use std::str::FromStr; use anyhow::Context; use secrecy::Secret; +use semver::Version; use serde::Deserialize; use sqlx::postgres::{PgConnectOptions, PgSslMode}; @@ -70,6 +71,7 @@ impl AISettings { pub struct WebsocketSetting { pub heartbeat_interval: u8, pub client_timeout: u8, + pub min_client_version: Version, } #[derive(Clone, Debug)] @@ -140,6 +142,7 @@ pub fn get_configuration() -> Result { websocket: WebsocketSetting { heartbeat_interval: get_env_var("APPFLOWY_WEBSOCKET_HEARTBEAT_INTERVAL", "6").parse()?, client_timeout: get_env_var("APPFLOWY_WEBSOCKET_CLIENT_TIMEOUT", "60").parse()?, + min_client_version: get_env_var("APPFLOWY_WEBSOCKET_CLIENT_MIN_VERSION", "0.5.0").parse()?, }, db_settings: DatabaseSetting { pg_conn_opts: PgConnectOptions::from_str(&get_env_var( diff --git a/src/api/ws.rs b/src/api/ws.rs index 3372d7aa..d23b4e40 100644 --- a/src/api/ws.rs +++ b/src/api/ws.rs @@ -26,7 +26,7 @@ use crate::state::AppState; pub fn ws_scope() -> Scope { web::scope("/ws") - .service(establish_ws_connection) + //.service(establish_ws_connection) .service(web::resource("/v1").route(web::get().to(establish_ws_connection_v1))) } const MAX_FRAME_SIZE: usize = 65_536; // 64 KiB @@ -86,6 +86,10 @@ pub async fn establish_ws_connection_v1( }, }; + if client_version < state.config.websocket.min_client_version { + return Err(AppError::Connect("Client version is too low".to_string()).into()); + } + start_connect( &request, payload, diff --git a/src/config/config.rs b/src/config/config.rs index c0ad3fc1..349c8ec1 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -1,11 +1,14 @@ -use anyhow::Context; -use infra::env_util::get_env_var; -use secrecy::{ExposeSecret, Secret}; -use serde::Deserialize; -use sqlx::postgres::{PgConnectOptions, PgSslMode}; use std::fmt::Display; use std::str::FromStr; +use anyhow::Context; +use secrecy::{ExposeSecret, Secret}; +use semver::Version; +use serde::Deserialize; +use sqlx::postgres::{PgConnectOptions, PgSslMode}; + +use infra::env_util::get_env_var; + #[derive(Clone, Debug)] pub struct Config { pub app_env: Environment, @@ -166,6 +169,7 @@ pub fn get_configuration() -> Result { websocket: WebsocketSetting { heartbeat_interval: get_env_var("APPFLOWY_WEBSOCKET_HEARTBEAT_INTERVAL", "6").parse()?, client_timeout: get_env_var("APPFLOWY_WEBSOCKET_CLIENT_TIMEOUT", "60").parse()?, + min_client_version: get_env_var("APPFLOWY_WEBSOCKET_CLIENT_MIN_VERSION", "0.5.0").parse()?, }, redis_uri: get_env_var("APPFLOWY_REDIS_URI", "redis://localhost:6379").into(), s3: S3Setting { @@ -239,4 +243,5 @@ impl FromStr for Environment { pub struct WebsocketSetting { pub heartbeat_interval: u8, pub client_timeout: u8, + pub min_client_version: Version, }