mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
parent
5cd5697aea
commit
7e7e4150e1
14 changed files with 167 additions and 7 deletions
|
@ -174,6 +174,10 @@ public interface Manager extends Closeable {
|
|||
|
||||
SendMessageResults sendEndSessionMessage(Set<RecipientIdentifier.Single> recipients) throws IOException;
|
||||
|
||||
void deleteRecipient(RecipientIdentifier.Single recipient) throws IOException;
|
||||
|
||||
void deleteContact(RecipientIdentifier.Single recipient) throws IOException;
|
||||
|
||||
void setContactName(
|
||||
RecipientIdentifier.Single recipient, String name
|
||||
) throws NotMasterDeviceException, IOException;
|
||||
|
|
|
@ -279,13 +279,17 @@ public class ManagerImpl implements Manager {
|
|||
*
|
||||
* @param numbers The set of phone number in question
|
||||
* @return A map of numbers to canonicalized number and uuid. If a number is not registered the uuid is null.
|
||||
* @throws IOException if its unable to get the contacts to check if they're registered
|
||||
* @throws IOException if it's unable to get the contacts to check if they're registered
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException {
|
||||
Map<String, String> canonicalizedNumbers = numbers.stream().collect(Collectors.toMap(n -> n, n -> {
|
||||
try {
|
||||
return PhoneNumberFormatter.formatNumber(n, account.getAccount());
|
||||
final var canonicalizedNumber = PhoneNumberFormatter.formatNumber(n, account.getAccount());
|
||||
if (!canonicalizedNumber.equals(n)) {
|
||||
logger.debug("Normalized number {} to {}.", n, canonicalizedNumber);
|
||||
}
|
||||
return canonicalizedNumber;
|
||||
} catch (InvalidNumberException e) {
|
||||
return "";
|
||||
}
|
||||
|
@ -774,6 +778,16 @@ public class ManagerImpl implements Manager {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRecipient(final RecipientIdentifier.Single recipient) throws IOException {
|
||||
account.removeRecipient(resolveRecipient(recipient));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteContact(final RecipientIdentifier.Single recipient) throws IOException {
|
||||
account.getContactStore().deleteContact(resolveRecipient(recipient));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContactName(
|
||||
RecipientIdentifier.Single recipient, String name
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.asamk.signal.manager.api;
|
|||
|
||||
import org.asamk.signal.manager.groups.GroupId;
|
||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
|
@ -18,9 +20,16 @@ public sealed interface RecipientIdentifier {
|
|||
|
||||
static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
|
||||
try {
|
||||
return UuidUtil.isUuid(identifier)
|
||||
? new Uuid(UUID.fromString(identifier))
|
||||
: new Number(PhoneNumberFormatter.formatNumber(identifier, localNumber));
|
||||
if (UuidUtil.isUuid(identifier)) {
|
||||
return new Uuid(UUID.fromString(identifier));
|
||||
}
|
||||
|
||||
final var normalizedNumber = PhoneNumberFormatter.formatNumber(identifier, localNumber);
|
||||
if (!normalizedNumber.equals(identifier)) {
|
||||
final Logger logger = LoggerFactory.getLogger(RecipientIdentifier.class);
|
||||
logger.debug("Normalized number {} to {}.", identifier, normalizedNumber);
|
||||
}
|
||||
return new Number(normalizedNumber);
|
||||
} catch (org.whispersystems.signalservice.api.util.InvalidNumberException e) {
|
||||
throw new InvalidNumberException(e.getMessage(), e);
|
||||
}
|
||||
|
|
|
@ -324,6 +324,14 @@ public class SignalAccount implements Closeable {
|
|||
senderKeyStore.mergeRecipients(recipientId, toBeMergedRecipientId);
|
||||
}
|
||||
|
||||
public void removeRecipient(final RecipientId recipientId) {
|
||||
sessionStore.deleteAllSessions(recipientId);
|
||||
identityKeyStore.deleteIdentity(recipientId);
|
||||
messageCache.deleteMessages(recipientId);
|
||||
senderKeyStore.deleteAll(recipientId);
|
||||
recipientStore.deleteRecipientData(recipientId);
|
||||
}
|
||||
|
||||
public static File getFileName(File dataPath, String account) {
|
||||
return new File(dataPath, account);
|
||||
}
|
||||
|
|
|
@ -13,4 +13,6 @@ public interface ContactsStore {
|
|||
Contact getContact(RecipientId recipientId);
|
||||
|
||||
List<Pair<RecipientId, Contact>> getContacts();
|
||||
|
||||
void deleteContact(RecipientId recipientId);
|
||||
}
|
||||
|
|
|
@ -172,6 +172,12 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden
|
|||
}
|
||||
}
|
||||
|
||||
public void deleteIdentity(final RecipientId recipientId) {
|
||||
synchronized (cachedIdentities) {
|
||||
deleteIdentityLocked(recipientId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param identifier can be either a serialized uuid or a e164 phone number
|
||||
*/
|
||||
|
|
|
@ -71,6 +71,25 @@ public class MessageCache {
|
|||
return new CachedMessage(cacheFile);
|
||||
}
|
||||
|
||||
public void deleteMessages(final RecipientId recipientId) {
|
||||
final var recipientMessageCachePath = getMessageCachePath(recipientId);
|
||||
if (!recipientMessageCachePath.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var file : Objects.requireNonNull(recipientMessageCachePath.listFiles())) {
|
||||
if (!file.isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Files.delete(file.toPath());
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to delete cache file “{}”, ignoring: {}", file, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File getMessageCachePath(RecipientId recipientId) {
|
||||
if (recipientId == null) {
|
||||
return messageCachePath;
|
||||
|
|
|
@ -220,6 +220,25 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteContact(final RecipientId recipientId) {
|
||||
synchronized (recipients) {
|
||||
final var recipient = recipients.get(recipientId);
|
||||
storeRecipientLocked(recipientId, Recipient.newBuilder(recipient).withContact(null).build());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRecipientData(final RecipientId recipientId) {
|
||||
synchronized (recipients) {
|
||||
final var recipient = recipients.get(recipientId);
|
||||
storeRecipientLocked(recipientId,
|
||||
Recipient.newBuilder()
|
||||
.withRecipientId(recipientId)
|
||||
.withAddress(new RecipientAddress(recipient.getAddress().getUuid().orElse(null)))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Profile getProfile(final RecipientId recipientId) {
|
||||
final var recipient = getRecipient(recipientId);
|
||||
|
|
|
@ -63,7 +63,7 @@ public class SenderKeyStore implements SignalServiceSenderKeyStore {
|
|||
senderKeyRecordStore.deleteAll();
|
||||
}
|
||||
|
||||
public void rotateSenderKeys(RecipientId recipientId) {
|
||||
public void deleteAll(RecipientId recipientId) {
|
||||
senderKeySharedStore.deleteAllFor(recipientId);
|
||||
senderKeyRecordStore.deleteAllFor(recipientId);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue