Bypass 2FA after successful login #72
@ -55,6 +55,10 @@ pub struct ChangePasswordResult(pub bool);
|
|||||||
#[rtype(result = "bool")]
|
#[rtype(result = "bool")]
|
||||||
pub struct AddSuccessful2FALogin(pub UserID, pub IpAddr);
|
pub struct AddSuccessful2FALogin(pub UserID, pub IpAddr);
|
||||||
|
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "bool")]
|
||||||
|
pub struct Clear2FALoginHistory(pub UserID);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UpdateUserResult(pub bool);
|
pub struct UpdateUserResult(pub bool);
|
||||||
|
|
||||||
@ -125,6 +129,13 @@ impl Handler<AddSuccessful2FALogin> for UsersActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Handler<Clear2FALoginHistory> for UsersActor {
|
||||||
|
type Result = <Clear2FALoginHistory as actix::Message>::Result;
|
||||||
|
fn handle(&mut self, msg: Clear2FALoginHistory, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
self.manager.clear_2fa_login_history(&msg.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Handler<GetUserRequest> for UsersActor {
|
impl Handler<GetUserRequest> for UsersActor {
|
||||||
type Result = MessageResult<GetUserRequest>;
|
type Result = MessageResult<GetUserRequest>;
|
||||||
|
|
||||||
|
@ -120,3 +120,15 @@ pub async fn delete_factor(
|
|||||||
HttpResponse::Ok().body("Removed factor!")
|
HttpResponse::Ok().body("Removed factor!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn clear_login_history(
|
||||||
|
user: CurrentUser,
|
||||||
|
users: web::Data<Addr<UsersActor>>,
|
||||||
|
) -> impl Responder {
|
||||||
|
users
|
||||||
|
.send(users_actor::Clear2FALoginHistory(user.uid.clone()))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
HttpResponse::Ok().body("History successfully cleared")
|
||||||
|
}
|
||||||
|
@ -313,4 +313,11 @@ impl EntityManager<User> {
|
|||||||
user
|
user
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_2fa_login_history(&mut self, id: &UserID) -> bool {
|
||||||
|
self.update_user(id, |mut user| {
|
||||||
|
user.last_successful_2fa = Default::default();
|
||||||
|
user
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,11 @@ async fn main() -> std::io::Result<()> {
|
|||||||
"/settings/api/two_factor/delete_factor",
|
"/settings/api/two_factor/delete_factor",
|
||||||
web::post().to(two_factor_api::delete_factor),
|
web::post().to(two_factor_api::delete_factor),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/settings/api/two_factor/clear_login_history",
|
||||||
|
// Use POST to prevent CSRF
|
||||||
|
web::post().to(two_factor_api::clear_login_history),
|
||||||
|
)
|
||||||
// Admin routes
|
// Admin routes
|
||||||
.route(
|
.route(
|
||||||
"/admin",
|
"/admin",
|
||||||
|
@ -35,8 +35,12 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if !user.last_successful_2fa.is_empty() %}
|
{% if !user.last_successful_2fa.is_empty() %}
|
||||||
<h5 style="margin-top: 50px">Successful 2FA login history</h5>
|
<div id="2fa_history_container">
|
||||||
<table class="table table-hover" style="max-width: 800px;" aria-describedby="Factors list">
|
<h5 style="margin-top: 50px">Successful 2FA login history</h5>
|
||||||
|
<p>
|
||||||
|
<a type="button" class="btn btn-danger btn-sm" onclick="clear_login_history()">Clear history</a>
|
||||||
|
</p>
|
||||||
|
<table class="table table-hover" style="max-width: 800px;" aria-describedby="Factors list">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">IP address</th>
|
<th scope="col">IP address</th>
|
||||||
@ -53,8 +57,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function delete_factor(id) {
|
async function delete_factor(id) {
|
||||||
@ -83,5 +88,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function clear_login_history() {
|
||||||
|
if (!confirm("Do you really want to clear your 2FA login history?"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch("/settings/api/two_factor/clear_login_history", {
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
|
||||||
|
let text = await res.text();
|
||||||
|
alert(text);
|
||||||
|
|
||||||
|
if (res.status == 200)
|
||||||
|
document.getElementById("2fa_history_container").remove();
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
alert("Failed to clear 2FA history!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
Loading…
Reference in New Issue
Block a user