feat: connect settings live flow to auth api

This commit is contained in:
a.tolmachev
2026-03-31 02:21:31 +03:00
parent 61718bce5a
commit 44363c0b1c
13 changed files with 502 additions and 102 deletions
+72
View File
@@ -62,6 +62,18 @@ pub struct SessionResponse {
pub memberships: Vec<WorkspaceMembershipRecord>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct UpdateProfilePayload {
pub display_name: String,
pub email: String,
}
#[derive(Clone, Debug, Deserialize)]
pub struct ChangePasswordPayload {
pub current_password: String,
pub new_password: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct OperationPayload {
pub name: String,
@@ -627,6 +639,66 @@ impl AdminService {
}))
}
pub async fn update_profile(
&self,
user_id: &crank_core::UserId,
payload: UpdateProfilePayload,
) -> Result<SessionResponse, ApiError> {
let display_name = payload.display_name.trim();
let email = payload.email.trim().to_ascii_lowercase();
if display_name.is_empty() {
return Err(ApiError::validation("display name is required"));
}
if email.is_empty() || !email.contains('@') {
return Err(ApiError::validation("a valid email address is required"));
}
let user = self
.registry
.update_user_profile(user_id, &email, display_name)
.await?;
let memberships = self.registry.list_workspaces_for_user(user_id).await?;
Ok(SessionResponse { user, memberships })
}
pub async fn change_password(
&self,
user_id: &crank_core::UserId,
payload: ChangePasswordPayload,
) -> Result<(), ApiError> {
if payload.new_password.len() < 12 {
return Err(ApiError::validation(
"new password must be at least 12 characters long",
));
}
let user = self
.registry
.get_auth_user_by_id(user_id)
.await?
.ok_or_else(|| {
ApiError::not_found(format!("user {} was not found", user_id.as_str()))
})?;
if !verify_password(
&payload.current_password,
&self.auth_settings.password_pepper,
&user.password_hash,
) {
return Err(ApiError::unauthorized("current password is invalid"));
}
let password_hash =
hash_password(&payload.new_password, &self.auth_settings.password_pepper)?;
self.registry
.update_user_password(user_id, &password_hash)
.await?;
Ok(())
}
pub async fn get_workspace(
&self,
workspace_id: &WorkspaceId,