import org.asamk.signal.manager.storage.groups.GroupInfo;
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
import org.asamk.signal.manager.storage.groups.JsonGroupStore;
+import org.asamk.signal.manager.storage.messageCache.MessageCache;
import org.asamk.signal.manager.storage.profiles.ProfileStore;
import org.asamk.signal.manager.storage.protocol.IdentityInfo;
import org.asamk.signal.manager.storage.protocol.JsonSignalProtocolStore;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.kbs.MasterKey;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
-import org.whispersystems.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.util.Base64;
import java.util.Collection;
import java.util.UUID;
import java.util.stream.Collectors;
public class SignalAccount implements Closeable {
- final static Logger logger = LoggerFactory.getLogger(SignalAccount.class);
+ private final static Logger logger = LoggerFactory.getLogger(SignalAccount.class);
private final ObjectMapper jsonProcessor = new ObjectMapper();
private final FileChannel fileChannel;
private ProfileStore profileStore;
private StickerStore stickerStore;
+ private MessageCache messageCache;
+
private SignalAccount(final FileChannel fileChannel, final FileLock lock) {
this.fileChannel = fileChannel;
this.lock = lock;
jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); // disable autodetect
- jsonProcessor.enable(SerializationFeature.INDENT_OUTPUT); // for pretty print, you can disable it.
+ jsonProcessor.enable(SerializationFeature.INDENT_OUTPUT); // for pretty print
jsonProcessor.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
jsonProcessor.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
account.recipientStore = new RecipientStore();
account.profileStore = new ProfileStore();
account.stickerStore = new StickerStore();
+
+ account.messageCache = new MessageCache(getMessageCachePath(dataPath, username));
+
account.registered = false;
+ account.migrateLegacyConfigs();
+
return account;
}
account.recipientStore = new RecipientStore();
account.profileStore = new ProfileStore();
account.stickerStore = new StickerStore();
+
+ account.messageCache = new MessageCache(getMessageCachePath(dataPath, username));
+
account.registered = true;
account.isMultiDevice = true;
+ account.migrateLegacyConfigs();
+
return account;
}
}
final ProfileKey profileKey;
try {
- profileKey = new ProfileKey(Base64.decode(profileKeyString));
- } catch (InvalidInputException | IOException e) {
+ profileKey = new ProfileKey(Base64.getDecoder().decode(profileKeyString));
+ } catch (InvalidInputException ignored) {
continue;
}
contact.profileKey = null;
JsonNode pinMasterKeyNode = rootNode.get("pinMasterKey");
pinMasterKey = pinMasterKeyNode == null || pinMasterKeyNode.isNull()
? null
- : new MasterKey(Base64.decode(pinMasterKeyNode.asText()));
+ : new MasterKey(Base64.getDecoder().decode(pinMasterKeyNode.asText()));
if (rootNode.has("signalingKey")) {
signalingKey = Utils.getNotNullNode(rootNode, "signalingKey").asText();
}
}
if (rootNode.has("profileKey")) {
try {
- profileKey = new ProfileKey(Base64.decode(Utils.getNotNullNode(rootNode, "profileKey").asText()));
+ profileKey = new ProfileKey(Base64.getDecoder()
+ .decode(Utils.getNotNullNode(rootNode, "profileKey").asText()));
} catch (InvalidInputException e) {
throw new IOException(
"Config file contains an invalid profileKey, needs to be base64 encoded array of 32 bytes",
stickerStore = new StickerStore();
}
+ messageCache = new MessageCache(getMessageCachePath(dataPath, username));
+
JsonNode threadStoreNode = rootNode.get("threadStore");
- if (threadStoreNode != null) {
+ if (threadStoreNode != null && !threadStoreNode.isNull()) {
LegacyJsonThreadStore threadStore = jsonProcessor.convertValue(threadStoreNode,
LegacyJsonThreadStore.class);
// Migrate thread info to group and contact store
.put("isMultiDevice", isMultiDevice)
.put("password", password)
.put("registrationLockPin", registrationLockPin)
- .put("pinMasterKey", pinMasterKey == null ? null : Base64.encodeBytes(pinMasterKey.serialize()))
+ .put("pinMasterKey",
+ pinMasterKey == null ? null : Base64.getEncoder().encodeToString(pinMasterKey.serialize()))
.put("signalingKey", signalingKey)
.put("preKeyIdOffset", preKeyIdOffset)
.put("nextSignedPreKeyId", nextSignedPreKeyId)
- .put("profileKey", Base64.encodeBytes(profileKey.serialize()))
+ .put("profileKey", Base64.getEncoder().encodeToString(profileKey.serialize()))
.put("registered", registered)
.putPOJO("axolotlStore", signalProtocolStore)
.putPOJO("groupStore", groupStore)
return stickerStore;
}
+ public MessageCache getMessageCache() {
+ return messageCache;
+ }
+
public String getUsername() {
return username;
}
@Override
public void close() throws IOException {
- save();
+ if (fileChannel.isOpen()) {
+ save();
+ }
synchronized (fileChannel) {
try {
lock.close();