Some checks failed
/ build-all-services (push) Has been cancelled
For task T155
171 lines
7.1 KiB
Rust
171 lines
7.1 KiB
Rust
/*
|
|
* asklyphe-frontend routes/user_settings.rs
|
|
* - http routes for the settings page
|
|
*
|
|
* Copyright (C) 2025 Real Microsoft, LLC
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
use std::sync::Arc;
|
|
use std::sync::atomic::Ordering;
|
|
use askama::Template;
|
|
use askama_axum::IntoResponse;
|
|
use asklyphe_common::nats::authservice::{AuthError, AuthRequest, AuthResponse, AuthServiceQuery, AuthServiceRequest, AuthServiceResponse, LogoutRequest, LogoutResponse};
|
|
use asklyphe_common::nats::authservice::profile::{ThemeChangeRequest, ThemeChangeResponse, UserInfoRequest, UserInfoResponse};
|
|
use asklyphe_common::nats::comms;
|
|
use asklyphe_common::nats::comms::{ServiceError, ServiceResponse};
|
|
use async_nats::jetstream;
|
|
use axum::{Extension, Form};
|
|
use axum::response::Redirect;
|
|
use axum_extra::extract::CookieJar;
|
|
use serde::Deserialize;
|
|
use tokio::sync::Mutex;
|
|
use tracing::error;
|
|
use crate::{BUILT_ON, GIT_COMMIT, Opts, ALPHA, VERSION, WEBSITE_COUNT, YEAR};
|
|
use crate::routes::{authenticate_user, Themes, UserInfo};
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "user_settings.html")]
|
|
pub struct SettingsTemplate {
|
|
themes: Vec<Themes>,
|
|
error: Option<String>,
|
|
|
|
info: UserInfo,
|
|
search_query: String,
|
|
version: String,
|
|
git_commit: String,
|
|
built_on: String,
|
|
year: String,
|
|
alpha: bool,
|
|
count: u64,
|
|
theme: Themes,
|
|
true_theme: Themes,
|
|
}
|
|
|
|
pub async fn user_settings(
|
|
jar: CookieJar,
|
|
Extension(nats): Extension<Arc<jetstream::Context>>,
|
|
Extension(opts): Extension<Opts>,
|
|
) -> impl IntoResponse {
|
|
if let Some(token) = jar.get("token") {
|
|
let token = token.value().to_string();
|
|
let info = match authenticate_user(nats.clone(), token).await {
|
|
Ok(i) => i,
|
|
Err(e) => {
|
|
return (jar.remove("token"), crate::routes::index::frontpage_error(e.as_str(), opts.auth_url.clone())).into_response();
|
|
}
|
|
};
|
|
let theme = info.get_theme();
|
|
SettingsTemplate {
|
|
themes: Themes::get_all_themes(),
|
|
error: None,
|
|
info: info.clone(),
|
|
search_query: "".to_string(),
|
|
version: VERSION.to_string(),
|
|
git_commit: GIT_COMMIT.to_string(),
|
|
built_on: BUILT_ON.to_string(),
|
|
year: YEAR.to_string(),
|
|
alpha: ALPHA,
|
|
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
|
theme,
|
|
true_theme: info.get_true_theme(),
|
|
}.into_response()
|
|
} else {
|
|
Redirect::temporary("/").into_response()
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct ThemeChangeForm {
|
|
pub theme: Option<String>,
|
|
}
|
|
|
|
pub async fn theme_change_post(
|
|
jar: CookieJar,
|
|
Extension(nats): Extension<Arc<jetstream::Context>>,
|
|
Extension(opts): Extension<Opts>,
|
|
Form(input): Form<ThemeChangeForm>,
|
|
) -> impl IntoResponse {
|
|
fn settings_error(info: UserInfo, theme: Themes, error: String) -> impl IntoResponse {
|
|
SettingsTemplate {
|
|
themes: Themes::get_all_themes(),
|
|
error: Some(error),
|
|
info: info.clone(),
|
|
search_query: "".to_string(),
|
|
version: VERSION.to_string(),
|
|
git_commit: GIT_COMMIT.to_string(),
|
|
built_on: BUILT_ON.to_string(),
|
|
year: YEAR.to_string(),
|
|
alpha: ALPHA,
|
|
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
|
theme,
|
|
true_theme: info.get_true_theme(),
|
|
}.into_response()
|
|
}
|
|
|
|
if let Some(token) = jar.get("token") {
|
|
let token = token.value().to_string();
|
|
let info = match authenticate_user(nats.clone(), token.clone()).await {
|
|
Ok(i) => i,
|
|
Err(e) => {
|
|
return (jar.remove("token"), crate::routes::index::frontpage_error(e.as_str(), opts.auth_url.clone())).into_response();
|
|
}
|
|
};
|
|
|
|
let theme = info.get_theme();
|
|
|
|
if let Some(theme_input) = &input.theme {
|
|
if !Themes::get_all_themes().iter().map(|x| x.internal_name().to_string()).collect::<Vec<String>>().contains(&theme_input) {
|
|
return settings_error(info, theme.clone(), "invalid input, please try again!".to_string()).into_response();
|
|
}
|
|
}
|
|
|
|
let response = comms::query_service(comms::Query::AuthService(AuthServiceQuery {
|
|
request: AuthServiceRequest::ThemeChangeRequest(ThemeChangeRequest {
|
|
token,
|
|
theme: input.theme.unwrap_or("default".to_string()),
|
|
}),
|
|
replyto: "".to_string(),
|
|
}), &nats, false).await;
|
|
if let Err(e) = response {
|
|
error!("nats error: {:?}", e);
|
|
settings_error(info, theme, "internal server error occurred! if the error persists, contact a developer!".to_string()).into_response()
|
|
} else {
|
|
let response = response.unwrap();
|
|
match response {
|
|
ServiceResponse::AuthService(r) => {
|
|
match r {
|
|
AuthServiceResponse::ThemeChangeResponse(r) => {
|
|
match r {
|
|
ThemeChangeResponse::Success => {
|
|
Redirect::to("/user_settings").into_response()
|
|
}
|
|
ThemeChangeResponse::Logout => {
|
|
(jar.remove("token"), crate::routes::index::frontpage_error("your session token was invalid, please try logging in again", opts.auth_url.clone())).into_response()
|
|
}
|
|
ThemeChangeResponse::InternalServerError => {
|
|
settings_error(info, theme, "internal server error occurred! if the error persists, contact a developer!".to_string()).into_response()
|
|
}
|
|
}
|
|
}
|
|
x => {
|
|
error!("ERROR! RECV WRONG AUTHSERVICE RESPONSE WHEN ASKING FOR THEME CHANGE! INVESTIGATE ASAP! {x}");
|
|
settings_error(info, theme, "internal server error occurred! if the error persists, contact a developer!".to_string()).into_response()
|
|
}
|
|
}
|
|
}
|
|
x => {
|
|
error!("ERROR! RECV WRONG SERVICE RESPONSE WHEN ASKING AUTHSERVICE! INVESTIGATE ASAP!");
|
|
settings_error(info, theme, "internal server error occurred! if the error persists, contact a developer!".to_string()).into_response()
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
Redirect::to("/").into_response()
|
|
}
|
|
}
|