Compare commits

...

3 commits

18 changed files with 255 additions and 39 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 3 KiB

Before After
Before After

View file

@ -54,6 +54,10 @@ a {
color: #a6e3a1; color: #a6e3a1;
} }
.dim {
color: #a6adc8;
}
.fancy-button { .fancy-button {
outline: 0; outline: 0;
border: none; border: none;
@ -68,3 +72,105 @@ a {
transition: 0.1s background-color; transition: 0.1s background-color;
} }
.fancy-button:hover {
background-color: #bad4fc;
}
.inline-post {
display: inline;
}
.inline-post-button {
display: inline;
background: none;
outline: none;
border: none;
color: inherit;
font-size: inherit;
font-weight: inherit;
text-decoration: underline;
cursor: pointer;
padding: 0;
}
.greeting ::selection {
background-color: #11111b;
color: #cdd6f4;
}
.greeting {
background-color: #89b4fa;
color: #11111b;
border-radius: 1.5em;
padding: 1em;
display: flex;
flex-direction: row;
gap: 1rem;
}
.greeting-l {
flex: 0 0 auto;
max-width: 100%;
width: auto;
height: 100%;
max-height: 3rem;
object-fit: contain;
display: block;
}
.greeting-r {
flex: 1 1 0px;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.greeting-top {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.greeting-top-left {
font-size: 1.4rem;
}
.greeting-stats {
display: flex;
flex-direction: row;
align-items: stretch;
gap: 0.5ex;
}
.greeting-stats img {
width: auto;
height: 1em;
}
.greeting a {
color: #11111b;
}
.header {
height: 96px;
max-width: 600px;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
}
.header>.greeting {
flex: 1 1 0px;
}
.favicon {
margin: auto;
display: block;
}

View file

@ -40,3 +40,6 @@ i've run out of ideas.
- authentication caching (ip? redis?) - authentication caching (ip? redis?)
- use log instead of println - use log instead of println
- make a proper rank system (reuploading, uploading music, rating, etc.) - make a proper rank system (reuploading, uploading music, rating, etc.)
- user icons in the account management + settings (gdicon.oat.zone? selfhost?)
- account settings page
- better web design

View file

@ -1,19 +1,18 @@
macro_rules! auth { use rocket::http::CookieJar;
($cookies: expr) => {
match $cookies.get_private("blackmail_data") { pub fn authenticate(cookies: &CookieJar<'_>) -> Result<(String, i32, i32), &'static str> {
Some(cookie_val) => { match cookies.get_private("blackmail_data") {
let parts = cookie_val.value().split(":").collect::<Vec<&str>>(); Some(cookie) => {
let parts = cookie.value().split(":").collect::<Vec<&str>>();
let username = parts[0].to_string(); let username = parts[0].to_string();
let account_id = parts[1].parse::<i32>().expect("account id is not an integer! this should NOT happen!"); let account_id = parts[1].parse::<i32>().expect("account id is not an integer! this should NOT happen!");
let user_id = parts[2].parse::<i32>().expect("user id is not an integer! this should NOT happen!"); let user_id = parts[2].parse::<i32>().expect("user id is not an integer! this should NOT happen!");
(true, Some(username), Some(account_id), Some(user_id)) return Ok((username, account_id, user_id))
} }
None => { None => {
(false, None, None, None) return Err("authentication failed")
}
} }
} }
} }
pub(crate) use auth;

View file

@ -58,7 +58,9 @@ fn rocket() -> _ {
template_endpoints::login::post_login, template_endpoints::login::post_login,
template_endpoints::login::get_login, template_endpoints::login::get_login,
template_endpoints::logout::logout, template_endpoints::account_management::account_management,
template_endpoints::logout::logout
]) ])
// assets // assets
.mount("/", routes![ .mount("/", routes![

View file

@ -1,3 +1,4 @@
pub mod account_management;
pub mod index; pub mod index;
pub mod login; pub mod login;
pub mod logout; pub mod logout;

View file

@ -0,0 +1,40 @@
use rocket::response::Redirect;
use rocket_dyn_templates::{Template, context};
use rocket::http::CookieJar;
use diesel::prelude::*;
use crate::db;
#[get("/accounts")]
pub fn account_management(cookies: &CookieJar<'_>) -> Result<Template, Redirect> {
let connection = &mut db::establish_connection_pg();
let logged_in = crate::helpers::templates::authenticate(cookies);
match logged_in {
Ok((username_val, account_id_val, user_id_val)) => {
use crate::schema::users::dsl::*;
use crate::models::User;
let result = users
.filter(id.eq(user_id_val))
.get_result::<User, >(connection)
.expect("couldnt find user with user id from account");
return Ok(Template::render("account_management", context! {
username: username_val,
stars: result.stars,
diamonds: result.diamonds,
coins: result.coins,
user_coins: result.user_coins,
demons: result.demons
}));
},
Err(_) => {
return Err(Redirect::to("/login"));
}
}
}

View file

@ -7,7 +7,7 @@ pub fn index() -> Template {
let silly_strings: Vec<&str> = vec![ let silly_strings: Vec<&str> = vec![
"the trianges consume", "the trianges consume",
"geomtry das", "geomtry das",
"now with no RCE!", "now with no ACE!",
"the best gdps", "the best gdps",
"better than topala", "better than topala",
"better than robtop", "better than robtop",
@ -17,7 +17,21 @@ pub fn index() -> Template {
"kagepro", "kagepro",
"wowaka is peak music", "wowaka is peak music",
"you have been warned: dyno jun", "you have been warned: dyno jun",
"listen to jin" "listen to jin",
"GIVEUP!GIVEUP!GIVEUP!GIVEUP!GIVEUP!GIVEUP!LOVE!LOVE!GIVEUP!GIVEUP!GIVEUP!GIVEUP!GIVEUP!GIVEUP!",
"cross site scripting is a myth",
"VITAL STATE: Deceased - abducted by Pikmin",
"geometry dash for the 3ds",
"trans rights",
"how many maggots eat burger?",
"who would win: the rust borrow checker or rotting flesh",
"your system has run out of application memory",
"unsafe { std::ptr::null_mut::<i32>().write(42) }",
"-1",
"[REDACTED]",
"chrome jop jop?",
"pikmin 4",
"italian apk downloader"
]; ];
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();

View file

@ -20,7 +20,7 @@ pub struct FormLogin {
} }
#[post("/login", data = "<input>")] #[post("/login", data = "<input>")]
pub fn post_login(jar: &CookieJar<'_>, input: Form<FormLogin>) -> Template { pub fn post_login(cookies: &CookieJar<'_>, input: Form<FormLogin>) -> Template {
let connection = &mut db::establish_connection_pg(); let connection = &mut db::establish_connection_pg();
use crate::schema::accounts::dsl::*; use crate::schema::accounts::dsl::*;
@ -34,7 +34,7 @@ pub fn post_login(jar: &CookieJar<'_>, input: Form<FormLogin>) -> Template {
Ok(account_id_username_val) => { Ok(account_id_username_val) => {
match helpers::accounts::auth(account_id_username_val.0, Some(input.password.clone()), None, None) { match helpers::accounts::auth(account_id_username_val.0, Some(input.password.clone()), None, None) {
Ok(account_id_user_id_val) => { Ok(account_id_user_id_val) => {
jar.add_private(Cookie::build( cookies.add_private(Cookie::build(
"blackmail_data", "blackmail_data",
format!("{}:{}:{}", account_id_username_val.1, account_id_user_id_val.0, account_id_user_id_val.1)) format!("{}:{}:{}", account_id_username_val.1, account_id_user_id_val.0, account_id_user_id_val.1))
.path("/") .path("/")
@ -65,11 +65,14 @@ pub fn post_login(jar: &CookieJar<'_>, input: Form<FormLogin>) -> Template {
#[get("/login")] #[get("/login")]
pub fn get_login(cookies: &CookieJar<'_>) -> Result<Redirect, Template> { pub fn get_login(cookies: &CookieJar<'_>) -> Result<Redirect, Template> {
let (logged_in, _username, _account_id, _user_id) = crate::helpers::templates::auth!(cookies); let logged_in = crate::helpers::templates::authenticate(cookies);
if logged_in { match logged_in {
Ok(Redirect::to("/")) Ok(_) => {
} else { return Ok(Redirect::to("/"))
},
Err(_) => {
Err(Template::render("login", context! { })) Err(Template::render("login", context! { }))
} }
}
} }

View file

@ -3,9 +3,7 @@ use rocket::response::Redirect;
#[post("/accounts/logout")] #[post("/accounts/logout")]
pub fn logout(jar: &CookieJar<'_>) -> Redirect { pub fn logout(jar: &CookieJar<'_>) -> Redirect {
jar.remove_private(Cookie::named("username")); jar.remove_private(Cookie::named("blackmail_data"));
jar.remove_private(Cookie::named("account_id"));
jar.remove_private(Cookie::named("user_id"));
Redirect::to("/") Redirect::to("/")
} }

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/style.css" />
<title>Home</title>
</head>
<body style="display: flex; align-items: center; gap: 1.5em; flex-direction: column">
<h1 style="display: flex; align-items: center; gap: 1em">
<a href="/"><img src="/favicon.png" width="64" height="auto"></a>
Account Management
</h1>
<div class="header">
<div class="greeting">
<img src="/assets/icons/gd/demon.png" title="{{ username }}" class="greeting-l">
<div class="greeting-r">
<div class="greeting-top">
<div class="greeting-top-left">
hai, <b>{{ username }}</b>!
</div>
<div class="greeting-stats">
{{ stars }} <img src="/assets/icons/gd/star.png"> {{ diamonds }} <img src="/assets/icons/gd/diamond.png"> {{ coins }} <img src="/assets/icons/gd/coin.png"> {{ user_coins }} <img src="/assets/icons/gd/silvercoin.png"> {{ demons }} <img src="/assets/icons/gd/demon.png">
</div>
</div>
<div class="greeting-bottom">
<a href="/accounts/settings">Settings</a> &middot;
<form action="/accounts/logout" method="post" class="inline-post">
<button type="submit" class="inline-post-button">
Log out
</button>
</form>
</div>
</div>
</div>
</div>
<div class="block">
lorem ipsum sur dolor amet or something. i'll put stuff here later LOL
<br><br>
anyway how has ur day been
<br><br>
the demon should be your user icon haha, ill get 2 that latr :3 (gonna be next update i think)
</div>
</body>
</html>

View file

@ -11,7 +11,7 @@
<body style="display: flex; align-items: center; gap: 1.5em; flex-direction: column"> <body style="display: flex; align-items: center; gap: 1.5em; flex-direction: column">
<h1 style="display: flex; align-items: center; gap: 1em"> <h1 style="display: flex; align-items: center; gap: 1em">
<img src="/favicon.png" width="64" height="auto"> <a href="/"><img src="/favicon.png" width="64" height="auto"></a>
gdps-server gdps-server
</h1> </h1>
<div class="block"> <div class="block">
@ -24,10 +24,11 @@
<el> <el>
<li>The <a href="https://git.reidlab.online/reidlab/gdps-server">Git repository</a></li> <li>The <a href="https://git.reidlab.online/reidlab/gdps-server">Git repository</a></li>
<li><a href="/tools/reupload">Level reuploading</a></li> <li><a href="/tools/reupload">Level reuploading</a></li>
<li><a href="/accounts">Account stuff</a></li>
</el> </el>
</p> </p>
</div> </div>
<div class="dim"> <div style="max-width: 400px; font-style: italic; text-align: center" class="dim">
{{ silly_string }} {{ silly_string }}
</div> </div>
</body> </body>

View file

@ -34,7 +34,7 @@
<body> <body>
<form method="post"> <form method="post">
<img src="/favicon.png" width="64" height="auto"> <a href="/"><img src="/favicon.png" width="64" height="auto"></a>
<br> <br>
<label for="username">Username</label> <label for="username">Username</label>
<input type="text" id="username" name="username" minlength="3" maxlength="20" required /> <input type="text" id="username" name="username" minlength="3" maxlength="20" required />