diff --git a/services/identity/src/database/device_list.rs b/services/identity/src/database/device_list.rs --- a/services/identity/src/database/device_list.rs +++ b/services/identity/src/database/device_list.rs @@ -1470,6 +1470,33 @@ Ok(()) } + /// Reset device list to empty array and remove devices data. + /// Ran during privileged password reset + #[tracing::instrument(skip_all)] + pub async fn reset_device_list( + &self, + user_id: &str, + ) -> Result { + let mut devices_being_removed: Vec = Vec::new(); + let update_result = self + .transact_update_devicelist(user_id, |current_list, _| { + devices_being_removed.extend(current_list.clone()); + + debug!("Resetting device list"); + *current_list = Vec::new(); + + Ok(UpdateOperationInfo::identity_generated()) + }) + .await?; + + // delete device data and invalidate CSAT for removed devices + self + .clean_up_devices_data(user_id, devices_being_removed) + .await?; + + Ok(update_result) + } + /// applies updated device list received from primary device pub async fn apply_devicelist_update( &self, @@ -1523,10 +1550,21 @@ }) .await?; - if !remove_device_data { - return Ok(update_result); + if remove_device_data { + self + .clean_up_devices_data(user_id, devices_being_removed) + .await?; } + Ok(update_result) + } + + /// called internally when removing devices from device list + async fn clean_up_devices_data( + &self, + user_id: &str, + devices_being_removed: Vec, + ) -> Result<(), Error> { // delete device data and invalidate CSAT for removed devices debug!( "{} devices have been removed from device list. Clearing data...", @@ -1552,8 +1590,7 @@ consume_error(result); }); } - - Ok(update_result) + Ok(()) } /// Performs a transactional update of the device list for the user. Afterwards diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs --- a/services/identity/src/grpc_services/authenticated.rs +++ b/services/identity/src/grpc_services/authenticated.rs @@ -787,9 +787,14 @@ self .db_client - .update_user_password(state.user_id, password_file) + .update_user_password(state.user_id.clone(), password_file) .await?; + // Delete backups, blob holders and tunnelbroker device tokens. + // This has to be done before resetting device list. + self.delete_services_data_for_user(&state.user_id).await?; + self.db_client.reset_device_list(&state.user_id).await?; + let response = Empty {}; Ok(Response::new(response)) }