diff --git a/client-solid/src/Footer.tsx b/client-solid/src/Footer.tsx
deleted file mode 100644
index 376e454..0000000
--- a/client-solid/src/Footer.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { JSXElement } from "solid-js";
-
-export function Footer(): JSXElement {
- return (
-
- );
-}
diff --git a/client-solid/src/Posts.tsx b/client-solid/src/Posts.tsx
index db1efad..72b22aa 100644
--- a/client-solid/src/Posts.tsx
+++ b/client-solid/src/Posts.tsx
@@ -15,9 +15,9 @@ export function Posts(): JSXElement {
return (
- {/*
+
{(post): JSXElement => }
- */}
+
);
}
diff --git a/client-solid/src/Root.tsx b/client-solid/src/Root.tsx
index e07d657..717d224 100644
--- a/client-solid/src/Root.tsx
+++ b/client-solid/src/Root.tsx
@@ -4,7 +4,6 @@ import { GlobalStateProvider } from "./GlobalState";
import { LoginModal } from "./LoginModal";
import { Navbar } from "./Navbar";
import { Primary } from "./Primary";
-import { Footer } from "./Footer";
function Root(): JSXElement {
return (
@@ -14,10 +13,9 @@ function Root(): JSXElement {
-
>
@@ -27,7 +25,7 @@ function Root(): JSXElement {
function FancyBackground(): JSXElement {
return (
);
}
diff --git a/server/Cargo.lock b/server/Cargo.lock
index bfc7374..9917c48 100755
--- a/server/Cargo.lock
+++ b/server/Cargo.lock
@@ -1851,7 +1851,6 @@ dependencies = [
"jsonwebtoken",
"lipsum",
"log",
- "rand",
"serde",
"serde_json",
"sled",
diff --git a/server/Cargo.toml b/server/Cargo.toml
index d3046e3..ed54483 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -17,7 +17,6 @@ env_logger = "0.10.0"
jsonwebtoken = "8.3.0"
lipsum = "0.9.0"
log = "0.4.20"
-rand = "0.8.5"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
sled = { version = "0.34.7" }
diff --git a/server/src/db.rs b/server/src/db.rs
index 3c52b93..89c643e 100644
--- a/server/src/db.rs
+++ b/server/src/db.rs
@@ -6,7 +6,7 @@ use argon2::{
use log::{info, warn};
use sqlx::PgPool;
-/// Gets the latest posts from the database, ordered by created_at
+// Gets the latest posts from the database, ordered by created_at
pub async fn db_get_latest_posts(pool: &PgPool, limit: i64, offset: i64) -> Vec
{
sqlx::query_as!(
Post,
@@ -19,7 +19,7 @@ pub async fn db_get_latest_posts(pool: &PgPool, limit: i64, offset: i64) -> Vec<
.unwrap()
}
-/// Gets the post with id from the database
+// Gets the post with id from the database
pub async fn db_get_post(id: i64, pool: &PgPool) -> Option {
sqlx::query_as!(Post, "SELECT * FROM posts WHERE id = $1", id)
.fetch_one(pool)
@@ -27,7 +27,7 @@ pub async fn db_get_post(id: i64, pool: &PgPool) -> Option {
.ok()
}
-/// Inserts a new post to the database
+// Inserts a new post to the database
pub async fn db_new_post(userid: i64, content: &str, pool: &PgPool) -> Option {
info!("User with id {} submitted a post", userid);
@@ -57,7 +57,6 @@ pub async fn db_new_post(userid: i64, content: &str, pool: &PgPool) -> Option bool {
let exists = sqlx::query!("SELECT username FROM users WHERE username = $1", username)
.fetch_one(pool)
@@ -68,7 +67,6 @@ pub async fn db_user_exists(username: String, pool: &PgPool) -> bool {
exists.is_some()
}
-/// Checks if the user exists and if the password is correct
pub async fn db_user_login(username: String, password: String, pool: &PgPool) -> Option {
let username = username.clone();
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE username = $1", username)
@@ -97,7 +95,6 @@ pub async fn db_user_login(username: String, password: String, pool: &PgPool) ->
}
}
-/// Creates a new user if the username is not already taken
pub async fn db_new_user(username: String, password: String, pool: &PgPool) -> Option {
// First check if the user already exists
match db_user_exists(username.clone(), pool).await {
diff --git a/server/src/main.rs b/server/src/main.rs
index beba099..3ed8abd 100755
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -8,12 +8,10 @@ mod db;
mod jwt;
mod routes;
mod state;
-mod util;
use routes::{get_posts, login, new_post, post_by_id, register};
use state::CaptchaState;
use state::ServerState;
-use util::hex_string;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
@@ -22,15 +20,6 @@ async fn main() -> std::io::Result<()> {
let data = ServerState::new().await;
let capt_db = CaptchaState::new();
- #[cfg(debug_assertions)]
- {
- for _ in 0..10 {
- let s = hex_string(10);
- info!("Adding captcha key: {}", &s);
- capt_db.capthca_db.lock().unwrap().insert(s);
- }
- }
-
info!("Spinning up server on http://localhost:8080");
HttpServer::new(move || {
App::new()
diff --git a/server/src/routes/users.rs b/server/src/routes/users.rs
index c5e7f02..5b7d999 100755
--- a/server/src/routes/users.rs
+++ b/server/src/routes/users.rs
@@ -5,6 +5,8 @@ use crate::ServerState;
use actix_web::web::Data;
use actix_web::{post, web::Json, HttpResponse, Responder, Result};
+use argon2::password_hash::rand_core::RngCore;
+use argon2::password_hash::*;
use biosvg::BiosvgBuilder;
use log::*;
use serde::{Deserialize, Serialize};
@@ -16,7 +18,7 @@ pub struct LoginData {
}
#[derive(Debug, Serialize, Deserialize)]
-pub struct AuthResponse {
+pub struct LoginResponse {
username: String,
token: String,
}
@@ -32,31 +34,10 @@ pub struct RegisterData {
pub async fn register(
data: Json,
state: Data,
- captcha_state: Data,
) -> Result {
- if !captcha_state
- .capthca_db
- .lock()
- .unwrap()
- .remove(&data.captcha)
- {
- info!("User failed to register, captcha was wrong");
- return Ok(HttpResponse::BadRequest().json("Error"));
- }
-
- match db_new_user(data.username.clone(), data.password.clone(), &state.pool).await {
- Some(user) => {
- info!("User: {} registered", &user.username);
- Ok(HttpResponse::Ok().json(AuthResponse {
- username: user.username.clone(),
- token: token_factory(&user.username).unwrap(),
- }))
- }
- None => {
- info!("User \"{}\" already exists", data.username);
- return Ok(HttpResponse::BadRequest().json("Error"));
- }
- }
+ db_new_user(data.username.clone(), data.password.clone(), &state.pool).await;
+ info!("User: {} registered", data.username);
+ Ok(HttpResponse::Ok().json("User registered"))
}
#[post("/login")]
@@ -65,7 +46,7 @@ pub async fn login(data: Json, state: Data) -> Result {
- return Ok(HttpResponse::Ok().json(AuthResponse {
+ return Ok(HttpResponse::Ok().json(LoginResponse {
username: data.username.clone(),
token: token_factory(&data.username).unwrap(),
}));
@@ -86,38 +67,35 @@ pub struct CaptchaResponse {
/// Request a captcha from the captcha service
#[post("/captcha")]
pub async fn captcha_request(cstate: Data) -> Result {
- unimplemented!("Captcha is currently disabled");
- return Ok(HttpResponse::InternalServerError().json("Error"));
-
// This might block the thread a bit too long
- // let (answer, svg) = get_captcha();
+ let (answer, svg) = get_captcha();
- // let id = rand_core::OsRng.next_u32() as i32;
+ let id = rand_core::OsRng.next_u32() as i32;
- // let cresponse = CaptchaResponse {
- // captcha_svg: svg.clone(),
- // captcha_id: id,
- // };
+ let cresponse = CaptchaResponse {
+ captcha_svg: svg.clone(),
+ captcha_id: id,
+ };
// This is bad in about every way i can think of
// It might just be better to hit the database every time, and let the database
// handle rng and maybe set a trigger to delete old captchas
- // match cstate.capthca_db.lock() {
- // Ok(mut db) => {
- // if (db.len() as i32) > 100 {
- // // To prevent the database from growing too large
- // // Replace with a proper LRU cache or circular buffer
- // db.remove(&(id % 100)); // This is terrible
- // }
- // db.insert(id, answer.clone()); // We do not care about collisions
- // return Ok(HttpResponse::Ok().json(cresponse));
- // }
- // Err(_) => {
- // // This shouldnt happen
- // error!("Failed to lock captcha database");
- // return Ok(HttpResponse::InternalServerError().json("Error"));
- // }
- // }
+ match cstate.capthca_db.lock() {
+ Ok(mut db) => {
+ if (db.len() as i32) > 100 {
+ // To prevent the database from growing too large
+ // Replace with a proper LRU cache or circular buffer
+ db.remove(&(id % 100)); // This is terrible
+ }
+ db.insert(id, answer.clone()); // We do not care about collisions
+ return Ok(HttpResponse::Ok().json(cresponse));
+ }
+ Err(_) => {
+ // This shouldnt happen
+ error!("Failed to lock captcha database");
+ return Ok(HttpResponse::InternalServerError().json("Error"));
+ }
+ }
}
/// Returns a new captcha in the form of a tuple (answer, svg)
diff --git a/server/src/state.rs b/server/src/state.rs
index aafca2b..8414449 100644
--- a/server/src/state.rs
+++ b/server/src/state.rs
@@ -1,4 +1,4 @@
-use std::collections::BTreeSet;
+use std::collections::BTreeMap;
use std::sync::Arc;
use std::sync::Mutex;
@@ -9,14 +9,13 @@ use sqlx::PgPool;
#[derive(Clone)]
pub struct CaptchaState {
- // pub capthca_db: Arc>>,
- pub capthca_db: Arc>>,
+ pub capthca_db: Arc>>,
}
impl CaptchaState {
pub fn new() -> Self {
Self {
- capthca_db: Arc::new(Mutex::new(BTreeSet::new())),
+ capthca_db: Arc::new(Mutex::new(BTreeMap::new())),
}
}
}
@@ -63,7 +62,6 @@ impl ServerState {
#[cfg(debug_assertions)]
async fn debug_setup(pool: &PgPool) -> Result<(), sqlx::Error> {
use lipsum::lipsum;
- use rand::prelude::*;
use sqlx::query;
use crate::db::db_new_user;
@@ -71,29 +69,26 @@ async fn debug_setup(pool: &PgPool) -> Result<(), sqlx::Error> {
db_new_user("user".to_string(), "pass".to_string(), pool).await;
// Check if the demo post already exists
- let no_posts = query!("SELECT * FROM posts WHERE id = 1",)
+ let posted = query!("SELECT * FROM posts WHERE id = 1",)
.fetch_one(pool)
.await
- .ok()
- .is_none();
+ .ok();
// If the demo user already has a post, don't insert another one
- if no_posts {
- let mut rng = rand::thread_rng();
-
+ if !posted.is_some() {
// This requires that the user with id 1 exists in the user table
- for _ in 0..100 {
+ query!("INSERT INTO posts (user_id, content) VALUES (1, 'Hello world! The demo username is user and the password is pass.')",)
+ .execute(pool)
+ .await?;
+
+ for _ in 0..10 {
query!(
"INSERT INTO posts (user_id, content) VALUES (1, $1)",
- lipsum(rng.gen_range(10..100))
+ lipsum(50)
)
.execute(pool)
.await?;
}
-
- query!("INSERT INTO posts (user_id, content) VALUES (1, 'Hello world! The demo username is user and the password is pass.')",)
- .execute(pool)
- .await?;
}
Ok(())
diff --git a/server/src/util/mod.rs b/server/src/util/mod.rs
deleted file mode 100644
index c8183a1..0000000
--- a/server/src/util/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod util;
-
-pub use util::*;
diff --git a/server/src/util/util.rs b/server/src/util/util.rs
deleted file mode 100644
index b50a703..0000000
--- a/server/src/util/util.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use rand::{Rng, RngCore};
-
-// This will do for now
-pub fn hex_string(length: usize) -> String {
- let mut rng = rand::thread_rng();
- let mut bytes = vec![0u8; length];
- rng.fill(&mut bytes[..]);
- bytes.iter().map(|b| format!("{:X}", b)).collect::()[..length].to_string()
-}
-
-mod tests {
- use super::*;
-
- #[test]
- fn test_random_hex_string() {
- let s = hex_string(16);
- assert_eq!(s.len(), 16);
- }
-}