Add Local Account Deletion #108
@ -22,20 +22,21 @@ import envoy.client.net.WriteProxy;
|
|||||||
*/
|
*/
|
||||||
public class Chat implements Serializable {
|
public class Chat implements Serializable {
|
||||||
|
|
||||||
|
protected transient ObservableList<Message> messages = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
protected final Contact recipient;
|
||||||
|
|
||||||
protected boolean disabled;
|
protected boolean disabled;
|
||||||
|
protected boolean underlyingContactDeleted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the last time an {@link envoy.event.IsTyping} event has been sent.
|
* Stores the last time an {@link envoy.event.IsTyping} event has been sent.
|
||||||
*/
|
*/
|
||||||
protected transient long lastWritingEvent;
|
protected transient long lastWritingEvent;
|
||||||
|
|
||||||
protected transient ObservableList<Message> messages = FXCollections.observableArrayList();
|
|
||||||
|
|
||||||
protected int unreadAmount;
|
protected int unreadAmount;
|
||||||
protected static IntegerProperty totalUnreadAmount = new SimpleIntegerProperty();
|
protected static IntegerProperty totalUnreadAmount = new SimpleIntegerProperty();
|
||||||
|
|
||||||
protected final Contact recipient;
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 2L;
|
private static final long serialVersionUID = 2L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -248,6 +248,10 @@ public final class LocalDB implements EventListener {
|
|||||||
*/
|
*/
|
||||||
@Event(eventType = EnvoyCloseEvent.class, priority = 500)
|
@Event(eventType = EnvoyCloseEvent.class, priority = 500)
|
||||||
private synchronized void save() {
|
private synchronized void save() {
|
||||||
|
|
||||||
|
// Stop saving if this account has been deleted
|
||||||
|
if (userFile == null)
|
||||||
|
return;
|
||||||
EnvoyLog.getLogger(LocalDB.class).log(Level.FINER, "Saving local database...");
|
EnvoyLog.getLogger(LocalDB.class).log(Level.FINER, "Saving local database...");
|
||||||
|
|
||||||
// Save users
|
// Save users
|
||||||
@ -273,6 +277,20 @@ public final class LocalDB implements EventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes any local remnant of this user.
|
||||||
|
*
|
||||||
|
* @since Envoy Client v0.3-beta
|
||||||
|
*/
|
||||||
|
public void delete() {
|
||||||
|
if (lastLoginFile != null)
|
||||||
|
lastLoginFile.delete();
|
||||||
|
userFile.delete();
|
||||||
|
users.remove(user.getName());
|
||||||
|
userFile = null;
|
||||||
|
onLogout();
|
||||||
|
}
|
||||||
|
|
||||||
@Event(priority = 500)
|
@Event(priority = 500)
|
||||||
private void onMessage(Message msg) {
|
private void onMessage(Message msg) {
|
||||||
if (msg.getStatus() == MessageStatus.SENT)
|
if (msg.getStatus() == MessageStatus.SENT)
|
||||||
@ -404,6 +422,17 @@ public final class LocalDB implements EventListener {
|
|||||||
getChat(event.get().getID()).ifPresent(chat -> chat.setDisabled(true));
|
getChat(event.get().getID()).ifPresent(chat -> chat.setDisabled(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Event(priority = 500)
|
||||||
|
private void onAccountDeletion(AccountDeletion deletion) {
|
||||||
|
if (user.getID() == deletion.get())
|
||||||
|
logger.log(Level.WARNING,
|
||||||
|
"I have been informed by the server that I have been deleted without even knowing it...");
|
||||||
|
getChat(deletion.get()).ifPresent(chat -> {
|
||||||
|
chat.setDisabled(true);
|
||||||
|
chat.setUnderlyingContactDeleted(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a {@code Map<String, User>} of all users stored locally with their user names as keys
|
* @return a {@code Map<String, User>} of all users stored locally with their user names as keys
|
||||||
* @since Envoy Client v0.2-alpha
|
* @since Envoy Client v0.2-alpha
|
||||||
|
@ -6,7 +6,7 @@ import java.io.*;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.Map;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
|
|
||||||
import javafx.animation.RotateTransition;
|
import javafx.animation.RotateTransition;
|
||||||
@ -25,9 +25,8 @@ import javafx.scene.shape.Rectangle;
|
|||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
import dev.kske.eventbus.*;
|
||||||
import dev.kske.eventbus.Event;
|
import dev.kske.eventbus.Event;
|
||||||
import dev.kske.eventbus.EventBus;
|
|
||||||
import dev.kske.eventbus.EventListener;
|
|
||||||
|
|
||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
import envoy.data.Attachment.AttachmentType;
|
import envoy.data.Attachment.AttachmentType;
|
||||||
@ -882,24 +881,22 @@ public final class ChatScene implements EventListener, Restorable, KeyboardMappi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<KeyCombination, Runnable> getKeyboardShortcuts() {
|
public Map<KeyCombination, Runnable> getKeyboardShortcuts() {
|
||||||
final var map = new HashMap<KeyCombination, Runnable>();
|
return Map.<KeyCombination, Runnable>of(
|
||||||
|
|
||||||
// Delete text before the caret with "Control" + U
|
// Delete text before the caret with "Control" + U
|
||||||
map.put(new KeyCodeCombination(KeyCode.U, KeyCombination.CONTROL_DOWN), () -> {
|
new KeyCodeCombination(KeyCode.U, KeyCombination.CONTROL_DOWN), () -> {
|
||||||
messageTextArea
|
messageTextArea
|
||||||
.setText(messageTextArea.getText().substring(messageTextArea.getCaretPosition()));
|
.setText(
|
||||||
|
messageTextArea.getText().substring(messageTextArea.getCaretPosition()));
|
||||||
checkPostConditions(false);
|
checkPostConditions(false);
|
||||||
});
|
|
||||||
|
|
||||||
// Delete text after the caret with "Control" + K
|
// Delete text after the caret with "Control" + K
|
||||||
map.put(new KeyCodeCombination(KeyCode.K, KeyCombination.CONTROL_DOWN), () -> {
|
}, new KeyCodeCombination(KeyCode.K, KeyCombination.CONTROL_DOWN), () -> {
|
||||||
messageTextArea
|
messageTextArea
|
||||||
.setText(
|
.setText(
|
||||||
messageTextArea.getText().substring(0, messageTextArea.getCaretPosition()));
|
messageTextArea.getText().substring(0, messageTextArea.getCaretPosition()));
|
||||||
checkPostConditions(false);
|
checkPostConditions(false);
|
||||||
messageTextArea.positionCaret(messageTextArea.getText().length());
|
messageTextArea.positionCaret(messageTextArea.getText().length());
|
||||||
});
|
});
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import dev.kske.eventbus.*;
|
|||||||
|
|
||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
import envoy.event.GroupCreation;
|
import envoy.event.GroupCreation;
|
||||||
import envoy.event.contact.UserOperation;
|
import envoy.event.contact.*;
|
||||||
import envoy.util.Bounds;
|
import envoy.util.Bounds;
|
||||||
|
|
||||||
import envoy.client.data.*;
|
import envoy.client.data.*;
|
||||||
@ -252,4 +252,10 @@ public class GroupCreationTab implements EventListener {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Event
|
||||||
|
private void onAccountDeletion(AccountDeletion deletion) {
|
||||||
|
final var deletedID = deletion.get();
|
||||||
|
Platform.runLater(() -> userList.getItems().removeIf(user -> (user.getID() == deletedID)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import envoy.event.*;
|
|||||||
import envoy.util.*;
|
import envoy.util.*;
|
||||||
|
|
||||||
import envoy.client.ui.control.ProfilePicImageView;
|
import envoy.client.ui.control.ProfilePicImageView;
|
||||||
import envoy.client.util.IconUtil;
|
import envoy.client.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Leon Hofmeister
|
* @author Leon Hofmeister
|
||||||
@ -38,6 +38,7 @@ public final class UserSettingsPane extends OnlineOnlySettingsPane {
|
|||||||
private final PasswordField newPasswordField = new PasswordField();
|
private final PasswordField newPasswordField = new PasswordField();
|
||||||
private final PasswordField repeatNewPasswordField = new PasswordField();
|
private final PasswordField repeatNewPasswordField = new PasswordField();
|
||||||
private final Button saveButton = new Button("Save");
|
private final Button saveButton = new Button("Save");
|
||||||
|
private final Button deleteAccountButton = new Button("Delete Account");
|
||||||
|
|
||||||
private static final EventBus eventBus = EventBus.getInstance();
|
private static final EventBus eventBus = EventBus.getInstance();
|
||||||
private static final Logger logger = EnvoyLog.getLogger(UserSettingsPane.class);
|
private static final Logger logger = EnvoyLog.getLogger(UserSettingsPane.class);
|
||||||
@ -112,15 +113,18 @@ public final class UserSettingsPane extends OnlineOnlySettingsPane {
|
|||||||
|
|
||||||
final PasswordField[] passwordFields =
|
final PasswordField[] passwordFields =
|
||||||
{ currentPasswordField, newPasswordField, repeatNewPasswordField };
|
{ currentPasswordField, newPasswordField, repeatNewPasswordField };
|
||||||
final EventHandler<? super InputEvent> passwordEntered = e -> {
|
final EventHandler<? super InputEvent> passwordEntered =
|
||||||
|
e -> {
|
||||||
newPassword =
|
newPassword =
|
||||||
newPasswordField.getText();
|
newPasswordField
|
||||||
validPassword = newPassword
|
.getText();
|
||||||
.equals(
|
validPassword =
|
||||||
|
newPassword.equals(
|
||||||
repeatNewPasswordField
|
repeatNewPasswordField
|
||||||
.getText())
|
.getText())
|
||||||
&& !newPasswordField
|
&& !newPasswordField
|
||||||
.getText().isBlank();
|
.getText()
|
||||||
|
.isBlank();
|
||||||
};
|
};
|
||||||
newPasswordField.setOnInputMethodTextChanged(passwordEntered);
|
newPasswordField.setOnInputMethodTextChanged(passwordEntered);
|
||||||
newPasswordField.setOnKeyTyped(passwordEntered);
|
newPasswordField.setOnKeyTyped(passwordEntered);
|
||||||
@ -140,6 +144,11 @@ public final class UserSettingsPane extends OnlineOnlySettingsPane {
|
|||||||
.setOnAction(e -> save(currentPasswordField.getText()));
|
.setOnAction(e -> save(currentPasswordField.getText()));
|
||||||
saveButton.setAlignment(Pos.BOTTOM_RIGHT);
|
saveButton.setAlignment(Pos.BOTTOM_RIGHT);
|
||||||
getChildren().add(saveButton);
|
getChildren().add(saveButton);
|
||||||
|
|
||||||
|
// Displaying the delete account button
|
||||||
|
deleteAccountButton.setAlignment(Pos.BASELINE_CENTER);
|
||||||
|
deleteAccountButton.setOnAction(e -> UserUtil.deleteAccount());
|
||||||
|
getChildren().add(deleteAccountButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,7 @@ package envoy.client.util;
|
|||||||
|
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
|
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.Alert.AlertType;
|
import javafx.scene.control.Alert.AlertType;
|
||||||
|
|
||||||
import dev.kske.eventbus.EventBus;
|
import dev.kske.eventbus.EventBus;
|
||||||
@ -10,7 +10,7 @@ import dev.kske.eventbus.EventBus;
|
|||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
import envoy.data.User.UserStatus;
|
import envoy.data.User.UserStatus;
|
||||||
import envoy.event.*;
|
import envoy.event.*;
|
||||||
import envoy.event.contact.UserOperation;
|
import envoy.event.contact.*;
|
||||||
import envoy.util.EnvoyLog;
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
import envoy.client.data.Context;
|
import envoy.client.data.Context;
|
||||||
@ -121,4 +121,40 @@ public final class UserUtil {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes anything pointing to this user, independent of client or server. Will do nothing if
|
||||||
|
* the client is currently offline.
|
||||||
|
*
|
||||||
|
* @since Envoy Client v0.3-beta
|
||||||
|
*/
|
||||||
|
public static void deleteAccount() {
|
||||||
|
if (!context.getClient().isOnline())
|
||||||
|
return;
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Show the first wall of defense, if not disabled by the user
|
||||||
|
final var outerAlert = new Alert(AlertType.CONFIRMATION);
|
||||||
|
outerAlert.setContentText(
|
||||||
|
"Are you sure you want to delete your account entirely? This action can seriously not be undone.");
|
||||||
|
outerAlert.setTitle("Delete Account?");
|
||||||
|
AlertHelper.confirmAction(outerAlert, () -> {
|
||||||
|
|
||||||
|
// Show the final wall of defense in every case
|
||||||
|
final var lastAlert = new Alert(AlertType.WARNING,
|
||||||
|
"Do you REALLY want to delete your account? Last Warning. Proceed?",
|
||||||
|
ButtonType.CANCEL, ButtonType.OK);
|
||||||
|
lastAlert.setTitle("Delete Account?");
|
||||||
|
lastAlert.showAndWait().filter(ButtonType.OK::equals).ifPresent(b2 -> {
|
||||||
|
|
||||||
|
// Delete the account
|
||||||
|
context.getClient()
|
||||||
|
.send(new AccountDeletion(context.getLocalDB().getUser().getID()));
|
||||||
|
context.getLocalDB().delete();
|
||||||
|
logger.log(Level.INFO, "The user just deleted his account. Goodbye.");
|
||||||
|
ShutdownHelper.exit(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package envoy.event.contact;
|
||||||
|
|
||||||
|
import envoy.event.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signifies the deletion of an account.
|
||||||
|
*
|
||||||
|
* @author Leon Hofmeister
|
||||||
|
* @since Envoy Common v0.3-beta
|
||||||
|
*/
|
||||||
|
public class AccountDeletion extends Event<Long> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value the ID of the contact that was deleted
|
||||||
|
* @since Envoy Common v0.3-beta
|
||||||
|
*/
|
||||||
|
public AccountDeletion(Long value) {
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
@ -59,7 +59,8 @@ public final class Startup {
|
|||||||
new NameChangeProcessor(),
|
new NameChangeProcessor(),
|
||||||
new ProfilePicChangeProcessor(),
|
new ProfilePicChangeProcessor(),
|
||||||
new PasswordChangeRequestProcessor(),
|
new PasswordChangeRequestProcessor(),
|
||||||
new IssueProposalProcessor())));
|
new IssueProposalProcessor(),
|
||||||
|
new AccountDeletionProcessor())));
|
||||||
|
|
||||||
// Initialize the current message ID
|
// Initialize the current message ID
|
||||||
final var persistenceManager = PersistenceManager.getInstance();
|
final var persistenceManager = PersistenceManager.getInstance();
|
||||||
|
@ -27,6 +27,7 @@ import envoy.data.Message.MessageStatus;
|
|||||||
@Entity
|
@Entity
|
||||||
@Table(name = "messages")
|
@Table(name = "messages")
|
||||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||||
|
@NamedQueries({
|
||||||
@NamedQuery(name = Message.getPending, query = "SELECT m FROM Message m WHERE "
|
@NamedQuery(name = Message.getPending, query = "SELECT m FROM Message m WHERE "
|
||||||
// Send to or by the user before last seen
|
// Send to or by the user before last seen
|
||||||
+ "(m.sender = :user OR m.recipient = :user) AND m.creationDate > :lastSeen "
|
+ "(m.sender = :user OR m.recipient = :user) AND m.creationDate > :lastSeen "
|
||||||
@ -34,7 +35,10 @@ import envoy.data.Message.MessageStatus;
|
|||||||
+ "OR m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT "
|
+ "OR m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT "
|
||||||
// Sent by the user and RECEIVED / READ after last seen
|
// Sent by the user and RECEIVED / READ after last seen
|
||||||
+ "OR m.sender = :user AND (m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen "
|
+ "OR m.sender = :user AND (m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen "
|
||||||
+ "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen)")
|
+ "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen)"),
|
||||||
|
@NamedQuery(name = Message.deleteByRecipient, query = "DELETE FROM Message m WHERE m.recipient = :deleted OR m.sender = :deleted")
|
||||||
|
|
||||||
|
})
|
||||||
public class Message {
|
public class Message {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,6 +49,13 @@ public class Message {
|
|||||||
*/
|
*/
|
||||||
public static final String getPending = "Message.getPending";
|
public static final String getPending = "Message.getPending";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Named query deleting all messages of a user (parameter {@code :deleted}).
|
||||||
|
*
|
||||||
|
* @since Envoy Server v0.3-beta
|
||||||
|
*/
|
||||||
|
public static final String deleteByRecipient = "Message.deleteByRecipient";
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
protected long id;
|
protected long id;
|
||||||
|
|
||||||
|
@ -123,6 +123,10 @@ public final class PersistenceManager {
|
|||||||
// Remove this contact from the contact list of his contacts
|
// Remove this contact from the contact list of his contacts
|
||||||
for (final var remainingContact : contact.getContacts())
|
for (final var remainingContact : contact.getContacts())
|
||||||
remainingContact.getContacts().remove(contact);
|
remainingContact.getContacts().remove(contact);
|
||||||
|
|
||||||
|
entityManager
|
||||||
|
.createNamedQuery(Message.deleteByRecipient).setParameter("deleted", contact)
|
||||||
|
.executeUpdate();
|
||||||
});
|
});
|
||||||
remove(contact);
|
remove(contact);
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,10 @@ public final class ConnectionManager implements ISocketIdListener {
|
|||||||
// Notify contacts of this users offline-going
|
// Notify contacts of this users offline-going
|
||||||
final envoy.server.data.User user =
|
final envoy.server.data.User user =
|
||||||
PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
|
PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
|
||||||
|
if (user != null) {
|
||||||
user.setLastSeen(Instant.now());
|
user.setLastSeen(Instant.now());
|
||||||
UserStatusChangeProcessor.updateUserStatus(user, UserStatus.OFFLINE);
|
UserStatusChangeProcessor.updateUserStatus(user, UserStatus.OFFLINE);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the socket
|
// Remove the socket
|
||||||
sockets.entrySet().removeIf(e -> e.getValue() == socketID);
|
sockets.entrySet().removeIf(e -> e.getValue() == socketID);
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package envoy.server.processors;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import envoy.event.contact.AccountDeletion;
|
||||||
|
|
||||||
|
import envoy.server.data.*;
|
||||||
|
import envoy.server.net.ObjectWriteProxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leon Hofmeister
|
||||||
|
* @since Envoy Server v0.3-beta
|
||||||
|
*/
|
||||||
|
public class AccountDeletionProcessor implements ObjectProcessor<AccountDeletion> {
|
||||||
|
|
||||||
|
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(AccountDeletion input, long socketID, ObjectWriteProxy writeProxy)
|
||||||
|
throws IOException {
|
||||||
|
final var contact = persistenceManager.getContactByID(input.get());
|
||||||
|
|
||||||
|
contact.getContacts().forEach(c -> {
|
||||||
|
persistenceManager.removeContactBidirectional(contact, c);
|
||||||
|
if (c instanceof User)
|
||||||
|
((User) c).setLatestContactDeletion(Instant.now());
|
||||||
|
});
|
||||||
|
|
||||||
|
writeProxy.writeToOnlineContacts(contact.getContacts(), input);
|
||||||
|
persistenceManager.deleteContact(contact);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import java.time.Instant;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import envoy.event.GroupResize;
|
import envoy.event.GroupResize;
|
||||||
|
import envoy.event.contact.AccountDeletion;
|
||||||
import envoy.util.EnvoyLog;
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
import envoy.server.data.*;
|
import envoy.server.data.*;
|
||||||
@ -24,6 +25,12 @@ public final class GroupResizeProcessor implements ObjectProcessor<GroupResize>
|
|||||||
final var group = persistenceManager.getGroupByID(groupResize.getGroupID());
|
final var group = persistenceManager.getGroupByID(groupResize.getGroupID());
|
||||||
final var sender = persistenceManager.getUserByID(groupResize.get().getID());
|
final var sender = persistenceManager.getUserByID(groupResize.get().getID());
|
||||||
|
|
||||||
|
// Inform the sender that this group has already been deleted
|
||||||
|
if (group == null) {
|
||||||
|
writeProxy.write(socketID, new AccountDeletion(groupResize.getGroupID()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Perform the desired operation
|
// Perform the desired operation
|
||||||
switch (groupResize.getOperation()) {
|
switch (groupResize.getOperation()) {
|
||||||
case ADD:
|
case ADD:
|
||||||
|
@ -4,7 +4,7 @@ import java.time.Instant;
|
|||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
|
|
||||||
import envoy.event.ElementOperation;
|
import envoy.event.ElementOperation;
|
||||||
import envoy.event.contact.UserOperation;
|
import envoy.event.contact.*;
|
||||||
import envoy.util.EnvoyLog;
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
import envoy.server.data.PersistenceManager;
|
import envoy.server.data.PersistenceManager;
|
||||||
@ -22,9 +22,17 @@ public final class UserOperationProcessor implements ObjectProcessor<UserOperati
|
|||||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(UserOperation evt, long socketId, ObjectWriteProxy writeProxy) {
|
public void process(UserOperation evt, long socketID, ObjectWriteProxy writeProxy) {
|
||||||
final long userID = ConnectionManager.getInstance().getUserIDBySocketID(socketId);
|
final long userID = ConnectionManager.getInstance().getUserIDBySocketID(socketID);
|
||||||
final long contactID = evt.get().getID();
|
final long contactID = evt.get().getID();
|
||||||
|
final var recipient = persistenceManager.getUserByID(contactID);
|
||||||
|
|
||||||
|
// Inform the sender if the requested contact has already been deleted
|
||||||
|
if (recipient == null) {
|
||||||
|
writeProxy.write(socketID, new AccountDeletion(contactID));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final var sender = persistenceManager.getUserByID(userID);
|
final var sender = persistenceManager.getUserByID(userID);
|
||||||
switch (evt.getOperationType()) {
|
switch (evt.getOperationType()) {
|
||||||
case ADD:
|
case ADD:
|
||||||
@ -45,7 +53,7 @@ public final class UserOperationProcessor implements ObjectProcessor<UserOperati
|
|||||||
sender.setLatestContactDeletion(Instant.now());
|
sender.setLatestContactDeletion(Instant.now());
|
||||||
|
|
||||||
// Notify the removed contact on next startup(s) of this deletion
|
// Notify the removed contact on next startup(s) of this deletion
|
||||||
persistenceManager.getUserByID(contactID).setLatestContactDeletion(Instant.now());
|
recipient.setLatestContactDeletion(Instant.now());
|
||||||
|
|
||||||
// Notify the removed contact if online
|
// Notify the removed contact if online
|
||||||
if (connectionManager.isOnline(contactID))
|
if (connectionManager.isOnline(contactID))
|
||||||
|
Reference in New Issue
Block a user