Add password management facilities
This commit is contained in:
parent
2b5ee33762
commit
b03fe0e5f7
5
src/user_management/pages/password/success.gmi
Normal file
5
src/user_management/pages/password/success.gmi
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Password Updated
|
||||||
|
|
||||||
|
To add a certificate, log in using the new certificate and provide your username and password.
|
||||||
|
|
||||||
|
=> /account Back to settings
|
|
@ -2,10 +2,12 @@ use anyhow::Result;
|
||||||
use tokio::net::ToSocketAddrs;
|
use tokio::net::ToSocketAddrs;
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{Serialize, de::DeserializeOwned};
|
||||||
|
|
||||||
use crate::{Request, Response};
|
use crate::{Document, Request, Response};
|
||||||
|
use crate::types::document::HeadingLevel;
|
||||||
use crate::user_management::{User, RegisteredUser, UserManagerError};
|
use crate::user_management::{User, RegisteredUser, UserManagerError};
|
||||||
|
|
||||||
const UNAUTH: &str = include_str!("pages/unauth.gmi");
|
const UNAUTH: &str = include_str!("pages/unauth.gmi");
|
||||||
|
const NSI: &str = include_str!("pages/nsi.gmi");
|
||||||
|
|
||||||
pub trait UserManagementRoutes: private::Sealed {
|
pub trait UserManagementRoutes: private::Sealed {
|
||||||
fn add_um_routes<UserData: Serialize + DeserializeOwned + Default + 'static>(self, redir: &'static str) -> Self;
|
fn add_um_routes<UserData: Serialize + DeserializeOwned + Default + 'static>(self, redir: &'static str) -> Self;
|
||||||
|
@ -17,6 +19,7 @@ impl<A: ToSocketAddrs> UserManagementRoutes for crate::Builder<A> {
|
||||||
.add_route("/account/askcert", move|r|handle_ask_cert::<UserData>(r, redir))
|
.add_route("/account/askcert", move|r|handle_ask_cert::<UserData>(r, redir))
|
||||||
.add_route("/account/register", move|r|handle_register::<UserData>(r, redir))
|
.add_route("/account/register", move|r|handle_register::<UserData>(r, redir))
|
||||||
.add_route("/account/login", move|r|handle_login::<UserData>(r, redir))
|
.add_route("/account/login", move|r|handle_login::<UserData>(r, redir))
|
||||||
|
.add_route("/account/password", handle_password::<UserData>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +29,7 @@ async fn handle_base<UserData: Serialize + DeserializeOwned>(request: Request, r
|
||||||
Response::success_gemini(UNAUTH)
|
Response::success_gemini(UNAUTH)
|
||||||
},
|
},
|
||||||
User::NotSignedIn(_) => {
|
User::NotSignedIn(_) => {
|
||||||
Response::success_gemini(include_str!("pages/nsi.gmi"))
|
Response::success_gemini(NSI)
|
||||||
},
|
},
|
||||||
User::SignedIn(user) => {
|
User::SignedIn(user) => {
|
||||||
render_settings_menu(user, redirect)
|
render_settings_menu(user, redirect)
|
||||||
|
@ -126,15 +129,63 @@ async fn handle_login<UserData: Serialize + DeserializeOwned + Default>(request:
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_password<UserData: Serialize + DeserializeOwned + Default>(request: Request) -> Result<Response> {
|
||||||
|
Ok(match request.user::<UserData>()? {
|
||||||
|
User::Unauthenticated => {
|
||||||
|
Response::success_gemini(UNAUTH)
|
||||||
|
},
|
||||||
|
User::NotSignedIn(_) => {
|
||||||
|
Response::success_gemini(NSI)
|
||||||
|
},
|
||||||
|
User::SignedIn(mut user) => {
|
||||||
|
if let Some(password) = request.input() {
|
||||||
|
user.set_password(password)?;
|
||||||
|
Response::success_gemini(include_str!("pages/password/success.gmi"))
|
||||||
|
} else {
|
||||||
|
Response::input(
|
||||||
|
format!("Please enter a {}password",
|
||||||
|
if user.has_password() {
|
||||||
|
"new "
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn render_settings_menu<UserData: Serialize + DeserializeOwned>(
|
fn render_settings_menu<UserData: Serialize + DeserializeOwned>(
|
||||||
user: RegisteredUser<UserData>,
|
user: RegisteredUser<UserData>,
|
||||||
redirect: &str
|
redirect: &str
|
||||||
) -> Response {
|
) -> Response {
|
||||||
Response::success_gemini(format!(
|
Document::new()
|
||||||
include_str!("pages/settings.gmi"),
|
.add_heading(HeadingLevel::H1, "User Settings")
|
||||||
username = user.username(),
|
.add_blank_line()
|
||||||
redirect = redirect,
|
.add_text(&format!("Welcome {}!", user.username()))
|
||||||
))
|
.add_blank_line()
|
||||||
|
.add_link(redirect, "Back to the app")
|
||||||
|
.add_blank_line()
|
||||||
|
.add_text(
|
||||||
|
if user.has_password() {
|
||||||
|
concat!(
|
||||||
|
"You currently have a password set. This can be used to link any new",
|
||||||
|
" certificates or clients to your account. If you don't remember your",
|
||||||
|
" password, or would like to change it, you may do so here.",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
concat!(
|
||||||
|
"You don't currently have a password set! Without a password, you cannot",
|
||||||
|
" link any new certificates to your account, and if you lose your current",
|
||||||
|
" client or certificate, you won't be able to recover your account.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.add_blank_line()
|
||||||
|
.add_link("/account/password", if user.has_password() { "Change password" } else { "Set password" })
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
mod private {
|
mod private {
|
||||||
|
|
Loading…
Reference in a new issue