diff --git a/Cargo.lock b/Cargo.lock
index f275ca6..b490d6b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -381,6 +381,12 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
[[package]]
name = "libc"
version = "0.2.139"
@@ -1051,6 +1057,7 @@ version = "0.0.1"
dependencies = [
"axum",
"bytes",
+ "lazy_static",
"rand",
"rusqlite",
"serde",
diff --git a/Cargo.toml b/Cargo.toml
index 1d3a937..e81c936 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,7 +11,8 @@ tower-cookies = "0.8.0"
tower = "0.4.13"
bytes = "1.3.0"
serde = { version = "1.0.152", features = ["derive"] }
-serde_json = "1.0"
+serde_json = { version = "1.0", features = ["std"] }
rusqlite = { version = "0.28.0", features = ["bundled"] }
rand = "0.8.5"
-time = "0.3.17"
\ No newline at end of file
+time = "0.3.17"
+lazy_static = "1.4.0"
\ No newline at end of file
diff --git a/public/css/console.css b/public/css/console.css
index bc07969..e3fde6a 100644
--- a/public/css/console.css
+++ b/public/css/console.css
@@ -2,8 +2,6 @@ body {
margin: 0;
padding: 0;
background-color: #181818;
- display: flex;
- flex-direction: column-reverse;
}
@font-face {
@@ -30,20 +28,20 @@ span {
margin-right: 10px;
}
+.body span {
+ margin-right: 0;
+}
+
.json span {
display: inline;
margin: 0;
}
-.key {
- color: white;
-}
-
.value {
color: white;
}
-.boolean {
+.bool {
color: aqua;
}
@@ -57,4 +55,8 @@ span {
.string {
color: #4ae04a
+}
+
+.key .string {
+ color: white;
}
\ No newline at end of file
diff --git a/public/css/profile.css b/public/css/profile.css
index 4c5ae10..467c756 100644
--- a/public/css/profile.css
+++ b/public/css/profile.css
@@ -62,6 +62,7 @@ body {
height: 3em;
display: flex;
align-items: center;
+ justify-content: space-between;
}
.profilebuttons button {
@@ -74,6 +75,7 @@ body {
justify-content: center;
color: #606770;
cursor: pointer;
+ flex: 0;
}
.profilebuttons button:hover {
@@ -118,4 +120,9 @@ body {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
+}
+
+.logout {
+ flex: 1;
+ /* align-self: flex-end !important; */
}
\ No newline at end of file
diff --git a/public/js/api.js b/public/js/api.js
index 07769f6..77adff7 100644
--- a/public/js/api.js
+++ b/public/js/api.js
@@ -30,6 +30,10 @@ const register = async (firstname, lastname, email, password, gender, day, month
return await request('/auth/register', {firstname, lastname, email, password, gender, day, month, year})
}
+const logout = async () => {
+ return await request('/auth/logout', {})
+}
+
const loadpostspage = async (page) => {
return await request('/posts/page', {page})
}
diff --git a/public/js/home.js b/public/js/home.js
index 23f0d01..688cbf5 100644
--- a/public/js/home.js
+++ b/public/js/home.js
@@ -1,12 +1,5 @@
-const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
-
-function parseDate(date) {
- return months[date.getUTCMonth()] + ' ' + date.getUTCDate() + ', ' + date.getUTCFullYear() + ' ' + date.toLocaleTimeString();
-}
-
function parseComment(comment) {
- const author = data.users[comment[0]]
+ let author = data.users[comment[0]]
if (author === undefined) {
author = {}
}
@@ -25,14 +18,14 @@ function parseComment(comment) {
}
function parsePost(post) {
- const author = data.users[post.user_id]
+ let author = data.users[post.user_id]
if (author === undefined) {
author = {}
}
const html = `
`
@@ -44,7 +46,7 @@ function render() {
Name: ${data.user.firstname + ' ' + data.user.lastname}
Email: ${data.user.email}
Gender: ${data.user.gender}
- Birthday: ${months[data.user.month] + ' ' + data.user.day + ', ' + data.user.year}
+ Birthday: ${parseMonth(data.user.month) + ' ' + data.user.day + ', ' + data.user.year}
User ID: ${data.user.user_id}
@@ -53,7 +55,14 @@ function render() {
add(about, 'about')
}
+async function logout_button() {
+ const response = await logout()
+ if (response.status != 200) return;
+ location.href = '/login'
+}
+
var posts = true
+var isself = false
async function load() {
header(false, false)
@@ -63,7 +72,18 @@ async function load() {
params[key] = value
}
- const id = params.id !== undefined && !isNaN(params.id) ? parseInt(params.id) : (await loadself()).json.user_id
+ let self = (await loadself()).json;
+ let id;
+
+ if (params.id !== undefined && !isNaN(params.id)) {
+
+ id = parseInt(params.id);
+ } else {
+ id = self.user_id
+ }
+
+ isself = id === self.user_id
+
const posts = (await loadusersposts(id)).json
data.posts.push(... posts)
const batch = [id]
diff --git a/src/api/auth.rs b/src/api/auth.rs
index 54c4e06..253e982 100644
--- a/src/api/auth.rs
+++ b/src/api/auth.rs
@@ -3,7 +3,7 @@ use serde::Deserialize;
use time::{OffsetDateTime, Duration};
use tower_cookies::{Cookies, Cookie};
-use crate::types::{user::User, response::ResponseCode, session::Session, extract::{Json, AuthorizedUser, Check, CheckResult}};
+use crate::types::{user::User, response::ResponseCode, session::Session, extract::{Json, AuthorizedUser, Check, CheckResult, Log}};
#[derive(Deserialize)]
struct RegistrationRequet {
@@ -55,7 +55,7 @@ async fn register(cookies: Cookies, Json(body): Json) -> Res
cookies.add(cookie);
- ResponseCode::Created.msg("Successfully created new user")
+ ResponseCode::Created.text("Successfully created new user")
}
#[derive(Deserialize)]
@@ -73,11 +73,11 @@ impl Check for LoginRequest {
async fn login(cookies: Cookies, Json(body): Json) -> Response {
let Ok(user) = User::from_email(&body.email) else {
- return ResponseCode::BadRequest.msg("Email is not registered")
+ return ResponseCode::BadRequest.text("Email is not registered")
};
if user.password != body.password {
- return ResponseCode::BadRequest.msg("Password is not correct")
+ return ResponseCode::BadRequest.text("Password is not correct")
}
let session = match Session::new(user.user_id) {
@@ -96,10 +96,10 @@ async fn login(cookies: Cookies, Json(body): Json) -> Response {
cookies.add(cookie);
- ResponseCode::Success.msg("Successfully logged in")
+ ResponseCode::Success.text("Successfully logged in")
}
-async fn logout(cookies: Cookies, AuthorizedUser(user): AuthorizedUser) -> Response {
+async fn logout(cookies: Cookies, AuthorizedUser(user): AuthorizedUser, _: Log) -> Response {
cookies.remove(Cookie::new("auth", ""));
@@ -107,7 +107,7 @@ async fn logout(cookies: Cookies, AuthorizedUser(user): AuthorizedUser) -> Respo
return err
}
- ResponseCode::Success.msg("Successfully logged out")
+ ResponseCode::Success.text("Successfully logged out")
}
pub fn router() -> Router {
diff --git a/src/api/pages.rs b/src/api/pages.rs
index 4701795..b2bef82 100644
--- a/src/api/pages.rs
+++ b/src/api/pages.rs
@@ -1,6 +1,6 @@
use axum::{Router, response::{Response, Redirect, IntoResponse}, routing::get};
-use crate::types::{extract::AuthorizedUser, response::ResponseCode};
+use crate::{types::{extract::AuthorizedUser, response::ResponseCode}, console};
async fn root(user: Option) -> Response {
if user.is_some() {
@@ -42,8 +42,12 @@ async fn profile(user: Option) -> Response {
}
}
+async fn console() -> Response {
+ console::generate().await
+}
+
async fn wordpress() -> Response {
- ResponseCode::ImATeapot.msg("Hello i am a teapot owo")
+ ResponseCode::ImATeapot.text("Hello i am a teapot owo")
}
pub fn router() -> Router {
@@ -53,5 +57,6 @@ pub fn router() -> Router {
.route("/home", get(home))
.route("/people", get(people))
.route("/profile", get(profile))
+ .route("/console", get(console))
.route("/wp-admin", get(wordpress))
}
\ No newline at end of file
diff --git a/src/api/posts.rs b/src/api/posts.rs
index 6830c1a..fda1fb1 100644
--- a/src/api/posts.rs
+++ b/src/api/posts.rs
@@ -19,11 +19,11 @@ impl Check for PostCreateRequest {
async fn create(AuthorizedUser(user): AuthorizedUser, Json(body): Json) -> Response {
let Ok(post) = Post::new(user.user_id, body.content) else {
- return ResponseCode::InternalServerError.msg("Failed to create post")
+ return ResponseCode::InternalServerError.text("Failed to create post")
};
let Ok(json) = serde_json::to_string(&post) else {
- return ResponseCode::InternalServerError.msg("Failed to create post")
+ return ResponseCode::InternalServerError.text("Failed to create post")
};
ResponseCode::Created.json(&json)
@@ -43,11 +43,11 @@ impl Check for PostPageRequest {
async fn page(AuthorizedUser(_user): AuthorizedUser, Json(body): Json) -> Response {
let Ok(posts) = Post::from_post_page(body.page) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ return ResponseCode::InternalServerError.text("Failed to fetch posts")
};
let Ok(json) = serde_json::to_string(&posts) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ return ResponseCode::InternalServerError.text("Failed to fetch posts")
};
ResponseCode::Success.json(&json)
@@ -67,11 +67,11 @@ impl Check for UsersPostsRequest {
async fn user(AuthorizedUser(_user): AuthorizedUser, Json(body): Json) -> Response {
let Ok(posts) = Post::from_user_id(body.user_id) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ return ResponseCode::InternalServerError.text("Failed to fetch posts")
};
let Ok(json) = serde_json::to_string(&posts) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ return ResponseCode::InternalServerError.text("Failed to fetch posts")
};
ResponseCode::Success.json(&json)
@@ -93,14 +93,14 @@ impl Check for PostCommentRequest {
async fn comment(AuthorizedUser(user): AuthorizedUser, Json(body): Json) -> Response {
let Ok(mut post) = Post::from_post_id(body.post_id) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ return ResponseCode::InternalServerError.text("Failed to fetch posts")
};
if let Err(err) = post.comment(user.user_id, body.content) {
return err;
}
- ResponseCode::Success.msg("Successfully commented on post")
+ ResponseCode::Success.text("Successfully commented on post")
}
#[derive(Deserialize)]
@@ -118,14 +118,14 @@ impl Check for PostLikeRequest {
async fn like(AuthorizedUser(user): AuthorizedUser, Json(body): Json) -> Response {
let Ok(mut post) = Post::from_post_id(body.post_id) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ return ResponseCode::InternalServerError.text("Failed to fetch posts")
};
if let Err(err) = post.like(user.user_id, body.state) {
return err;
}
- ResponseCode::Success.msg("Successfully changed like status on post")
+ ResponseCode::Success.text("Successfully changed like status on post")
}
pub fn router() -> Router {
diff --git a/src/api/users.rs b/src/api/users.rs
index 45ed195..7bea200 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -17,7 +17,7 @@ async fn load_batch(AuthorizedUser(_user): AuthorizedUser, Json(body): Json) -> Response {
let Ok(users) = User::from_user_page(body.page) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch users")
+ return ResponseCode::InternalServerError.text("Failed to fetch users")
};
let Ok(json) = serde_json::to_string(&users) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch users")
+ return ResponseCode::InternalServerError.text("Failed to fetch users")
};
ResponseCode::Success.json(&json)
@@ -50,7 +50,7 @@ async fn load_page(AuthorizedUser(_user): AuthorizedUser, Json(body): Json Response {
let Ok(json) = serde_json::to_string(&user) else {
- return ResponseCode::InternalServerError.msg("Failed to fetch user")
+ return ResponseCode::InternalServerError.text("Failed to fetch user")
};
ResponseCode::Success.json(&json)
diff --git a/src/console.rs b/src/console.rs
index 5a3c60b..660fb25 100644
--- a/src/console.rs
+++ b/src/console.rs
@@ -1,13 +1,195 @@
-use std::net::IpAddr;
-use axum::http::{Method, Uri};
+use std::{net::IpAddr, collections::VecDeque, io, };
+use axum::{http::{Method, Uri}, response::Response};
+use lazy_static::lazy_static;
+use serde::Serialize;
+use serde_json::{ser::Formatter, Value};
+use tokio::sync::Mutex;
-pub async fn log(ip: &IpAddr, method: &Method, uri: &Uri, path: Option<&str>, body: Option<&str>) {
-
- if path.is_some() && body.is_some() {
- println!("{} {} {}{} {}", ip, method, path.unwrap(), uri, body.unwrap());
- } else {
- println!("{} {} {}", ip, method, uri);
+use crate::types::response::ResponseCode;
+
+struct LogMessage {
+ ip: IpAddr,
+ method: Method,
+ uri: Uri,
+ path: String,
+ body: String
+}
+
+impl ToString for LogMessage {
+ fn to_string(&self) -> String {
+ let mut ip = self.ip.to_string();
+ if ip.contains("::ffff:") {
+ ip = ip.as_str()[7..].to_string()
+ }
+ let color = match self.method {
+ Method::GET => "#3fe04f",
+ Method::POST => "#853fe0",
+ Method::PATCH => "#e0773f",
+ Method::PUT => "#e0cb3f",
+ Method::HEAD => "#3f75e0",
+ Method::DELETE => "#e04c3f",
+ Method::CONNECT => "#3fe0ad",
+ Method::TRACE => "#e03fc5",
+ Method::OPTIONS => "#423fe0",
+ _ => "white"
+ };
+ format!("{} {} {}{} {}
", ip, color, self.method, self.path, self.uri, self.body)
}
-
+}
+lazy_static! {
+ static ref LOG: Mutex> = Mutex::new(VecDeque::with_capacity(200));
+}
+
+pub async fn log(ip: IpAddr, method: Method, uri: Uri, path: Option, body: Option) {
+
+ if uri.to_string().starts_with("/console") { return; }
+
+ let path = path.unwrap_or_default();
+ let body = body.unwrap_or_default();
+
+ println!("{} {} {}{} {}", &ip, &method, &path, &uri, &body);
+
+ let message = LogMessage {
+ ip: ip,
+ method: method,
+ uri: uri,
+ path: path,
+ body: beautify(body)
+ };
+
+ let mut lock = LOG.lock().await;
+ if lock.len() > 200 {
+ lock.pop_back();
+ }
+ lock.push_front(message);
+}
+
+struct HtmlFormatter;
+impl Formatter for HtmlFormatter {
+ fn write_null(&mut self, writer: &mut W) -> io::Result<()> where W: ?Sized + io::Write {
+ writer.write_all(b"null")
+ }
+
+ fn write_bool(&mut self, writer: &mut W, value: bool) -> io::Result<()> where W: ?Sized + io::Write {
+ let s = if value {
+ b"true" as &[u8]
+ } else {
+ b"false" as &[u8]
+ };
+ writer.write_all(s)
+ }
+
+ fn write_i8(&mut self, writer: &mut W, value: i8) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_i16(&mut self, writer: &mut W, value: i16) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_i32(&mut self, writer: &mut W, value: i32) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_i64(&mut self, writer: &mut W, value: i64) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_u8(&mut self, writer: &mut W, value: u8) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_u16(&mut self, writer: &mut W, value: u16) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_u32(&mut self, writer: &mut W, value: u32) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_u64(&mut self, writer: &mut W, value: u64) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_f32(&mut self, writer: &mut W, value: f32) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn write_f64(&mut self, writer: &mut W, value: f64) -> io::Result<()> where W: ?Sized + io::Write {
+ let buff = format!("{}", value);
+ writer.write_all(buff.as_bytes())
+ }
+
+ fn begin_string(&mut self, writer: &mut W) -> io::Result<()> where W: ?Sized + io::Write {
+ writer.write_all(b"\"")
+ }
+
+ fn end_string(&mut self, writer: &mut W) -> io::Result<()> where W: ?Sized + io::Write {
+ writer.write_all(b"\"")
+ }
+
+ fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> where W: ?Sized + io::Write {
+ if first {
+ writer.write_all(b"")
+ } else {
+ writer.write_all(b",")
+ }
+ }
+
+ fn end_object_key(&mut self, writer: &mut W) -> io::Result<()> where W: ?Sized + io::Write {
+ writer.write_all(b"")
+ }
+
+}
+
+fn beautify(body: String) -> String {
+ if body.len() < 1 {
+ return "".to_string()
+ }
+ let Ok(mut json) = serde_json::from_str::(&body) else {
+ return body
+ };
+ if json["password"].is_string() {
+ json["password"] = Value::String("********".to_owned());
+ }
+ let mut writer: Vec = Vec::with_capacity(128);
+ let mut serializer = serde_json::Serializer::with_formatter(&mut writer, HtmlFormatter);
+ if let Err(_) = json.serialize(&mut serializer) {
+ return body
+ }
+ String::from_utf8_lossy(&writer).to_string()
+}
+
+pub async fn generate() -> Response {
+
+ let lock = LOG.lock().await;
+
+ let mut html = r#"
+
+
+
+
+
+ XSSBook - Console
+
+
+ "#.to_string();
+
+ for message in lock.iter() {
+ html.push_str(&message.to_string());
+ }
+
+ html.push_str("");
+
+ ResponseCode::Success.html(&html)
}
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 64abf68..54c73c1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -25,7 +25,7 @@ async fn log(mut req: Request, next: Next) -> Response where
return next.run(req).await
};
- console::log(&info.ip(), req.method(), req.uri(), None, None).await;
+ console::log(info.ip().clone(), req.method().clone(), req.uri().clone(), None, None).await;
return next.run(req).await
}
diff --git a/src/types/extract.rs b/src/types/extract.rs
index 1379828..399fe67 100644
--- a/src/types/extract.rs
+++ b/src/types/extract.rs
@@ -15,25 +15,60 @@ impl FromRequestParts for AuthorizedUser where S: Send + Sync {
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result {
let Ok(Some(cookies)) = Option::>::from_request_parts(parts, state).await else {
- return Err(ResponseCode::Forbidden.msg("No cookies provided"))
+ return Err(ResponseCode::Forbidden.text("No cookies provided"))
};
let Some(token) = cookies.get("auth") else {
- return Err(ResponseCode::Forbidden.msg("No auth token provided"))
+ return Err(ResponseCode::Forbidden.text("No auth token provided"))
};
let Ok(session) = Session::from_token(&token) else {
- return Err(ResponseCode::Unauthorized.msg("Auth token invalid"))
+ return Err(ResponseCode::Unauthorized.text("Auth token invalid"))
};
let Ok(user) = User::from_user_id(session.user_id, true) else {
- return Err(ResponseCode::InternalServerError.msg("Valid token but no valid user"))
+ return Err(ResponseCode::InternalServerError.text("Valid token but no valid user"))
};
Ok(AuthorizedUser(user))
}
}
+pub struct Log;
+#[async_trait]
+impl FromRequest for Log where
+ B: HttpBody + Sync + Send + 'static,
+ B::Data: Send,
+ B::Error: Into,
+ S: Send + Sync,
+{
+ type Rejection = Response;
+
+ async fn from_request(mut req: Request, state: &S) -> Result {
+
+ let Ok(ConnectInfo(info)) = req.extract_parts::>().await else {
+ return Ok(Log)
+ };
+ let method = req.method().clone();
+ let path = req.extensions().get::().unwrap().0;
+ let uri = req.uri().clone();
+
+ let Ok(bytes) = Bytes::from_request(req, state).await else {
+ console::log(info.ip().clone(), method.clone(), uri.clone(), Some(path.to_string()), None).await;
+ return Ok(Log)
+ };
+
+ let Ok(body) = String::from_utf8(bytes.bytes().flatten().collect()) else {
+ console::log(info.ip().clone(), method.clone(), uri.clone(), Some(path.to_string()), None).await;
+ return Ok(Log)
+ };
+
+ console::log(info.ip().clone(), method.clone(), uri.clone(), Some(path.to_string()), Some(body.to_string())).await;
+
+ Ok(Log)
+ }
+}
+
pub struct Json(pub T);
#[async_trait]
@@ -49,28 +84,28 @@ impl FromRequest for Json where
async fn from_request(mut req: Request, state: &S) -> Result {
let Ok(ConnectInfo(info)) = req.extract_parts::>().await else {
- return Err(ResponseCode::InternalServerError.msg("Failed to read connection info"));
+ return Err(ResponseCode::InternalServerError.text("Failed to read connection info"));
};
let method = req.method().clone();
let path = req.extensions().get::().unwrap().0;
let uri = req.uri().clone();
let Ok(bytes) = Bytes::from_request(req, state).await else {
- return Err(ResponseCode::InternalServerError.msg("Failed to read request body"));
+ return Err(ResponseCode::InternalServerError.text("Failed to read request body"));
};
let Ok(body) = String::from_utf8(bytes.bytes().flatten().collect()) else {
- return Err(ResponseCode::BadRequest.msg("Invalid utf8 body"))
+ return Err(ResponseCode::BadRequest.text("Invalid utf8 body"))
};
- console::log(&info.ip(), &method, &uri, Some(path), Some(&body)).await;
+ console::log(info.ip().clone(), method.clone(), uri.clone(), Some(path.to_string()), Some(body.to_string())).await;
let Ok(value) = serde_json::from_str::(&body) else {
- return Err(ResponseCode::BadRequest.msg("Invalid request body"))
+ return Err(ResponseCode::BadRequest.text("Invalid request body"))
};
if let Err(msg) = value.check() {
- return Err(ResponseCode::BadRequest.msg(&msg));
+ return Err(ResponseCode::BadRequest.text(&msg));
}
Ok(Json(value))
diff --git a/src/types/post.rs b/src/types/post.rs
index 94f0a9e..7805a4e 100644
--- a/src/types/post.rs
+++ b/src/types/post.rs
@@ -18,7 +18,7 @@ impl Post {
pub fn from_post_id(post_id: u64) -> Result {
let Ok(Some(post)) = database::posts::get_post(post_id) else {
- return Err(ResponseCode::BadRequest.msg("Post does not exist"))
+ return Err(ResponseCode::BadRequest.text("Post does not exist"))
};
Ok(post)
@@ -35,21 +35,21 @@ impl Post {
pub fn from_post_page(page: u64) -> Result> {
let Ok(posts) = database::posts::get_post_page(page) else {
- return Err(ResponseCode::BadRequest.msg("Failed to fetch posts"))
+ return Err(ResponseCode::BadRequest.text("Failed to fetch posts"))
};
Ok(posts)
}
pub fn from_user_id(user_id: u64) -> Result> {
let Ok(posts) = database::posts::get_users_posts(user_id) else {
- return Err(ResponseCode::BadRequest.msg("Failed to fetch posts"))
+ return Err(ResponseCode::BadRequest.text("Failed to fetch posts"))
};
Ok(posts)
}
pub fn new(user_id: u64, content: String) -> Result {
let Ok(post) = database::posts::add_post(user_id, &content) else {
- return Err(ResponseCode::InternalServerError.msg("Failed to create post"))
+ return Err(ResponseCode::InternalServerError.text("Failed to create post"))
};
Ok(post)
@@ -59,7 +59,7 @@ impl Post {
self.comments.push((user_id, content));
if database::posts::update_post(self.post_id, &self.likes, &self.comments).is_err() {
- return Err(ResponseCode::InternalServerError.msg("Failed to comment on post"))
+ return Err(ResponseCode::InternalServerError.text("Failed to comment on post"))
}
Ok(())
@@ -74,7 +74,7 @@ impl Post {
}
if database::posts::update_post(self.post_id, &self.likes, &self.comments).is_err() {
- return Err(ResponseCode::InternalServerError.msg("Failed to comment on post"))
+ return Err(ResponseCode::InternalServerError.text("Failed to comment on post"))
}
Ok(())
diff --git a/src/types/response.rs b/src/types/response.rs
index bea3406..72c1334 100644
--- a/src/types/response.rs
+++ b/src/types/response.rs
@@ -28,7 +28,7 @@ impl ResponseCode {
}
}
- pub fn msg(self, msg: &str) -> Response {
+ pub fn text(self, msg: &str) -> Response {
(self.code(), msg.to_owned()).into_response()
}
@@ -40,17 +40,25 @@ impl ResponseCode {
res
}
+ pub fn html(self, json: &str) -> Response {
+ let mut res = (self.code(), json.to_owned()).into_response();
+ res.headers_mut().insert(
+ HeaderName::from_static("content-type"), HeaderValue::from_static("text/html"),
+ );
+ res
+ }
+
pub async fn file(self, path: &str) -> Result {
if path.chars().position(|c| c == '.' ).is_none() {
- return Err(ResponseCode::BadRequest.msg("Folders cannot be served"));
+ return Err(ResponseCode::BadRequest.text("Folders cannot be served"));
}
let path = format!("public{}", path);
let svc = ServeFile::new(path);
let Ok(mut res) = svc.oneshot(Request::new(Body::empty())).await else {
- return Err(ResponseCode::InternalServerError.msg("Error wile fetching file"));
+ return Err(ResponseCode::InternalServerError.text("Error wile fetching file"));
};
if res.status() != StatusCode::OK {
- return Err(ResponseCode::NotFound.msg("File not found"));
+ return Err(ResponseCode::NotFound.text("File not found"));
}
*res.status_mut() = self.code();
Ok(res.into_response())
diff --git a/src/types/session.rs b/src/types/session.rs
index 8064fb1..9b949be 100644
--- a/src/types/session.rs
+++ b/src/types/session.rs
@@ -14,7 +14,7 @@ impl Session {
pub fn from_token(token: &str) -> Result {
let Ok(Some(session)) = database::sessions::get_session(token) else {
- return Err(ResponseCode::BadRequest.msg("Invalid auth token"));
+ return Err(ResponseCode::BadRequest.text("Invalid auth token"));
};
Ok(session)
@@ -23,14 +23,14 @@ impl Session {
pub fn new(user_id: u64) -> Result {
let token: String = rand::thread_rng().sample_iter(&Alphanumeric).take(32).map(char::from).collect();
match database::sessions::set_session(user_id, &token) {
- Err(_) => return Err(ResponseCode::BadRequest.msg("Failed to create session")),
+ Err(_) => return Err(ResponseCode::BadRequest.text("Failed to create session")),
Ok(_) => return Ok(Session {user_id, token})
};
}
pub fn delete(user_id: u64) -> Result<()> {
if let Err(_) = database::sessions::delete_session(user_id) {
- return Err(ResponseCode::InternalServerError.msg("Failed to logout"));
+ return Err(ResponseCode::InternalServerError.text("Failed to logout"));
};
Ok(())
}
diff --git a/src/types/user.rs b/src/types/user.rs
index 1213a75..56ef467 100644
--- a/src/types/user.rs
+++ b/src/types/user.rs
@@ -22,7 +22,7 @@ impl User {
pub fn from_user_id(user_id: u64, hide_password: bool) -> Result {
let Ok(Some(user)) = database::users::get_user_by_id(user_id, hide_password) else {
- return Err(ResponseCode::BadRequest.msg("User does not exist"))
+ return Err(ResponseCode::BadRequest.text("User does not exist"))
};
Ok(user)
@@ -39,14 +39,14 @@ impl User {
pub fn from_user_page(page: u64) -> Result> {
let Ok(users) = database::users::get_user_page(page, true) else {
- return Err(ResponseCode::BadRequest.msg("Failed to fetch users"))
+ return Err(ResponseCode::BadRequest.text("Failed to fetch users"))
};
Ok(users)
}
pub fn from_email(email: &str) -> Result {
let Ok(Some(user)) = database::users::get_user_by_email(email, false) else {
- return Err(ResponseCode::BadRequest.msg("User does not exist"))
+ return Err(ResponseCode::BadRequest.text("User does not exist"))
};
Ok(user)
@@ -54,7 +54,7 @@ impl User {
pub fn from_password(password: &str) -> Result {
let Ok(Some(user)) = database::users::get_user_by_password(password, true) else {
- return Err(ResponseCode::BadRequest.msg("User does not exist"))
+ return Err(ResponseCode::BadRequest.text("User does not exist"))
};
Ok(user)
@@ -62,15 +62,15 @@ impl User {
pub fn new(firstname: String, lastname: String, email: String, password: String, gender: String, day: u8, month: u8, year: u32) -> Result {
if let Ok(_) = User::from_email(&email) {
- return Err(ResponseCode::BadRequest.msg(&format!("Email is already in use by {}", &email)))
+ return Err(ResponseCode::BadRequest.text(&format!("Email is already in use by {}", &email)))
}
if let Ok(user) = User::from_password(&password) {
- return Err(ResponseCode::BadRequest.msg(&format!("Password is already in use by {}", user.email)))
+ return Err(ResponseCode::BadRequest.text(&format!("Password is already in use by {}", user.email)))
}
let Ok(user) = database::users::add_user(&firstname, &lastname, &email, &password, &gender, day, month, year) else {
- return Err(ResponseCode::InternalServerError.msg("Failed to create new uesr"))
+ return Err(ResponseCode::InternalServerError.text("Failed to create new uesr"))
};
Ok(user)