Handle saving inside SignalAccount

This commit is contained in:
AsamK 2021-05-02 22:03:41 +02:00
parent 5b8c0c4e2d
commit 530ef51ba7
4 changed files with 84 additions and 80 deletions

View file

@ -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,19 +1371,15 @@ 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);
final var expirationTime = contact != null ? contact.getMessageExpirationTime() : 0; final var expirationTime = contact != null ? contact.getMessageExpirationTime() : 0;
messageBuilder.withExpiration(expirationTime); messageBuilder.withExpiration(expirationTime);
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) {

View file

@ -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;

View file

@ -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;

View file

@ -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();