diff --git a/Cargo.toml b/Cargo.toml index 52ac0fa..03eb2af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,14 +5,10 @@ edition = "2024" [dependencies] actix-web = "4.10" -futures = "0.3" -regex = "1.11" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +serde = { version = "1.0.219", features = ["derive"] } sqlx = { version = "0.8", features = ["runtime-tokio", "tls-native-tls", "postgres"] } toml = "0.8" -url = { version = "2.5", features = ["serde"] } -uuid = { version = "1.16", features = ["v7"] } +url = { version = "2.5.4", features = ["serde"] } [dependencies.tokio] version = "1.44" diff --git a/src/api/v1/mod.rs b/src/api/v1/mod.rs index 690188f..542a0f5 100644 --- a/src/api/v1/mod.rs +++ b/src/api/v1/mod.rs @@ -1,10 +1,7 @@ use actix_web::{Scope, web}; mod stats; -mod register; pub fn web() -> Scope { - web::scope("/v1") - .service(stats::res) - .service(register::res) + web::scope("/v1").service(stats::res) } diff --git a/src/api/v1/register.rs b/src/api/v1/register.rs deleted file mode 100644 index 63dca6d..0000000 --- a/src/api/v1/register.rs +++ /dev/null @@ -1,134 +0,0 @@ -use actix_web::{error, post, web, Error, HttpResponse}; -use regex::Regex; -use serde::{Deserialize, Serialize}; -use futures::StreamExt; -use sqlx::Executor; -use uuid::Uuid; - -use crate::Data; - -const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); - -#[derive(Deserialize)] -struct AccountInformation { - identifier: String, - email: String, - password: String, - device_name: String, -} - -#[derive(Serialize)] -struct ResponseError { - signups_enabled: bool, - gorb_id_valid: bool, - gorb_id_available: bool, - email_valid: bool, - email_available: bool, - password_minimum_length: bool, - password_special_characters: bool, - password_letters: bool, - password_numbers: bool, -} - -impl Default for ResponseError { - fn default() -> Self { - Self { - signups_enabled: true, - gorb_id_valid: true, - gorb_id_available: true, - email_valid: true, - email_available: true, - password_minimum_length: true, - password_special_characters: true, - password_letters: true, - password_numbers: true, - } - } -} - -#[derive(Serialize)] -struct Response { - access_token: String, - user_id: String, - expires_in: u64, - refresh_token: String, -} - -const MAX_SIZE: usize = 262_144; - -#[post("/register")] -pub async fn res(mut payload: web::Payload, data: web::Data) -> Result { - let mut body = web::BytesMut::new(); - while let Some(chunk) = payload.next().await { - let chunk = chunk?; - // limit max size of in-memory payload - if (body.len() + chunk.len()) > MAX_SIZE { - return Err(error::ErrorBadRequest("overflow")); - } - body.extend_from_slice(&chunk); - } - - let account_information = serde_json::from_slice::(&body)?; - - let uuid = Uuid::now_v7(); - - let email_regex = Regex::new(r"[-A-Za-z0-9!#$%&'*+/=?^_`{|}~]+(?:\.[-A-Za-z0-9!#$%&'*+/=?^_`{|}~]+)*@(?:[A-Za-z0-9](?:[-A-Za-z0-9]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[-A-Za-z0-9]*[A-Za-z0-9])?").unwrap(); - - if !email_regex.is_match(&account_information.email) { - return Ok(HttpResponse::Forbidden().json( - ResponseError { - email_valid: false, - ..Default::default() - } - )) - } - - let username_regex = Regex::new(r"[a-zA-Z0-9.-_]").unwrap(); - - if !username_regex.is_match(&account_information.identifier) || account_information.identifier.len() < 3 || account_information.identifier.len() > 32 { - return Ok(HttpResponse::Forbidden().json( - ResponseError { - gorb_id_valid: false, - ..Default::default() - } - )) - } - - Ok(match data.pool.execute( - &*format!( - "INSERT INTO users VALUES ( '{}', '{}', NULL, '{}', '{}', '0' )", - uuid, - account_information.identifier, - account_information.password, - account_information.email, - ) - ).await { - Ok(v) => { - HttpResponse::Ok().json( - Response { - access_token: "bogus".to_string(), - user_id: "bogus".to_string(), - expires_in: 1, - refresh_token: "bogus".to_string(), - } - ) - }, - Err(error) => { - let err_msg = error.as_database_error().unwrap().message(); - - match err_msg { - err_msg if err_msg.contains("unique") && err_msg.contains("username_key") => HttpResponse::Forbidden().json(ResponseError { - gorb_id_available: false, - ..Default::default() - }), - err_msg if err_msg.contains("unique") && err_msg.contains("email_key") => HttpResponse::Forbidden().json(ResponseError { - email_available: false, - ..Default::default() - }), - _ => HttpResponse::Forbidden().json(ResponseError { - ..Default::default() - }) - } - }, - }) -} diff --git a/src/config.rs b/src/config.rs index 27a426e..cefc272 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,5 @@ use crate::Error; use serde::Deserialize; -use sqlx::postgres::PgConnectOptions; use tokio::fs::read_to_string; #[derive(Debug, Deserialize)] @@ -13,7 +12,7 @@ pub struct ConfigBuilder { pub struct Database { username: String, password: String, - host: String, + hostname: String, database: String, port: u16, } @@ -68,14 +67,3 @@ pub struct Web { pub port: u16, pub ssl: bool, } - -impl Database { - pub fn connect_options(&self) -> PgConnectOptions { - PgConnectOptions::new() - .database(&self.database) - .host(&self.host) - .username(&self.username) - .password(&self.password) - .port(self.port) - } -} diff --git a/src/main.rs b/src/main.rs index 78f1fb9..989630c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ use actix_web::{App, HttpServer, web}; -use sqlx::{Executor, PgPool, Pool, Postgres}; use std::time::SystemTime; mod config; use config::{Config, ConfigBuilder}; @@ -9,7 +8,6 @@ type Error = Box; #[derive(Clone)] struct Data { - pub pool: Pool, pub config: Config, pub start_time: SystemTime, } @@ -20,20 +18,7 @@ async fn main() -> Result<(), Error> { let web = config.web.clone(); - let pool = PgPool::connect_with(config.database.connect_options()).await?; - - pool.execute(r#"CREATE TABLE IF NOT EXISTS users ( - uuid uuid UNIQUE NOT NULL, - username varchar(32) UNIQUE NOT NULL, - display_name varchar(64), - password varchar(512) NOT NULL, - email varchar(100) UNIQUE NOT NULL, - email_verified integer NOT NULL DEFAULT '0', - PRIMARY KEY (uuid) - )"#).await?; - let data = Data { - pool, config, start_time: SystemTime::now(), };