signup
This commit is contained in:
parent
3a702ed3a5
commit
2d7607bbc1
|
@ -0,0 +1,9 @@
|
|||
use std::error::Error;
|
||||
use log::info;
|
||||
|
||||
pub fn send_magic_link(token: &str) -> Result<(), Box<dyn Error>> {
|
||||
// TODO: actually do this
|
||||
info!("sent magic link {}", token);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -15,6 +15,7 @@ pub mod routes;
|
|||
pub mod error;
|
||||
pub mod tokens;
|
||||
pub mod timers;
|
||||
pub mod magic_link;
|
||||
|
||||
pub struct AppState {
|
||||
pub conn: DatabaseConnection
|
||||
|
@ -60,6 +61,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
).into()
|
||||
}))
|
||||
.wrap(RequestIdentifier::with_generator(random_id_no_id))
|
||||
.service(routes::v1::auth::magic_link::magic_link_request)
|
||||
.service(routes::v1::signup::signup_request)
|
||||
}).bind(CONFIG.server.bind)?.run().await?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1 +1 @@
|
|||
pub mod auth;
|
||||
pub mod v1;
|
|
@ -3,11 +3,12 @@ use actix_web::web::{Data, Json};
|
|||
use log::error;
|
||||
use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use trifid_api_entities::user::Entity as UserEntity;
|
||||
use trifid_api_entities::user;
|
||||
use trifid_api_entities::entity::user::Entity as UserEntity;
|
||||
use trifid_api_entities::entity::user;
|
||||
use crate::AppState;
|
||||
use crate::config::CONFIG;
|
||||
use crate::error::{APIError, APIErrorsResponse};
|
||||
use crate::magic_link::send_magic_link;
|
||||
use crate::timers::expires_in_seconds;
|
||||
use crate::tokens::random_token;
|
||||
|
||||
|
@ -59,12 +60,28 @@ pub async fn magic_link_request(data: Data<AppState>, req: Json<MagicLinkRequest
|
|||
}
|
||||
};
|
||||
|
||||
let model = trifid_api_entities::magic_link::Model {
|
||||
let model = trifid_api_entities::entity::magic_link::Model {
|
||||
id: random_token("ml"),
|
||||
user: user.id,
|
||||
expires_on: expires_in_seconds(CONFIG.tokens.magic_link_expiry_time_seconds) as i64,
|
||||
};
|
||||
|
||||
match send_magic_link(&model.id) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("error sending magic link: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_ML_ERROR".to_string(),
|
||||
message: "There was an error sending the magic link email, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let active_model = model.into_active_model();
|
||||
|
||||
match active_model.insert(&data.conn).await {
|
|
@ -0,0 +1,2 @@
|
|||
pub mod auth;
|
||||
pub mod signup;
|
|
@ -0,0 +1,128 @@
|
|||
use actix_web::{HttpResponse, post};
|
||||
use actix_web::web::{Data, Json};
|
||||
use log::error;
|
||||
use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use trifid_api_entities::entity::user::Entity as UserEntity;
|
||||
use trifid_api_entities::entity::user;
|
||||
use crate::AppState;
|
||||
use crate::config::CONFIG;
|
||||
use crate::error::{APIError, APIErrorsResponse};
|
||||
use crate::magic_link::send_magic_link;
|
||||
use crate::timers::expires_in_seconds;
|
||||
use crate::tokens::{random_id, random_token};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SignupRequest {
|
||||
pub email: String
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SignupResponse {
|
||||
pub data: Option<SignupResponseData>,
|
||||
pub metadata: SignupResponseMetadata
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SignupResponseData {}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SignupResponseMetadata {}
|
||||
|
||||
#[post("/v1/signup")]
|
||||
pub async fn signup_request(data: Data<AppState>, req: Json<SignupRequest>) -> HttpResponse {
|
||||
let user: Vec<user::Model> = match UserEntity::find().filter(user::Column::Email.eq(&req.email)).all(&data.conn).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
if user.is_empty() {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_USER_EXISTS".to_string(),
|
||||
message: "That user already exists.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
let model = user::Model {
|
||||
id: random_id("user"),
|
||||
email: req.email.clone()
|
||||
};
|
||||
let id = model.id.clone();
|
||||
|
||||
let active_model = model.into_active_model();
|
||||
|
||||
match active_model.insert(&data.conn).await {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let model = trifid_api_entities::entity::magic_link::Model {
|
||||
id: random_token("ml"),
|
||||
user: id,
|
||||
expires_on: expires_in_seconds(CONFIG.tokens.magic_link_expiry_time_seconds) as i64,
|
||||
};
|
||||
|
||||
match send_magic_link(&model.id) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("error sending magic link: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_ML_ERROR".to_string(),
|
||||
message: "There was an error sending the magic link email, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let active_model = model.into_active_model();
|
||||
|
||||
match active_model.insert(&data.conn).await {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
HttpResponse::Ok().json(SignupResponse {
|
||||
data: None,
|
||||
metadata: SignupResponseMetadata {}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod magic_link;
|
||||
pub mod user;
|
|
@ -9,7 +9,6 @@ pub struct Model {
|
|||
pub id: String,
|
||||
#[sea_orm(unique)]
|
||||
pub email: String,
|
||||
pub password_hash: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
|
@ -1,6 +1 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod user;
|
||||
pub mod magic_link;
|
||||
pub mod entity;
|
|
@ -13,7 +13,6 @@ impl MigrationTrait for Migration {
|
|||
.if_not_exists()
|
||||
.col(ColumnDef::new(User::Id).string().not_null().primary_key())
|
||||
.col(ColumnDef::new(User::Email).string().not_null().unique_key())
|
||||
.col(ColumnDef::new(User::PasswordHash).string().not_null())
|
||||
.to_owned()
|
||||
).await
|
||||
}
|
||||
|
@ -28,6 +27,5 @@ impl MigrationTrait for Migration {
|
|||
pub enum User {
|
||||
Table,
|
||||
Id,
|
||||
Email,
|
||||
PasswordHash,
|
||||
Email
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue