feat: set user password

This commit is contained in:
Fu Zi Xiang 2023-10-13 16:32:28 +08:00
parent 9458c7714c
commit de5a33da97
No known key found for this signature in database
6 changed files with 81 additions and 7 deletions

View File

@ -10,3 +10,9 @@ pub struct LoginRequest {
pub struct LoginResponse {
pub access_token: String,
}
#[derive(Deserialize)]
pub struct PutUserRequest {
pub email: String,
pub password: String,
}

View File

@ -1,4 +1,5 @@
use crate::error::WebApiError;
use crate::models::PutUserRequest;
use crate::response::WebApiResponse;
use crate::session::{self, UserSession};
use crate::{models::LoginRequest, AppState};
@ -19,10 +20,31 @@ pub fn router() -> Router<AppState> {
// TODO
.route("/login", post(login_handler))
.route("/logout", post(logout_handler))
.route("/user/:param", post(post_user_handler).delete(delete_user_handler))
.route("/user/:param", post(post_user_handler).delete(delete_user_handler).put(put_user_handler))
.route("/user/:email/generate-link", post(post_user_generate_link_handler))
}
pub async fn put_user_handler(
State(state): State<AppState>,
session: UserSession,
Path(user_uuid): Path<String>,
Json(param): Json<PutUserRequest>,
) -> Result<WebApiResponse<User>, WebApiError<'static>> {
let res = state
.gotrue_client
.admin_put_user(
&session.access_token,
&user_uuid,
&AdminUserParams {
email: param.email.to_owned(),
password: Some(param.password.to_owned()),
..Default::default()
},
)
.await?;
Ok(res.into())
}
pub async fn post_user_generate_link_handler(
State(state): State<AppState>,
session: UserSession,

View File

@ -47,14 +47,15 @@
const newPassword = document.getElementById("newPassword").value;
let confirmed = confirm("Set new password?");
if (confirmed && newPassword) {
fetch("/web-api/set_user_password", {
method: "POST",
const user_uuid = "{{ user.id|escape }}";
fetch(`/web-api/user/${user_uuid}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: "{{ user.id }}",
newPassword: newPassword,
email: "{{ user.email|escape }}",
password: newPassword,
}),
})
.then((response) => {

View File

@ -163,6 +163,22 @@ impl Client {
check_gotrue_result(resp).await
}
pub async fn admin_put_user(
&self,
access_token: &str,
user_uuid: &str,
admin_user_params: &AdminUserParams,
) -> Result<User, GoTrueError> {
let resp = self
.client
.put(format!("{}/admin/users/{}", self.base_url, user_uuid))
.header("Authorization", format!("Bearer {}", access_token))
.json(&admin_user_params)
.send()
.await?;
to_gotrue_result(resp).await
}
pub async fn admin_add_user(
&self,
access_token: &str,

View File

@ -27,10 +27,12 @@ pub async fn from_body<T>(resp: reqwest::Response) -> Result<T, Error>
where
T: serde::de::DeserializeOwned,
{
let status_code = resp.status();
let bytes = resp.bytes().await?;
serde_json::from_slice(&bytes).map_err(|e| {
anyhow!(
"deserialize error: {}, body: {}",
"deserialize error: {}, status: {}, body: {}",
status_code,
e,
String::from_utf8_lossy(&bytes)
)

View File

@ -12,7 +12,7 @@ use crate::{
};
#[tokio::test]
async fn admin_user_create_and_list_delete() {
async fn admin_user_create_list_edit_delete() {
let http_client = reqwest::Client::new();
let gotrue_client = Client::new(http_client, "http://localhost:9998");
let admin_token = gotrue_client
@ -51,6 +51,7 @@ async fn admin_user_create_and_list_delete() {
.unwrap();
assert!(user_token.user.email_confirmed_at.is_some());
// list users
let users = gotrue_client
.admin_list_user(&admin_token.access_token)
.await
@ -60,6 +61,32 @@ async fn admin_user_create_and_list_delete() {
// should be able to find user that was just created
let new_user = users.iter().find(|u| u.email == user_email).unwrap();
// change password for user
let new_password = "Hello456!";
let _ = gotrue_client
.admin_put_user(
&admin_token.access_token,
new_user.id.as_str(),
&AdminUserParams {
email: user_email.clone(),
password: Some(new_password.to_owned()),
..Default::default()
},
)
.await
.unwrap();
assert_eq!(user.email, user_email);
assert!(user.email_confirmed_at.is_some());
// login user with new password
let _ = gotrue_client
.token(&Grant::Password(PasswordGrant {
email: user_email.clone(),
password: new_password.to_string(),
}))
.await
.unwrap();
// delete user that was just created
gotrue_client
.admin_delete_user(