feat(webserver): add reset_user_auth_token mutation (#1001)
* feat(webserver): add reset_user_auth_token mutation * fix * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>r0.7
parent
f00b2c3334
commit
03c418340a
|
|
@ -10,6 +10,7 @@ enum WorkerKind {
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
resetRegistrationToken: String!
|
resetRegistrationToken: String!
|
||||||
|
resetUserAuthToken: Boolean!
|
||||||
register(email: String!, password1: String!, password2: String!, invitationCode: String): RegisterResponse!
|
register(email: String!, password1: String!, password2: String!, invitationCode: String): RegisterResponse!
|
||||||
tokenAuth(email: String!, password: String!): TokenAuthResponse!
|
tokenAuth(email: String!, password: String!): TokenAuthResponse!
|
||||||
verifyToken(token: String!): VerifyTokenResponse!
|
verifyToken(token: String!): VerifyTokenResponse!
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,8 @@ pub trait AuthenticationService: Send + Sync {
|
||||||
async fn create_invitation(&self, email: String) -> Result<i32>;
|
async fn create_invitation(&self, email: String) -> Result<i32>;
|
||||||
async fn list_invitations(&self) -> Result<Vec<Invitation>>;
|
async fn list_invitations(&self) -> Result<Vec<Invitation>>;
|
||||||
async fn delete_invitation(&self, id: i32) -> Result<i32>;
|
async fn delete_invitation(&self, id: i32) -> Result<i32>;
|
||||||
|
|
||||||
|
async fn reset_user_auth_token(&self, email: &str) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,18 @@ impl Mutation {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn reset_user_auth_token(ctx: &Context) -> Result<bool> {
|
||||||
|
if let Some(claims) = &ctx.claims {
|
||||||
|
ctx.locator
|
||||||
|
.auth()
|
||||||
|
.reset_user_auth_token(&claims.sub)
|
||||||
|
.await?;
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Err(CoreError::Unauthorized("You're not logged in"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn register(
|
async fn register(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
email: String,
|
email: String,
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,10 @@ impl AuthenticationService for DbConn {
|
||||||
async fn delete_invitation(&self, id: i32) -> Result<i32> {
|
async fn delete_invitation(&self, id: i32) -> Result<i32> {
|
||||||
self.delete_invitation(id).await
|
self.delete_invitation(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn reset_user_auth_token(&self, email: &str) -> Result<()> {
|
||||||
|
self.reset_user_auth_token_by_email(email).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn password_hash(raw: &str) -> password_hash::Result<String> {
|
fn password_hash(raw: &str) -> password_hash::Result<String> {
|
||||||
|
|
@ -460,4 +464,16 @@ mod tests {
|
||||||
// expire time should be no change
|
// expire time should be no change
|
||||||
assert_eq!(resp1.refresh_expires_at, resp2.refresh_expires_at);
|
assert_eq!(resp1.refresh_expires_at, resp2.refresh_expires_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_reset_user_auth_token() {
|
||||||
|
let conn = DbConn::new_in_memory().await.unwrap();
|
||||||
|
register_admin_user(&conn).await;
|
||||||
|
|
||||||
|
let user = conn.get_user_by_email(ADMIN_EMAIL).await.unwrap().unwrap();
|
||||||
|
conn.reset_user_auth_token(&user.email).await.unwrap();
|
||||||
|
|
||||||
|
let user2 = conn.get_user_by_email(ADMIN_EMAIL).await.unwrap().unwrap();
|
||||||
|
assert_ne!(user.auth_token, user2.auth_token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,16 +162,17 @@ impl DbConn {
|
||||||
id.is_ok()
|
id.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reset_auth_token(&self, id: i32) -> Result<i32> {
|
pub async fn reset_user_auth_token_by_email(&self, email: &str) -> Result<()> {
|
||||||
|
let email = email.to_owned();
|
||||||
self.conn
|
self.conn
|
||||||
.call(move |c| {
|
.call(move |c| {
|
||||||
let mut stmt = c.prepare(r#"UPDATE users SET auth_token = ? WHERE id = ?"#)?;
|
let mut stmt = c.prepare(r#"UPDATE users SET auth_token = ? WHERE email = ?"#)?;
|
||||||
stmt.execute((Uuid::new_v4().to_string(), id))?;
|
stmt.execute((generate_auth_token(), email))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(id)
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +216,9 @@ mod tests {
|
||||||
|
|
||||||
assert!(conn.verify_auth_token(&user.auth_token).await);
|
assert!(conn.verify_auth_token(&user.auth_token).await);
|
||||||
|
|
||||||
conn.reset_auth_token(id).await.unwrap();
|
conn.reset_user_auth_token_by_email(&user.email)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let new_user = conn.get_user(id).await.unwrap().unwrap();
|
let new_user = conn.get_user(id).await.unwrap().unwrap();
|
||||||
assert_eq!(user.email, new_user.email);
|
assert_eq!(user.email, new_user.email);
|
||||||
assert_ne!(user.auth_token, new_user.auth_token);
|
assert_ne!(user.auth_token, new_user.auth_token);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue