endpoint /v1/signup works, /v1/auth/magic-link is functionally the same and can also be considered finished
This commit is contained in:
parent
c3990486b8
commit
e3c8819c08
|
@ -3,11 +3,14 @@ use log::info;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::config::TFConfig;
|
use crate::config::TFConfig;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
use std::time::UNIX_EPOCH;
|
||||||
|
|
||||||
// https://admin.defined.net/auth/magic-link?email=coredoescode%40gmail.com&token=ml-ckBsgw_5IdK5VYgseBYcoV_v_cQjtdq1re_RhDu_MKg
|
// https://admin.defined.net/auth/magic-link?email=coredoescode%40gmail.com&token=ml-ckBsgw_5IdK5VYgseBYcoV_v_cQjtdq1re_RhDu_MKg
|
||||||
pub async fn send_magic_link(id: i64, email: String, db: &PgPool, config: &TFConfig) -> Result<(), Box<dyn Error>> {
|
pub async fn send_magic_link(id: i64, email: String, db: &PgPool, config: &TFConfig) -> Result<(), Box<dyn Error>> {
|
||||||
let otp = Uuid::new_v4().to_string();
|
let otp = Uuid::new_v4().to_string();
|
||||||
let otp_url = format!("{}/{}", config.base, urlencoding::encode(&format!("/auth/magic-link?email={}&token={}", email.clone(), otp.clone())));
|
let otp_url = config.base.join(&format!("/auth/magic-link?email={}&token={}", urlencoding::encode(&email.clone()), otp.clone())).unwrap();
|
||||||
sqlx::query!("INSERT INTO magic_links (id, user_id, expires_on) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING;", otp, id, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64 + config.config.magic_links_valid_for).await?;
|
sqlx::query!("INSERT INTO magic_links (id, user_id, expires_on) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING;", otp, id as i32, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32 + config.magic_links_valid_for as i32).execute(db).await?;
|
||||||
// TODO: send email
|
// TODO: send email
|
||||||
info!("sent magic link {} to {}, valid for {} seconds", otp_url, email.clone(), config.magic_links_valid_for);
|
info!("sent magic link {} to {}, valid for {} seconds", otp_url, email.clone(), config.magic_links_valid_for);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -31,15 +31,27 @@ created_on TIMESTAMP NOT NULL,
|
||||||
*/
|
*/
|
||||||
#[post("/v1/signup", data = "<req>")]
|
#[post("/v1/signup", data = "<req>")]
|
||||||
pub async fn signup_request(req: Json<SignupRequest>, pool: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<SignupResponse>), (Status, String)> {
|
pub async fn signup_request(req: Json<SignupRequest>, pool: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<SignupResponse>), (Status, String)> {
|
||||||
match sqlx::query!("INSERT INTO users (email, created_on, banned, ban_reason, totp_secret, totp_otpurl, totp_verified) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id ON CONFLICT DO NOTHING;", req.email, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64, 0, "", "", "", 0).execute(pool.inner()).await {
|
// figure out if the user already exists
|
||||||
Ok(_) => (),
|
let mut id = -1;
|
||||||
|
match sqlx::query!("SELECT id FROM users WHERE email = $1", req.email.clone()).fetch_optional(pool.inner()).await {
|
||||||
|
Ok(res) => if let Some(r) = res { id = r.id as i64 },
|
||||||
|
Err(e) => {
|
||||||
|
return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if id == -1 {
|
||||||
|
let id_res = match sqlx::query!("INSERT INTO users (email, created_on, banned, ban_reason, totp_secret, totp_otpurl, totp_verified) VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT DO NOTHING RETURNING id;", req.email, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64, 0, "", "", "", 0).fetch_one(pool.inner()).await {
|
||||||
|
Ok(row) => row.id,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))
|
return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
id = id_res as i64;
|
||||||
|
}
|
||||||
|
|
||||||
// send magic link to email
|
// send magic link to email
|
||||||
match send_magic_link(req.email.clone(), pool.inner(), config.inner()).await {
|
match send_magic_link(id, req.email.clone(), pool.inner(), config.inner()).await {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))
|
return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_QL_QUERY_FAILED", "an error occurred while running the graphql query", e)))
|
||||||
|
|
Loading…
Reference in New Issue