mirror of
https://github.com/nitnelave/lldap.git
synced 2023-04-12 14:25:13 +00:00
app: improve error message for wrong/expired reset token
This commit is contained in:
parent
193a0fd710
commit
bebb00aa2e
@ -32,7 +32,7 @@ pub struct App {
|
|||||||
user_info: Option<(String, bool)>,
|
user_info: Option<(String, bool)>,
|
||||||
redirect_to: Option<AppRoute>,
|
redirect_to: Option<AppRoute>,
|
||||||
route_dispatcher: RouteAgentDispatcher,
|
route_dispatcher: RouteAgentDispatcher,
|
||||||
password_reset_enabled: bool,
|
password_reset_enabled: Option<bool>,
|
||||||
task: Option<FetchTask>,
|
task: Option<FetchTask>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ impl Component for App {
|
|||||||
}),
|
}),
|
||||||
redirect_to: Self::get_redirect_route(),
|
redirect_to: Self::get_redirect_route(),
|
||||||
route_dispatcher: RouteAgentDispatcher::new(),
|
route_dispatcher: RouteAgentDispatcher::new(),
|
||||||
password_reset_enabled: false,
|
password_reset_enabled: None,
|
||||||
task: None,
|
task: None,
|
||||||
};
|
};
|
||||||
app.task = Some(
|
app.task = Some(
|
||||||
@ -95,22 +95,21 @@ impl Component for App {
|
|||||||
Msg::Logout => {
|
Msg::Logout => {
|
||||||
self.user_info = None;
|
self.user_info = None;
|
||||||
self.redirect_to = None;
|
self.redirect_to = None;
|
||||||
|
self.route_dispatcher
|
||||||
|
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
|
||||||
}
|
}
|
||||||
Msg::PasswordResetProbeFinished(Ok(enabled)) => {
|
Msg::PasswordResetProbeFinished(Ok(enabled)) => {
|
||||||
self.task = None;
|
self.task = None;
|
||||||
self.password_reset_enabled = enabled;
|
self.password_reset_enabled = Some(enabled);
|
||||||
}
|
}
|
||||||
Msg::PasswordResetProbeFinished(Err(err)) => {
|
Msg::PasswordResetProbeFinished(Err(err)) => {
|
||||||
self.task = None;
|
self.task = None;
|
||||||
|
self.password_reset_enabled = Some(false);
|
||||||
ConsoleService::error(&format!(
|
ConsoleService::error(&format!(
|
||||||
"Could not probe for password reset support: {err:#}"
|
"Could not probe for password reset support: {err:#}"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.user_info.is_none() {
|
|
||||||
self.route_dispatcher
|
|
||||||
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +159,7 @@ impl App {
|
|||||||
let route_service = RouteService::<()>::new();
|
let route_service = RouteService::<()>::new();
|
||||||
let current_route = route_service.get_path();
|
let current_route = route_service.get_path();
|
||||||
if current_route.contains("reset-password") {
|
if current_route.contains("reset-password") {
|
||||||
if !self.password_reset_enabled {
|
if self.password_reset_enabled == Some(false) {
|
||||||
self.route_dispatcher
|
self.route_dispatcher
|
||||||
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
|
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
|
||||||
}
|
}
|
||||||
@ -195,11 +194,11 @@ impl App {
|
|||||||
switch: AppRoute,
|
switch: AppRoute,
|
||||||
link: &ComponentLink<Self>,
|
link: &ComponentLink<Self>,
|
||||||
is_admin: bool,
|
is_admin: bool,
|
||||||
password_reset_enabled: bool,
|
password_reset_enabled: Option<bool>,
|
||||||
) -> Html {
|
) -> Html {
|
||||||
match switch {
|
match switch {
|
||||||
AppRoute::Login => html! {
|
AppRoute::Login => html! {
|
||||||
<LoginForm on_logged_in=link.callback(Msg::Login) password_reset_enabled=password_reset_enabled/>
|
<LoginForm on_logged_in=link.callback(Msg::Login) password_reset_enabled=password_reset_enabled.unwrap_or(false)/>
|
||||||
},
|
},
|
||||||
AppRoute::CreateUser => html! {
|
AppRoute::CreateUser => html! {
|
||||||
<CreateUserForm/>
|
<CreateUserForm/>
|
||||||
@ -234,23 +233,20 @@ impl App {
|
|||||||
AppRoute::ChangePassword(username) => html! {
|
AppRoute::ChangePassword(username) => html! {
|
||||||
<ChangePasswordForm username=username is_admin=is_admin />
|
<ChangePasswordForm username=username is_admin=is_admin />
|
||||||
},
|
},
|
||||||
AppRoute::StartResetPassword => {
|
AppRoute::StartResetPassword => match password_reset_enabled {
|
||||||
if password_reset_enabled {
|
Some(true) => html! { <ResetPasswordStep1Form /> },
|
||||||
html! {
|
Some(false) => {
|
||||||
<ResetPasswordStep1Form />
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
|
App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
AppRoute::FinishResetPassword(token) => html! {
|
None => html! {},
|
||||||
if password_reset_enabled {
|
},
|
||||||
html! {
|
AppRoute::FinishResetPassword(token) => match password_reset_enabled {
|
||||||
<ResetPasswordStep2Form token=token />
|
Some(true) => html! { <ResetPasswordStep2Form token=token /> },
|
||||||
}
|
Some(false) => {
|
||||||
} else {
|
|
||||||
App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
|
App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
|
||||||
}
|
}
|
||||||
|
None => html! {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,50 +283,48 @@ impl App {
|
|||||||
} } else { html!{} } }
|
} } else { html!{} } }
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="dropdown text-end">
|
{
|
||||||
<a href="#"
|
if let Some((user_id, _)) = &self.user_info {
|
||||||
class="d-block link-dark text-decoration-none dropdown-toggle"
|
html! {
|
||||||
id="dropdownUser"
|
<div class="dropdown text-end">
|
||||||
data-bs-toggle="dropdown"
|
<a href="#"
|
||||||
aria-expanded="false">
|
class="d-block link-dark text-decoration-none dropdown-toggle"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg"
|
id="dropdownUser"
|
||||||
width="32"
|
data-bs-toggle="dropdown"
|
||||||
height="32"
|
aria-expanded="false">
|
||||||
fill="currentColor"
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
class="bi bi-person-circle"
|
width="32"
|
||||||
viewBox="0 0 16 16">
|
height="32"
|
||||||
<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
fill="currentColor"
|
||||||
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
|
class="bi bi-person-circle"
|
||||||
</svg>
|
viewBox="0 0 16 16">
|
||||||
{
|
<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
||||||
if let Some((user_id, _)) = &self.user_info {
|
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
|
||||||
html! {
|
</svg>
|
||||||
<span class="ms-2">
|
<span class="ms-2">
|
||||||
{user_id}
|
{user_id}
|
||||||
</span>
|
</span>
|
||||||
}
|
</a>
|
||||||
} else { html!{} }
|
<ul
|
||||||
|
class="dropdown-menu text-small dropdown-menu-lg-end"
|
||||||
|
aria-labelledby="dropdownUser1"
|
||||||
|
style="">
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
classes="dropdown-item"
|
||||||
|
route=AppRoute::UserDetails(user_id.clone())>
|
||||||
|
{"View details"}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li><hr class="dropdown-divider" /></li>
|
||||||
|
<li>
|
||||||
|
<LogoutButton on_logged_out=self.link.callback(|_| Msg::Logout) />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</a>
|
} else { html!{} }
|
||||||
{if let Some((user_id, _)) = &self.user_info { html! {
|
}
|
||||||
<ul
|
|
||||||
class="dropdown-menu text-small dropdown-menu-lg-end"
|
|
||||||
aria-labelledby="dropdownUser1"
|
|
||||||
style="">
|
|
||||||
<li>
|
|
||||||
<Link
|
|
||||||
classes="dropdown-item"
|
|
||||||
route=AppRoute::UserDetails(user_id.clone())>
|
|
||||||
{"View details"}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
<li><hr class="dropdown-divider" /></li>
|
|
||||||
<li>
|
|
||||||
<LogoutButton on_logged_out=self.link.callback(|_| Msg::Logout) />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
} } else { html!{} } }
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
components::router::AppRoute,
|
components::router::{AppRoute, NavButton},
|
||||||
infra::{
|
infra::{
|
||||||
api::HostService,
|
api::HostService,
|
||||||
common_component::{CommonComponent, CommonComponentParts},
|
common_component::{CommonComponent, CommonComponentParts},
|
||||||
@ -158,9 +158,17 @@ impl Component for ResetPasswordStep2Form {
|
|||||||
}
|
}
|
||||||
(None, Some(e)) => {
|
(None, Some(e)) => {
|
||||||
return html! {
|
return html! {
|
||||||
<div class="alert alert-danger">
|
<>
|
||||||
{e.to_string() }
|
<div class="alert alert-danger">
|
||||||
</div>
|
{e.to_string() }
|
||||||
|
</div>
|
||||||
|
<NavButton
|
||||||
|
classes="btn-link btn"
|
||||||
|
disabled=self.common.is_task_running()
|
||||||
|
route=AppRoute::Login>
|
||||||
|
{"Back"}
|
||||||
|
</NavButton>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -214,11 +214,15 @@ where
|
|||||||
let token = request
|
let token = request
|
||||||
.match_info()
|
.match_info()
|
||||||
.get("token")
|
.get("token")
|
||||||
.ok_or_else(|| TcpError::BadRequest("Missing reset token".to_string()))?;
|
.ok_or_else(|| TcpError::BadRequest("Missing reset token".to_owned()))?;
|
||||||
let user_id = data
|
let user_id = data
|
||||||
.backend_handler
|
.backend_handler
|
||||||
.get_user_id_for_password_reset_token(token)
|
.get_user_id_for_password_reset_token(token)
|
||||||
.await?;
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
debug!("Reset token error: {e:#}");
|
||||||
|
TcpError::NotFoundError("Wrong or expired reset token".to_owned())
|
||||||
|
})?;
|
||||||
let _ = data
|
let _ = data
|
||||||
.backend_handler
|
.backend_handler
|
||||||
.delete_password_reset_token(token)
|
.delete_password_reset_token(token)
|
||||||
|
@ -37,6 +37,8 @@ pub enum TcpError {
|
|||||||
BadRequest(String),
|
BadRequest(String),
|
||||||
#[error("Internal server error: `{0}`")]
|
#[error("Internal server error: `{0}`")]
|
||||||
InternalServerError(String),
|
InternalServerError(String),
|
||||||
|
#[error("Not found: `{0}`")]
|
||||||
|
NotFoundError(String),
|
||||||
#[error("Unauthorized: `{0}`")]
|
#[error("Unauthorized: `{0}`")]
|
||||||
UnauthorizedError(String),
|
UnauthorizedError(String),
|
||||||
}
|
}
|
||||||
@ -57,6 +59,7 @@ pub(crate) fn error_to_http_response(error: TcpError) -> HttpResponse {
|
|||||||
| DomainError::EntityNotFound(_) => HttpResponse::BadRequest(),
|
| DomainError::EntityNotFound(_) => HttpResponse::BadRequest(),
|
||||||
},
|
},
|
||||||
TcpError::BadRequest(_) => HttpResponse::BadRequest(),
|
TcpError::BadRequest(_) => HttpResponse::BadRequest(),
|
||||||
|
TcpError::NotFoundError(_) => HttpResponse::NotFound(),
|
||||||
TcpError::InternalServerError(_) => HttpResponse::InternalServerError(),
|
TcpError::InternalServerError(_) => HttpResponse::InternalServerError(),
|
||||||
TcpError::UnauthorizedError(_) => HttpResponse::Unauthorized(),
|
TcpError::UnauthorizedError(_) => HttpResponse::Unauthorized(),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user