mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Handle saving inside SignalAccount
This commit is contained in:
parent
5b8c0c4e2d
commit
530ef51ba7
4 changed files with 84 additions and 80 deletions
|
@ -316,11 +316,9 @@ public class Manager implements Closeable {
|
||||||
public void checkAccountState() throws IOException {
|
public void checkAccountState() throws IOException {
|
||||||
if (accountManager.getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
|
if (accountManager.getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
|
||||||
refreshPreKeys();
|
refreshPreKeys();
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
if (account.getUuid() == null) {
|
if (account.getUuid() == null) {
|
||||||
account.setUuid(accountManager.getOwnUuid());
|
account.setUuid(accountManager.getOwnUuid());
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
updateAccountAttributes();
|
updateAccountAttributes();
|
||||||
}
|
}
|
||||||
|
@ -411,13 +409,11 @@ public class Manager implements Closeable {
|
||||||
accountManager.deleteAccount();
|
accountManager.deleteAccount();
|
||||||
|
|
||||||
account.setRegistered(false);
|
account.setRegistered(false);
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DeviceInfo> getLinkedDevices() throws IOException {
|
public List<DeviceInfo> getLinkedDevices() throws IOException {
|
||||||
var devices = accountManager.getDevices();
|
var devices = accountManager.getDevices();
|
||||||
account.setMultiDevice(devices.size() > 1);
|
account.setMultiDevice(devices.size() > 1);
|
||||||
account.save();
|
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +421,6 @@ public class Manager implements Closeable {
|
||||||
accountManager.removeDevice(deviceId);
|
accountManager.removeDevice(deviceId);
|
||||||
var devices = accountManager.getDevices();
|
var devices = accountManager.getDevices();
|
||||||
account.setMultiDevice(devices.size() > 1);
|
account.setMultiDevice(devices.size() > 1);
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDeviceLink(URI linkUri) throws IOException, InvalidKeyException {
|
public void addDeviceLink(URI linkUri) throws IOException, InvalidKeyException {
|
||||||
|
@ -444,7 +439,6 @@ public class Manager implements Closeable {
|
||||||
Optional.of(account.getProfileKey().serialize()),
|
Optional.of(account.getProfileKey().serialize()),
|
||||||
verificationCode);
|
verificationCode);
|
||||||
account.setMultiDevice(true);
|
account.setMultiDevice(true);
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistrationLockPin(Optional<String> pin) throws IOException, UnauthenticatedResponseException {
|
public void setRegistrationLockPin(Optional<String> pin) throws IOException, UnauthenticatedResponseException {
|
||||||
|
@ -458,8 +452,7 @@ public class Manager implements Closeable {
|
||||||
|
|
||||||
pinHelper.setRegistrationLockPin(pin.get(), masterKey);
|
pinHelper.setRegistrationLockPin(pin.get(), masterKey);
|
||||||
|
|
||||||
account.setRegistrationLockPin(pin.get());
|
account.setRegistrationLockPin(pin.get(), masterKey);
|
||||||
account.setPinMasterKey(masterKey);
|
|
||||||
} else {
|
} else {
|
||||||
// Remove legacy registration lock
|
// Remove legacy registration lock
|
||||||
accountManager.removeRegistrationLockV1();
|
accountManager.removeRegistrationLockV1();
|
||||||
|
@ -467,10 +460,8 @@ public class Manager implements Closeable {
|
||||||
// Remove KBS Pin
|
// Remove KBS Pin
|
||||||
pinHelper.removeRegistrationLockPin();
|
pinHelper.removeRegistrationLockPin();
|
||||||
|
|
||||||
account.setRegistrationLockPin(null);
|
account.setRegistrationLockPin(null, null);
|
||||||
account.setPinMasterKey(null);
|
|
||||||
}
|
}
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshPreKeys() throws IOException {
|
void refreshPreKeys() throws IOException {
|
||||||
|
@ -1082,7 +1073,6 @@ public class Manager implements Closeable {
|
||||||
for (var address : signalServiceAddresses) {
|
for (var address : signalServiceAddresses) {
|
||||||
handleEndSession(address);
|
handleEndSession(address);
|
||||||
}
|
}
|
||||||
account.save();
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1097,7 +1087,6 @@ public class Manager implements Closeable {
|
||||||
var contact = account.getContactStore().getContact(recipientId);
|
var contact = account.getContactStore().getContact(recipientId);
|
||||||
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
|
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
|
||||||
account.getContactStore().storeContact(recipientId, builder.withName(name).build());
|
account.getContactStore().storeContact(recipientId, builder.withName(name).build());
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContactBlocked(String number, boolean blocked) throws InvalidNumberException {
|
public void setContactBlocked(String number, boolean blocked) throws InvalidNumberException {
|
||||||
|
@ -1108,7 +1097,6 @@ public class Manager implements Closeable {
|
||||||
var contact = account.getContactStore().getContact(recipientId);
|
var contact = account.getContactStore().getContact(recipientId);
|
||||||
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
|
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
|
||||||
account.getContactStore().storeContact(recipientId, builder.withBlocked(blocked).build());
|
account.getContactStore().storeContact(recipientId, builder.withBlocked(blocked).build());
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGroupBlocked(final GroupId groupId, final boolean blocked) throws GroupNotFoundException {
|
public void setGroupBlocked(final GroupId groupId, final boolean blocked) throws GroupNotFoundException {
|
||||||
|
@ -1119,7 +1107,6 @@ public class Manager implements Closeable {
|
||||||
|
|
||||||
group.setBlocked(blocked);
|
group.setBlocked(blocked);
|
||||||
account.getGroupStore().updateGroup(group);
|
account.getGroupStore().updateGroup(group);
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setExpirationTimer(RecipientId recipientId, int messageExpirationTimer) {
|
private void setExpirationTimer(RecipientId recipientId, int messageExpirationTimer) {
|
||||||
|
@ -1146,7 +1133,6 @@ public class Manager implements Closeable {
|
||||||
var recipientId = canonicalizeAndResolveRecipient(number);
|
var recipientId = canonicalizeAndResolveRecipient(number);
|
||||||
setExpirationTimer(recipientId, messageExpirationTimer);
|
setExpirationTimer(recipientId, messageExpirationTimer);
|
||||||
sendExpirationTimerUpdate(recipientId);
|
sendExpirationTimerUpdate(recipientId);
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1179,7 +1165,6 @@ public class Manager implements Closeable {
|
||||||
|
|
||||||
var sticker = new Sticker(StickerPackId.deserialize(Hex.fromStringCondensed(packId)), packKey);
|
var sticker = new Sticker(StickerPackId.deserialize(Hex.fromStringCondensed(packId)), packKey);
|
||||||
account.getStickerStore().updateSticker(sticker);
|
account.getStickerStore().updateSticker(sticker);
|
||||||
account.save();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new URI("https",
|
return new URI("https",
|
||||||
|
@ -1376,7 +1361,6 @@ public class Manager implements Closeable {
|
||||||
handleEndSession(recipient);
|
handleEndSession(recipient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1387,7 +1371,6 @@ public class Manager implements Closeable {
|
||||||
messageBuilder.withTimestamp(timestamp);
|
messageBuilder.withTimestamp(timestamp);
|
||||||
getOrCreateMessagePipe();
|
getOrCreateMessagePipe();
|
||||||
getOrCreateUnidentifiedMessagePipe();
|
getOrCreateUnidentifiedMessagePipe();
|
||||||
try {
|
|
||||||
final var recipientId = account.getSelfRecipientId();
|
final var recipientId = account.getSelfRecipientId();
|
||||||
|
|
||||||
final var contact = account.getContactStore().getContact(recipientId);
|
final var contact = account.getContactStore().getContact(recipientId);
|
||||||
|
@ -1397,9 +1380,6 @@ public class Manager implements Closeable {
|
||||||
var message = messageBuilder.build();
|
var message = messageBuilder.build();
|
||||||
final var result = sendSelfMessage(message);
|
final var result = sendSelfMessage(message);
|
||||||
return new Pair<>(timestamp, result);
|
return new Pair<>(timestamp, result);
|
||||||
} finally {
|
|
||||||
account.save();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
|
private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
|
||||||
|
@ -1715,7 +1695,6 @@ public class Manager implements Closeable {
|
||||||
}
|
}
|
||||||
actions = handleMessage(envelope, content, ignoreAttachments);
|
actions = handleMessage(envelope, content, ignoreAttachments);
|
||||||
}
|
}
|
||||||
account.save();
|
|
||||||
handler.handleMessage(envelope, content, null);
|
handler.handleMessage(envelope, content, null);
|
||||||
cachedMessage.delete();
|
cachedMessage.delete();
|
||||||
return actions;
|
return actions;
|
||||||
|
@ -1763,7 +1742,6 @@ public class Manager implements Closeable {
|
||||||
logger.warn("Message action failed.", e);
|
logger.warn("Message action failed.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
account.save();
|
|
||||||
queuedActions.clear();
|
queuedActions.clear();
|
||||||
queuedActions = null;
|
queuedActions = null;
|
||||||
}
|
}
|
||||||
|
@ -1803,7 +1781,6 @@ public class Manager implements Closeable {
|
||||||
queuedActions.addAll(actions);
|
queuedActions.addAll(actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
account.save();
|
|
||||||
if (isMessageBlocked(envelope, content)) {
|
if (isMessageBlocked(envelope, content)) {
|
||||||
logger.info("Ignoring a message from blocked user/group: {}", envelope.getTimestamp());
|
logger.info("Ignoring a message from blocked user/group: {}", envelope.getTimestamp());
|
||||||
} else if (notAGroupMember) {
|
} else if (notAGroupMember) {
|
||||||
|
|
|
@ -125,7 +125,6 @@ public class ProvisioningManager {
|
||||||
ret.getIdentity(),
|
ret.getIdentity(),
|
||||||
registrationId,
|
registrationId,
|
||||||
profileKey);
|
profileKey);
|
||||||
account.save();
|
|
||||||
|
|
||||||
Manager m = null;
|
Manager m = null;
|
||||||
try {
|
try {
|
||||||
|
@ -149,8 +148,6 @@ public class ProvisioningManager {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
account.save();
|
|
||||||
|
|
||||||
final var result = m;
|
final var result = m;
|
||||||
account = null;
|
account = null;
|
||||||
m = null;
|
m = null;
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||||
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
|
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
|
||||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||||
|
import org.whispersystems.signalservice.api.kbs.MasterKey;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.api.util.SleepTimer;
|
import org.whispersystems.signalservice.api.util.SleepTimer;
|
||||||
import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
|
import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
|
||||||
|
@ -40,7 +41,6 @@ import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class RegistrationManager implements Closeable {
|
public class RegistrationManager implements Closeable {
|
||||||
|
@ -103,7 +103,6 @@ public class RegistrationManager implements Closeable {
|
||||||
identityKey,
|
identityKey,
|
||||||
registrationId,
|
registrationId,
|
||||||
profileKey);
|
profileKey);
|
||||||
account.save();
|
|
||||||
|
|
||||||
return new RegistrationManager(account, pathConfig, serviceConfiguration, userAgent);
|
return new RegistrationManager(account, pathConfig, serviceConfiguration, userAgent);
|
||||||
}
|
}
|
||||||
|
@ -114,10 +113,6 @@ public class RegistrationManager implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(boolean voiceVerification, String captcha) throws IOException {
|
public void register(boolean voiceVerification, String captcha) throws IOException {
|
||||||
if (account.getPassword() == null) {
|
|
||||||
account.setPassword(KeyUtils.createPassword());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (voiceVerification) {
|
if (voiceVerification) {
|
||||||
accountManager.requestVoiceVerificationCode(Locale.getDefault(),
|
accountManager.requestVoiceVerificationCode(Locale.getDefault(),
|
||||||
Optional.fromNullable(captcha),
|
Optional.fromNullable(captcha),
|
||||||
|
@ -125,8 +120,6 @@ public class RegistrationManager implements Closeable {
|
||||||
} else {
|
} else {
|
||||||
accountManager.requestSmsVerificationCode(false, Optional.fromNullable(captcha), Optional.absent());
|
accountManager.requestSmsVerificationCode(false, Optional.fromNullable(captcha), Optional.absent());
|
||||||
}
|
}
|
||||||
|
|
||||||
account.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Manager verifyAccount(
|
public Manager verifyAccount(
|
||||||
|
@ -134,9 +127,11 @@ public class RegistrationManager implements Closeable {
|
||||||
) throws IOException, KeyBackupSystemNoDataException, KeyBackupServicePinException {
|
) throws IOException, KeyBackupSystemNoDataException, KeyBackupServicePinException {
|
||||||
verificationCode = verificationCode.replace("-", "");
|
verificationCode = verificationCode.replace("-", "");
|
||||||
VerifyAccountResponse response;
|
VerifyAccountResponse response;
|
||||||
|
MasterKey masterKey;
|
||||||
try {
|
try {
|
||||||
response = verifyAccountWithCode(verificationCode, pin, null);
|
response = verifyAccountWithCode(verificationCode, pin, null);
|
||||||
account.setPinMasterKey(null);
|
|
||||||
|
masterKey = null;
|
||||||
} catch (LockedException e) {
|
} catch (LockedException e) {
|
||||||
if (pin == null) {
|
if (pin == null) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -153,33 +148,21 @@ public class RegistrationManager implements Closeable {
|
||||||
} catch (LockedException _e) {
|
} catch (LockedException _e) {
|
||||||
throw new AssertionError("KBS Pin appeared to matched but reg lock still failed!");
|
throw new AssertionError("KBS Pin appeared to matched but reg lock still failed!");
|
||||||
}
|
}
|
||||||
account.setPinMasterKey(registrationLockData.getMasterKey());
|
masterKey = registrationLockData.getMasterKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO response.isStorageCapable()
|
// TODO response.isStorageCapable()
|
||||||
//accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
|
//accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
|
||||||
|
account.finishRegistration(UuidUtil.parseOrNull(response.getUuid()), masterKey, pin);
|
||||||
account.setDeviceId(SignalServiceAddress.DEFAULT_DEVICE_ID);
|
|
||||||
account.setMultiDevice(false);
|
|
||||||
account.setRegistered(true);
|
|
||||||
account.setUuid(UuidUtil.parseOrNull(response.getUuid()));
|
|
||||||
account.setRegistrationLockPin(pin);
|
|
||||||
account.getSessionStore().archiveAllSessions();
|
|
||||||
final var recipientId = account.getRecipientStore().resolveRecipientTrusted(account.getSelfAddress());
|
|
||||||
final var publicKey = account.getIdentityKeyPair().getPublicKey();
|
|
||||||
account.getIdentityKeyStore().saveIdentity(recipientId, publicKey, new Date());
|
|
||||||
account.getIdentityKeyStore().setIdentityTrustLevel(recipientId, publicKey, TrustLevel.TRUSTED_VERIFIED);
|
|
||||||
|
|
||||||
Manager m = null;
|
Manager m = null;
|
||||||
try {
|
try {
|
||||||
m = new Manager(account, pathConfig, serviceEnvironmentConfig, userAgent);
|
m = new Manager(account, pathConfig, serviceEnvironmentConfig, userAgent);
|
||||||
|
account = null;
|
||||||
|
|
||||||
m.refreshPreKeys();
|
m.refreshPreKeys();
|
||||||
|
|
||||||
account.save();
|
|
||||||
|
|
||||||
final var result = m;
|
final var result = m;
|
||||||
account = null;
|
|
||||||
m = null;
|
m = null;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.asamk.signal.manager.storage;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.asamk.signal.manager.TrustLevel;
|
||||||
import org.asamk.signal.manager.groups.GroupId;
|
import org.asamk.signal.manager.groups.GroupId;
|
||||||
import org.asamk.signal.manager.storage.contacts.ContactsStore;
|
import org.asamk.signal.manager.storage.contacts.ContactsStore;
|
||||||
import org.asamk.signal.manager.storage.contacts.LegacyJsonContactsStore;
|
import org.asamk.signal.manager.storage.contacts.LegacyJsonContactsStore;
|
||||||
|
@ -54,6 +55,7 @@ import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.channels.FileLock;
|
import java.nio.channels.FileLock;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -139,6 +141,7 @@ public class SignalAccount implements Closeable {
|
||||||
account.registered = false;
|
account.registered = false;
|
||||||
|
|
||||||
account.migrateLegacyConfigs();
|
account.migrateLegacyConfigs();
|
||||||
|
account.save();
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
@ -196,15 +199,19 @@ public class SignalAccount implements Closeable {
|
||||||
|
|
||||||
account.recipientStore.resolveRecipientTrusted(account.getSelfAddress());
|
account.recipientStore.resolveRecipientTrusted(account.getSelfAddress());
|
||||||
account.migrateLegacyConfigs();
|
account.migrateLegacyConfigs();
|
||||||
|
account.save();
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void migrateLegacyConfigs() {
|
private void migrateLegacyConfigs() {
|
||||||
|
if (getPassword() == null) {
|
||||||
|
setPassword(KeyUtils.createPassword());
|
||||||
|
}
|
||||||
|
|
||||||
if (getProfileKey() == null && isRegistered()) {
|
if (getProfileKey() == null && isRegistered()) {
|
||||||
// Old config file, creating new profile key
|
// Old config file, creating new profile key
|
||||||
setProfileKey(KeyUtils.createProfileKey());
|
setProfileKey(KeyUtils.createProfileKey());
|
||||||
save();
|
|
||||||
}
|
}
|
||||||
// Ensure our profile key is stored in profile store
|
// Ensure our profile key is stored in profile store
|
||||||
getProfileStore().storeProfileKey(getSelfRecipientId(), getProfileKey());
|
getProfileStore().storeProfileKey(getSelfRecipientId(), getProfileKey());
|
||||||
|
@ -225,7 +232,7 @@ public class SignalAccount implements Closeable {
|
||||||
return new File(dataPath, username + ".d");
|
return new File(dataPath, username + ".d");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getMessageCachePath(File dataPath, String username) {
|
private static File getMessageCachePath(File dataPath, String username) {
|
||||||
return new File(getUserPath(dataPath, username), "msg-cache");
|
return new File(getUserPath(dataPath, username), "msg-cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,6 +331,7 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var migratedLegacyConfig = false;
|
||||||
final var legacySignalProtocolStore = rootNode.hasNonNull("axolotlStore")
|
final var legacySignalProtocolStore = rootNode.hasNonNull("axolotlStore")
|
||||||
? jsonProcessor.convertValue(Utils.getNotNullNode(rootNode, "axolotlStore"),
|
? jsonProcessor.convertValue(Utils.getNotNullNode(rootNode, "axolotlStore"),
|
||||||
LegacyJsonSignalProtocolStore.class)
|
LegacyJsonSignalProtocolStore.class)
|
||||||
|
@ -331,11 +339,12 @@ public class SignalAccount implements Closeable {
|
||||||
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
|
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
|
||||||
identityKeyPair = legacySignalProtocolStore.getLegacyIdentityKeyStore().getIdentityKeyPair();
|
identityKeyPair = legacySignalProtocolStore.getLegacyIdentityKeyStore().getIdentityKeyPair();
|
||||||
registrationId = legacySignalProtocolStore.getLegacyIdentityKeyStore().getLocalRegistrationId();
|
registrationId = legacySignalProtocolStore.getLegacyIdentityKeyStore().getLocalRegistrationId();
|
||||||
|
migratedLegacyConfig = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
initStores(dataPath, identityKeyPair, registrationId);
|
initStores(dataPath, identityKeyPair, registrationId);
|
||||||
|
|
||||||
loadLegacyStores(rootNode, legacySignalProtocolStore);
|
migratedLegacyConfig = loadLegacyStores(rootNode, legacySignalProtocolStore) || migratedLegacyConfig;
|
||||||
|
|
||||||
if (rootNode.hasNonNull("groupStore")) {
|
if (rootNode.hasNonNull("groupStore")) {
|
||||||
groupStoreStorage = jsonProcessor.convertValue(rootNode.get("groupStore"), GroupStore.Storage.class);
|
groupStoreStorage = jsonProcessor.convertValue(rootNode.get("groupStore"), GroupStore.Storage.class);
|
||||||
|
@ -356,12 +365,17 @@ public class SignalAccount implements Closeable {
|
||||||
stickerStore = new StickerStore(this::saveStickerStore);
|
stickerStore = new StickerStore(this::saveStickerStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadLegacyThreadStore(rootNode);
|
migratedLegacyConfig = loadLegacyThreadStore(rootNode) || migratedLegacyConfig;
|
||||||
|
|
||||||
|
if (migratedLegacyConfig) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadLegacyStores(
|
private boolean loadLegacyStores(
|
||||||
final JsonNode rootNode, final LegacyJsonSignalProtocolStore legacySignalProtocolStore
|
final JsonNode rootNode, final LegacyJsonSignalProtocolStore legacySignalProtocolStore
|
||||||
) {
|
) {
|
||||||
|
var migrated = false;
|
||||||
var legacyRecipientStoreNode = rootNode.get("recipientStore");
|
var legacyRecipientStoreNode = rootNode.get("recipientStore");
|
||||||
if (legacyRecipientStoreNode != null) {
|
if (legacyRecipientStoreNode != null) {
|
||||||
logger.debug("Migrating legacy recipient store.");
|
logger.debug("Migrating legacy recipient store.");
|
||||||
|
@ -370,6 +384,7 @@ public class SignalAccount implements Closeable {
|
||||||
recipientStore.resolveRecipientsTrusted(legacyRecipientStore.getAddresses());
|
recipientStore.resolveRecipientsTrusted(legacyRecipientStore.getAddresses());
|
||||||
}
|
}
|
||||||
recipientStore.resolveRecipientTrusted(getSelfAddress());
|
recipientStore.resolveRecipientTrusted(getSelfAddress());
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyPreKeyStore() != null) {
|
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyPreKeyStore() != null) {
|
||||||
|
@ -381,6 +396,7 @@ public class SignalAccount implements Closeable {
|
||||||
logger.warn("Failed to migrate pre key, ignoring", e);
|
logger.warn("Failed to migrate pre key, ignoring", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacySignedPreKeyStore() != null) {
|
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacySignedPreKeyStore() != null) {
|
||||||
|
@ -392,6 +408,7 @@ public class SignalAccount implements Closeable {
|
||||||
logger.warn("Failed to migrate signed pre key, ignoring", e);
|
logger.warn("Failed to migrate signed pre key, ignoring", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacySessionStore() != null) {
|
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacySessionStore() != null) {
|
||||||
|
@ -404,6 +421,7 @@ public class SignalAccount implements Closeable {
|
||||||
logger.warn("Failed to migrate session, ignoring", e);
|
logger.warn("Failed to migrate session, ignoring", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
|
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
|
||||||
|
@ -415,6 +433,7 @@ public class SignalAccount implements Closeable {
|
||||||
identity.getIdentityKey(),
|
identity.getIdentityKey(),
|
||||||
identity.getTrustLevel());
|
identity.getTrustLevel());
|
||||||
}
|
}
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rootNode.hasNonNull("contactStore")) {
|
if (rootNode.hasNonNull("contactStore")) {
|
||||||
|
@ -442,6 +461,7 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rootNode.hasNonNull("profileStore")) {
|
if (rootNode.hasNonNull("profileStore")) {
|
||||||
|
@ -479,9 +499,11 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return migrated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadLegacyThreadStore(final JsonNode rootNode) {
|
private boolean loadLegacyThreadStore(final JsonNode rootNode) {
|
||||||
var threadStoreNode = rootNode.get("threadStore");
|
var threadStoreNode = rootNode.get("threadStore");
|
||||||
if (threadStoreNode != null && !threadStoreNode.isNull()) {
|
if (threadStoreNode != null && !threadStoreNode.isNull()) {
|
||||||
var threadStore = jsonProcessor.convertValue(threadStoreNode, LegacyJsonThreadStore.class);
|
var threadStore = jsonProcessor.convertValue(threadStoreNode, LegacyJsonThreadStore.class);
|
||||||
|
@ -511,7 +533,10 @@ public class SignalAccount implements Closeable {
|
||||||
logger.warn("Failed to read legacy thread info: {}", e.getMessage());
|
logger.warn("Failed to read legacy thread info: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveStickerStore(StickerStore.Storage storage) {
|
private void saveStickerStore(StickerStore.Storage storage) {
|
||||||
|
@ -524,7 +549,7 @@ public class SignalAccount implements Closeable {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
private void save() {
|
||||||
synchronized (fileChannel) {
|
synchronized (fileChannel) {
|
||||||
var rootNode = jsonProcessor.createObjectNode();
|
var rootNode = jsonProcessor.createObjectNode();
|
||||||
rootNode.put("username", username)
|
rootNode.put("username", username)
|
||||||
|
@ -645,6 +670,7 @@ public class SignalAccount implements Closeable {
|
||||||
|
|
||||||
public void setUuid(final UUID uuid) {
|
public void setUuid(final UUID uuid) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceAddress getSelfAddress() {
|
public SignalServiceAddress getSelfAddress() {
|
||||||
|
@ -659,10 +685,6 @@ public class SignalAccount implements Closeable {
|
||||||
return deviceId;
|
return deviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeviceId(final int deviceId) {
|
|
||||||
this.deviceId = deviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMasterDevice() {
|
public boolean isMasterDevice() {
|
||||||
return deviceId == SignalServiceAddress.DEFAULT_DEVICE_ID;
|
return deviceId == SignalServiceAddress.DEFAULT_DEVICE_ID;
|
||||||
}
|
}
|
||||||
|
@ -679,26 +701,25 @@ public class SignalAccount implements Closeable {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(final String password) {
|
private void setPassword(final String password) {
|
||||||
this.password = password;
|
this.password = password;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRegistrationLockPin() {
|
public String getRegistrationLockPin() {
|
||||||
return registrationLockPin;
|
return registrationLockPin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegistrationLockPin(final String registrationLockPin) {
|
public void setRegistrationLockPin(final String registrationLockPin, final MasterKey pinMasterKey) {
|
||||||
this.registrationLockPin = registrationLockPin;
|
this.registrationLockPin = registrationLockPin;
|
||||||
|
this.pinMasterKey = pinMasterKey;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MasterKey getPinMasterKey() {
|
public MasterKey getPinMasterKey() {
|
||||||
return pinMasterKey;
|
return pinMasterKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPinMasterKey(final MasterKey pinMasterKey) {
|
|
||||||
this.pinMasterKey = pinMasterKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StorageKey getStorageKey() {
|
public StorageKey getStorageKey() {
|
||||||
if (pinMasterKey != null) {
|
if (pinMasterKey != null) {
|
||||||
return pinMasterKey.deriveStorageServiceKey();
|
return pinMasterKey.deriveStorageServiceKey();
|
||||||
|
@ -707,7 +728,11 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStorageKey(final StorageKey storageKey) {
|
public void setStorageKey(final StorageKey storageKey) {
|
||||||
|
if (storageKey.equals(this.storageKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.storageKey = storageKey;
|
this.storageKey = storageKey;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileKey getProfileKey() {
|
public ProfileKey getProfileKey() {
|
||||||
|
@ -715,7 +740,11 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProfileKey(final ProfileKey profileKey) {
|
public void setProfileKey(final ProfileKey profileKey) {
|
||||||
|
if (profileKey.equals(this.profileKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.profileKey = profileKey;
|
this.profileKey = profileKey;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getSelfUnidentifiedAccessKey() {
|
public byte[] getSelfUnidentifiedAccessKey() {
|
||||||
|
@ -736,6 +765,7 @@ public class SignalAccount implements Closeable {
|
||||||
|
|
||||||
public void setRegistered(final boolean registered) {
|
public void setRegistered(final boolean registered) {
|
||||||
this.registered = registered;
|
this.registered = registered;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMultiDevice() {
|
public boolean isMultiDevice() {
|
||||||
|
@ -743,7 +773,11 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMultiDevice(final boolean multiDevice) {
|
public void setMultiDevice(final boolean multiDevice) {
|
||||||
|
if (isMultiDevice == multiDevice) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
isMultiDevice = multiDevice;
|
isMultiDevice = multiDevice;
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnrestrictedUnidentifiedAccess() {
|
public boolean isUnrestrictedUnidentifiedAccess() {
|
||||||
|
@ -756,11 +790,24 @@ public class SignalAccount implements Closeable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void finishRegistration(final UUID uuid, final MasterKey masterKey, final String pin) {
|
||||||
|
this.pinMasterKey = masterKey;
|
||||||
|
this.deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID;
|
||||||
|
this.isMultiDevice = false;
|
||||||
|
this.registered = true;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.registrationLockPin = pin;
|
||||||
|
save();
|
||||||
|
|
||||||
|
getSessionStore().archiveAllSessions();
|
||||||
|
final var recipientId = getRecipientStore().resolveRecipientTrusted(getSelfAddress());
|
||||||
|
final var publicKey = getIdentityKeyPair().getPublicKey();
|
||||||
|
getIdentityKeyStore().saveIdentity(recipientId, publicKey, new Date());
|
||||||
|
getIdentityKeyStore().setIdentityTrustLevel(recipientId, publicKey, TrustLevel.TRUSTED_VERIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (fileChannel.isOpen()) {
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
synchronized (fileChannel) {
|
synchronized (fileChannel) {
|
||||||
try {
|
try {
|
||||||
lock.close();
|
lock.close();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue