Working on email templating, updating with swagger

This commit is contained in:
2025-05-14 20:33:13 -04:00
parent 1e3c75624a
commit e46e8ab9b4
41 changed files with 1124 additions and 189 deletions

View File

@@ -1,13 +1,26 @@
use actix_web::{post, web, HttpResponse, ResponseError, HttpRequest, put, get};
use crate::{
account::{verify_hash, Session, SESSION_COOKIE_NAME},
account::{SESSION_COOKIE_NAME, Session, verify_hash},
error::Error,
smtp,
users::{LoginRequest, RegisterRequest, User, UserResponse},
};
use actix_web::{HttpRequest, HttpResponse, ResponseError, get, post, put, web};
use utoipa_actix_web::scope;
use utoipa_actix_web::service_config::ServiceConfig;
use crate::account::Auth;
use crate::account::{Auth, csprng};
use crate::users::UpdateUser;
#[utoipa::path(
tag = "Account",
request_body(
content = RegisterRequest, content_type = "application/json"
),
responses(
(status = 200, description = "", body = UserResponse),
(status = 409, description = ""),
)
)]
#[post("/register")]
async fn register(user: web::Json<RegisterRequest>, req: HttpRequest) -> HttpResponse {
let register_user = user.into_inner();
@@ -38,13 +51,22 @@ async fn register(user: web::Json<RegisterRequest>, req: HttpRequest) -> HttpRes
);
HttpResponse::Conflict().finish()
} else {
log::error!("attemptFailed to register user [Email: {}]: {}", email, err);
log::error!("Failed to register user [Email: {}]: {}", email, err);
ResponseError::error_response(&err)
}
}
}
}
#[utoipa::path(
tag = "Account",
request_body(
content = LoginRequest, content_type = "application/json"
),
responses(
(status = 200, description = "", body = UserResponse),
),
)]
#[post("/login")]
async fn login(request: web::Json<LoginRequest>, req: HttpRequest) -> HttpResponse {
let email = &request.email;
@@ -93,6 +115,17 @@ async fn login(request: web::Json<LoginRequest>, req: HttpRequest) -> HttpRespon
}
}
#[utoipa::path(
tag = "Account",
responses(
(status = 200, description = ""),
(status = 401, description = ""),
(status = 500, description = ""),
),
security(
("session_auth" = [])
)
)]
#[post("/logout")]
async fn logout(req: HttpRequest, auth: Auth) -> HttpResponse {
let email = auth.user.email;
@@ -132,6 +165,16 @@ async fn logout(req: HttpRequest, auth: Auth) -> HttpResponse {
.finish()
}
#[utoipa::path(
tag = "Account",
responses(
(status = 200, description = "", body = UserResponse),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[get("/profile")]
async fn get_profile(req: HttpRequest) -> HttpResponse {
let ip_address = req.peer_addr().unwrap().ip().to_string();
@@ -154,7 +197,7 @@ async fn get_profile(req: HttpRequest) -> HttpResponse {
.finish();
}
};
let id = &session.id;
let id = &session.user_id;
let query_user = match User::select(&id).await {
Some(query_user) => query_user,
None => {
@@ -186,6 +229,16 @@ async fn get_profile(req: HttpRequest) -> HttpResponse {
}
}
#[utoipa::path(
tag = "Account",
responses(
(status = 200, description = ""),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[get("/session")]
async fn session_refresh(req: HttpRequest) -> HttpResponse {
let ip_address = req.peer_addr().unwrap().ip().to_string();
@@ -208,7 +261,7 @@ async fn session_refresh(req: HttpRequest) -> HttpResponse {
.finish();
}
};
let id = &session.id;
let id = &session.user_id;
let session_cookie = session.cookie();
let session_exp_cookie = session.expiration_cookie();
@@ -229,6 +282,19 @@ async fn session_refresh(req: HttpRequest) -> HttpResponse {
}
}
#[utoipa::path(
tag = "Account",
request_body(
content = String, content_type = "application/json"
),
responses(
(status = 200, description = "", body = UserResponse),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[put("/password")]
async fn change_password(
password: web::Json<String>,
@@ -269,25 +335,52 @@ async fn change_password(
ip_address,
err
);
ResponseError::error_response(&Error::new(500, err.to_string()))
ResponseError::error_response(&err)
}
}
}
#[post("/password-reset")]
async fn password_reset(req: HttpRequest, _auth: Auth) -> HttpResponse {
let _ip_address = req.peer_addr().unwrap().ip().to_string();
#[utoipa::path(
tag = "Account",
responses(
(status = 200, description = ""),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[post("/password/reset")]
async fn reset_password(req: HttpRequest, auth: Auth) -> HttpResponse {
let ip_address = req.peer_addr().unwrap().ip().to_string();
let id = auth.user.id;
let email = auth.user.email;
let token = csprng(128);
match smtp::send_password_reset(&email, &token) {
Ok(_) => HttpResponse::Ok().finish(),
Err(err) => {
log::error!(
"Invalid password reset attempt [ID: {}] [IP Address: {}]: {}",
&id,
ip_address,
err
);
ResponseError::error_response(&err)
}
};
HttpResponse::Ok().finish()
}
pub fn init_routes(config: &mut web::ServiceConfig) {
pub fn init_routes(config: &mut ServiceConfig) {
config.service(
web::scope("account")
scope::scope("/account")
.service(register)
.service(login)
.service(logout)
.service(change_password)
.service(get_profile)
.service(session_refresh),
.service(session_refresh)
.service(change_password)
.service(reset_password),
);
}