From 53820e8b5f4311e6b3a7e1434bb9ac8dcffe58e0 Mon Sep 17 00:00:00 2001 From: Per Stark Date: Sat, 28 Dec 2024 00:07:20 +0100 Subject: [PATCH] feat: account page --- src/bin/server.rs | 3 ++ src/server/routes/html/account.rs | 70 +++++++++++++++++++++++++++++++ src/server/routes/html/index.rs | 14 ++++--- src/server/routes/html/mod.rs | 1 + src/server/routes/html/signin.rs | 23 +++++----- src/storage/types/user.rs | 4 -- templates/auth/account.html | 49 ++++++++++++++++++++++ templates/body_base.html | 2 +- 8 files changed, 142 insertions(+), 24 deletions(-) create mode 100644 src/server/routes/html/account.rs create mode 100644 templates/auth/account.html diff --git a/src/bin/server.rs b/src/bin/server.rs index 82c24ae..fbd77e9 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -24,6 +24,7 @@ use zettle_db::{ queue_length::queue_length_handler, }, html::{ + account::{set_api_key, show_account_page}, index::index_handler, search_result::search_result_handler, signin::{authenticate_user, show_signin_form}, @@ -151,6 +152,8 @@ fn html_routes( .route("/search", get(search_result_handler)) .route("/signout", get(sign_out_user)) .route("/signin", get(show_signin_form).post(authenticate_user)) + .route("/account", get(show_account_page)) + .route("/set-api-key", post(set_api_key)) .route( "/signup", get(show_signup_form).post(process_signup_and_show_verification), diff --git a/src/server/routes/html/account.rs b/src/server/routes/html/account.rs new file mode 100644 index 0000000..a57b743 --- /dev/null +++ b/src/server/routes/html/account.rs @@ -0,0 +1,70 @@ +use axum::{ + extract::State, + http::{Response, StatusCode}, + response::{Html, IntoResponse, Redirect}, +}; +use axum_session_auth::AuthSession; +use axum_session_surreal::SessionSurrealPool; +use surrealdb::{engine::any::Any, Surreal}; +use tracing::info; + +use crate::{ + error::ApiError, + page_data, + server::{routes::html::render_template, AppState}, + storage::types::user::User, +}; + +use super::render_block; + +page_data!(AccountData, "auth/account.html", { + user: User +}); + +pub async fn show_account_page( + State(state): State, + auth: AuthSession, Surreal>, +) -> Result { + if !auth.is_authenticated() { + return Ok(Redirect::to("/").into_response()); + } + + info!("{:?}", auth.current_user); + + let output = render_template( + AccountData::template_name(), + AccountData { + user: auth.current_user.unwrap(), + }, + state.templates, + )?; + + Ok(output.into_response()) +} + +pub async fn set_api_key( + State(state): State, + auth: AuthSession, Surreal>, +) -> Result { + // Early return if the user is not authenticated + let user = auth.current_user.ok_or(ApiError::AuthRequired)?; + + // Generate and set the API key + let api_key = User::set_api_key(&user.id, &state.surreal_db_client).await?; + + // Update the user's API key + let updated_user = User { + api_key: Some(api_key), + ..user + }; + + // Render the API key section block + let output = render_block( + AccountData::template_name(), + "api_key_section", + AccountData { user: updated_user }, + state.templates, + )?; + + Ok(output.into_response()) +} diff --git a/src/server/routes/html/index.rs b/src/server/routes/html/index.rs index dc5e108..feb21e3 100644 --- a/src/server/routes/html/index.rs +++ b/src/server/routes/html/index.rs @@ -24,12 +24,14 @@ pub async fn index_handler( let queue_length = state.rabbitmq_consumer.get_queue_length().await?; - let data = IndexData { - queue_length, - user: auth.current_user, - }; - - let output = render_template(IndexData::template_name(), data, state.templates)?; + let output = render_template( + IndexData::template_name(), + IndexData { + queue_length, + user: auth.current_user, + }, + state.templates, + )?; Ok(output) } diff --git a/src/server/routes/html/mod.rs b/src/server/routes/html/mod.rs index a409ff9..f0eb24e 100644 --- a/src/server/routes/html/mod.rs +++ b/src/server/routes/html/mod.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use axum::response::Html; use minijinja_autoreload::AutoReloader; +pub mod account; pub mod index; pub mod search_result; pub mod signin; diff --git a/src/server/routes/html/signin.rs b/src/server/routes/html/signin.rs index ef7fd0b..12779b2 100644 --- a/src/server/routes/html/signin.rs +++ b/src/server/routes/html/signin.rs @@ -7,10 +7,9 @@ use axum::{ use axum_htmx::{HxBoosted, HxRedirect}; use axum_session_auth::AuthSession; use axum_session_surreal::SessionSurrealPool; -use serde::{Deserialize, Serialize}; use surrealdb::{engine::any::Any, Surreal}; -use crate::{error::ApiError, server::AppState, storage::types::user::User}; +use crate::{error::ApiError, page_data, server::AppState, storage::types::user::User}; use super::{render_block, render_template}; @@ -21,10 +20,7 @@ pub struct SignupParams { pub remember_me: Option, } -#[derive(Serialize)] -struct PageData { - // name: String, -} +page_data!(ShowSignInForm, "auth/signin_form.html", {}); pub async fn show_signin_form( State(state): State, @@ -36,12 +32,16 @@ pub async fn show_signin_form( } let output = match boosted { true => render_block( - "auth/signin_form.html", + ShowSignInForm::template_name(), "body", - PageData {}, + ShowSignInForm {}, + state.templates, + )?, + false => render_template( + ShowSignInForm::template_name(), + ShowSignInForm {}, state.templates, )?, - false => render_template("auth/signin_form.html", PageData {}, state.templates)?, }; Ok(output.into_response()) @@ -54,10 +54,7 @@ pub async fn authenticate_user( ) -> Result { let user = User::authenticate(form.email, form.password, &state.surreal_db_client).await?; auth.login_user(user.id); - if form - .remember_me - .is_some_and(|string| string == "on".to_string()) - { + if form.remember_me.is_some_and(|string| string == *"on") { auth.remember_user(true); } Ok((HxRedirect::from(Uri::from_static("/")), StatusCode::OK).into_response()) diff --git a/src/storage/types/user.rs b/src/storage/types/user.rs index 94a10c4..f94000e 100644 --- a/src/storage/types/user.rs +++ b/src/storage/types/user.rs @@ -134,10 +134,6 @@ impl User { Err(ApiError::UserNotFound) } } - pub async fn reset_api_key(id: &str, db: &SurrealDbClient) -> Result { - // Simply call set_api_key to generate and set a new key - Self::set_api_key(id, db).await - } pub async fn revoke_api_key(id: &str, db: &SurrealDbClient) -> Result<(), ApiError> { let user: Option = db diff --git a/templates/auth/account.html b/templates/auth/account.html new file mode 100644 index 0000000..1ce95cf --- /dev/null +++ b/templates/auth/account.html @@ -0,0 +1,49 @@ +{% extends "body_base.html" %} +{% block content %} + +
+
+

Account Settings

+
+ + +
+
+ + {% block api_key_section %} + {% if user.api_key %} + + {% else %} + + {% endif %} + {% endblock %} +
+
+ +
+
+ +
+
+ +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/body_base.html b/templates/body_base.html index 7617ce4..da6d920 100644 --- a/templates/body_base.html +++ b/templates/body_base.html @@ -20,7 +20,7 @@ -
+
{% block content %}{% endblock %}