Working invites.
This commit is contained in:
parent
a8efdac3dd
commit
df01960be5
3 changed files with 14 additions and 18 deletions
|
@ -62,13 +62,11 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
|
||||||
let assets_dir = std::env::current_dir().unwrap().join("assets");
|
let assets_dir = std::env::current_dir().unwrap().join("assets");
|
||||||
let assets_svc = ServeDir::new(assets_dir.as_path());
|
let assets_svc = ServeDir::new(assets_dir.as_path());
|
||||||
|
|
||||||
tracing_subscriber::fmt().with_target(false).pretty().init();
|
|
||||||
|
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
.route("/", get(handle_slash).post(handle_slash))
|
.route("/", get(handle_slash).post(handle_slash))
|
||||||
.nest_service("/assets", assets_svc)
|
.nest_service("/assets", assets_svc)
|
||||||
|
.route("/signup", post(post_create_user))
|
||||||
.route("/signup/:invitation", get(get_create_user))
|
.route("/signup/:invitation", get(get_create_user))
|
||||||
.route("/signup/", post(post_create_user))
|
|
||||||
.route("/signup_success/:user", get(get_signup_success))
|
.route("/signup_success/:user", get(get_signup_success))
|
||||||
.route("/login", get(get_login).post(post_login))
|
.route("/login", get(get_login).post(post_login))
|
||||||
.route("/logout", get(get_logout).post(post_logout))
|
.route("/logout", get(get_logout).post(post_logout))
|
||||||
|
|
|
@ -15,8 +15,6 @@ use unicode_segmentation::UnicodeSegmentation;
|
||||||
use super::{templates::*, Invitation};
|
use super::{templates::*, Invitation};
|
||||||
use crate::{util::empty_string_as_none, User};
|
use crate::{util::empty_string_as_none, User};
|
||||||
|
|
||||||
pub(crate) const CREATE_QUERY: &str =
|
|
||||||
"insert into users (username, displayname, email, pwhash, invited_by) values ($1, $2, $3, $4, $5) returning *";
|
|
||||||
const ID_QUERY: &str = "select * from users where id = $1";
|
const ID_QUERY: &str = "select * from users where id = $1";
|
||||||
|
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
|
@ -98,8 +96,6 @@ pub async fn post_create_user(
|
||||||
State(pool): State<SqlitePool>,
|
State(pool): State<SqlitePool>,
|
||||||
Form(signup): Form<SignupForm>,
|
Form(signup): Form<SignupForm>,
|
||||||
) -> Result<impl IntoResponse, CreateUserError> {
|
) -> Result<impl IntoResponse, CreateUserError> {
|
||||||
dbg!(&signup);
|
|
||||||
|
|
||||||
use crate::util::validate_optional_length;
|
use crate::util::validate_optional_length;
|
||||||
let username = signup.username.trim();
|
let username = signup.username.trim();
|
||||||
let password = signup.password.trim();
|
let password = signup.password.trim();
|
||||||
|
@ -151,7 +147,6 @@ pub async fn get_signup_success(
|
||||||
Path(id): Path<String>,
|
Path(id): Path<String>,
|
||||||
State(pool): State<SqlitePool>,
|
State(pool): State<SqlitePool>,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
dbg!(&id);
|
|
||||||
let id = id.trim();
|
let id = id.trim();
|
||||||
let id = Julid::from_string(id).unwrap_or_default();
|
let id = Julid::from_string(id).unwrap_or_default();
|
||||||
let user: User = {
|
let user: User = {
|
||||||
|
@ -185,6 +180,9 @@ pub(crate) async fn create_user(
|
||||||
pool: &SqlitePool,
|
pool: &SqlitePool,
|
||||||
invitation: &str,
|
invitation: &str,
|
||||||
) -> Result<User, CreateUserError> {
|
) -> Result<User, CreateUserError> {
|
||||||
|
const CREATE_QUERY: &str =
|
||||||
|
"insert into users (username, displayname, email, pwhash, invited_by) values ($1, $2, $3, $4, $5) returning *";
|
||||||
|
|
||||||
// Argon2 with default params (Argon2id v19)
|
// Argon2 with default params (Argon2id v19)
|
||||||
let argon2 = Argon2::default();
|
let argon2 = Argon2::default();
|
||||||
let salt = SaltString::generate(&mut OsRng);
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
@ -209,9 +207,10 @@ pub(crate) async fn create_user(
|
||||||
.bind(email)
|
.bind(email)
|
||||||
.bind(&pwhash)
|
.bind(&pwhash)
|
||||||
.bind(invited_by)
|
.bind(invited_by)
|
||||||
.fetch_one(pool)
|
.fetch_one(&mut *tx)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
tracing::info!("Got error inserting new user: {e}");
|
||||||
match e {
|
match e {
|
||||||
sqlx::Error::Database(db) => {
|
sqlx::Error::Database(db) => {
|
||||||
let exit = db.code().unwrap_or_default().parse().unwrap_or(0);
|
let exit = db.code().unwrap_or_default().parse().unwrap_or(0);
|
||||||
|
@ -306,8 +305,6 @@ mod test {
|
||||||
.content_type(FORM_CONTENT_TYPE)
|
.content_type(FORM_CONTENT_TYPE)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
dbg!(&resp.text());
|
|
||||||
|
|
||||||
assert_eq!(StatusCode::SEE_OTHER, resp.status_code());
|
assert_eq!(StatusCode::SEE_OTHER, resp.status_code());
|
||||||
|
|
||||||
// get the new user from the db
|
// get the new user from the db
|
||||||
|
@ -327,16 +324,18 @@ mod test {
|
||||||
let path = format!("/signup/{invitation}");
|
let path = format!("/signup/{invitation}");
|
||||||
let resp = server.get(&path).await;
|
let resp = server.get(&path).await;
|
||||||
let body = std::str::from_utf8(resp.as_bytes()).unwrap();
|
let body = std::str::from_utf8(resp.as_bytes()).unwrap();
|
||||||
let expected = SignupPage::default().to_string();
|
let expected = SignupPage {
|
||||||
|
invitation,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
assert_eq!(&expected, body);
|
assert_eq!(&expected, body);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn handle_signup_success() {
|
fn handle_signup_success() {
|
||||||
dbg!("getting the pool");
|
|
||||||
let pool = get_db_pool();
|
let pool = get_db_pool();
|
||||||
dbg!("got the pool");
|
|
||||||
let rt = Runtime::new().unwrap();
|
let rt = Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let server = server_with_pool(&pool).await;
|
let server = server_with_pool(&pool).await;
|
||||||
|
@ -354,9 +353,7 @@ mod test {
|
||||||
assert_eq!(StatusCode::SEE_OTHER, resp.status_code());
|
assert_eq!(StatusCode::SEE_OTHER, resp.status_code());
|
||||||
|
|
||||||
// get the new user from the db
|
// get the new user from the db
|
||||||
let user = User::try_get("good_user", &pool).await.unwrap();
|
let user = User::try_get("good_user", &pool).await.unwrap().unwrap();
|
||||||
dbg!(&user);
|
|
||||||
let user = user.unwrap();
|
|
||||||
let id = user.id;
|
let id = user.id;
|
||||||
|
|
||||||
|
|
||||||
|
@ -625,7 +622,7 @@ mod test {
|
||||||
|
|
||||||
let path = "/signup_success/nope";
|
let path = "/signup_success/nope";
|
||||||
|
|
||||||
let resp = server.get(&path).expect_failure().await;
|
let resp = server.get(path).expect_failure().await;
|
||||||
assert_eq!(resp.status_code(), StatusCode::SEE_OTHER);
|
assert_eq!(resp.status_code(), StatusCode::SEE_OTHER);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<form action="/signup" enctype="application/x-www-form-urlencoded" method="post">
|
<form action="/signup" enctype="application/x-www-form-urlencoded" method="post">
|
||||||
|
<input type="hidden" name="invitation" value="{{self.invitation}}">
|
||||||
<label for="username">Username</label>
|
<label for="username">Username</label>
|
||||||
<input type="text" name="username" id="username" minlength="1" maxlength="20" required></br>
|
<input type="text" name="username" id="username" minlength="1" maxlength="20" required></br>
|
||||||
<label for="displayname">Displayname (optional)</label>
|
<label for="displayname">Displayname (optional)</label>
|
||||||
|
|
Loading…
Reference in a new issue