X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/e63e6e1fa2b90ba68a5351029a365bf477393301..bb342babba6bf716375ef4ba65919f80258aa29f:/src/main/java/org/asamk/signal/Manager.java diff --git a/src/main/java/org/asamk/signal/Manager.java b/src/main/java/org/asamk/signal/Manager.java index 585da2e8..8a606edd 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/Manager.java @@ -61,6 +61,8 @@ import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.push.exceptions.*; import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; +import org.whispersystems.signalservice.api.util.SleepTimer; +import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; @@ -116,6 +118,7 @@ class Manager implements Signal { private String username; private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; private String password; + private String registrationLockPin; private String signalingKey; private int preKeyIdOffset; private int nextSignedPreKeyId; @@ -129,6 +132,8 @@ class Manager implements Signal { private JsonThreadStore threadStore; private SignalServiceMessagePipe messagePipe = null; + private SleepTimer timer = new UptimeSleepTimer(); + public Manager(String username, String settingsPath) { this.username = username; this.settingsPath = settingsPath; @@ -237,7 +242,7 @@ class Manager implements Signal { migrateLegacyConfigs(); - accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, deviceId, USER_AGENT); + accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, deviceId, USER_AGENT, timer); try { if (registered && accountManager.getPreKeysCount() < PREKEY_MINIMUM_COUNT) { refreshPreKeys(); @@ -258,6 +263,8 @@ class Manager implements Signal { } username = getNotNullNode(rootNode, "username").asText(); password = getNotNullNode(rootNode, "password").asText(); + JsonNode pinNode = rootNode.get("registrationLockPin"); + registrationLockPin = pinNode == null ? null : pinNode.asText(); if (rootNode.has("signalingKey")) { signalingKey = getNotNullNode(rootNode, "signalingKey").asText(); } @@ -326,6 +333,7 @@ class Manager implements Signal { rootNode.put("username", username) .put("deviceId", deviceId) .put("password", password) + .put("registrationLockPin", registrationLockPin) .put("signalingKey", signalingKey) .put("preKeyIdOffset", preKeyIdOffset) .put("nextSignedPreKeyId", nextSignedPreKeyId) @@ -362,7 +370,7 @@ class Manager implements Signal { public void register(boolean voiceVerification) throws IOException { password = Util.getSecret(18); - accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, USER_AGENT); + accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, USER_AGENT, timer); if (voiceVerification) accountManager.requestVoiceVerificationCode(); @@ -374,7 +382,7 @@ class Manager implements Signal { } public void updateAccountAttributes() throws IOException { - accountManager.setAccountAttributes(signalingKey, signalProtocolStore.getLocalRegistrationId(), true); + accountManager.setAccountAttributes(signalingKey, signalProtocolStore.getLocalRegistrationId(), true, registrationLockPin); } public void unregister() throws IOException { @@ -387,7 +395,7 @@ class Manager implements Signal { public URI getDeviceLinkUri() throws TimeoutException, IOException { password = Util.getSecret(18); - accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, USER_AGENT); + accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, USER_AGENT, timer); String uuid = accountManager.getNewDeviceUuid(); registered = false; @@ -504,18 +512,28 @@ class Manager implements Signal { } } - public void verifyAccount(String verificationCode) throws IOException { + public void verifyAccount(String verificationCode, String pin) throws IOException { verificationCode = verificationCode.replace("-", ""); signalingKey = Util.getSecret(52); - accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), true); + accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), true, pin); //accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID))); registered = true; + registrationLockPin = pin; refreshPreKeys(); save(); } + public void setRegistrationLockPin(Optional pin) throws IOException { + accountManager.setPin(pin); + if (pin.isPresent()) { + registrationLockPin = pin.get(); + } else { + registrationLockPin = null; + } + } + private void refreshPreKeys() throws IOException { List oneTimePreKeys = generatePreKeys(); SignedPreKeyRecord signedPreKeyRecord = generateSignedPreKey(signalProtocolStore.getIdentityKeyPair()); @@ -547,7 +565,7 @@ class Manager implements Signal { mime = "application/octet-stream"; } // TODO mabybe add a parameter to set the voiceNote and preview option - return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, Optional.absent(), null); + return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, Optional.absent(), 0, 0, null); } private Optional createGroupAvatarAttachment(byte[] groupId) throws IOException { @@ -804,6 +822,16 @@ class Manager implements Signal { save(); } + @Override + public List getGroupIds() { + List groups = getGroups(); + List ids = new ArrayList(groups.size()); + for (GroupInfo group : groups) { + ids.add(group.groupId); + } + return ids; + } + @Override public String getGroupName(byte[] groupId) { GroupInfo group = getGroup(groupId); @@ -1111,7 +1139,7 @@ class Manager implements Signal { public void receiveMessages(long timeout, TimeUnit unit, boolean returnOnTimeout, boolean ignoreAttachments, ReceiveMessageHandler handler) throws IOException { retryFailedReceivedMessages(handler, ignoreAttachments); - final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null); + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null, timer); try { if (messagePipe == null) { @@ -1220,6 +1248,9 @@ class Manager implements Signal { } syncGroup.members.addAll(g.getMembers()); syncGroup.active = g.isActive(); + if (g.getColor().isPresent()) { + syncGroup.color = g.getColor().get(); + } if (g.getAvatar().isPresent()) { retrieveGroupAvatarAttachment(g.getAvatar().get(), syncGroup.groupId); @@ -1413,7 +1444,7 @@ class Manager implements Signal { } } - final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null); + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null, timer); File tmpFile = Util.createTempFile(); try (InputStream input = messageReceiver.retrieveAttachment(pointer, tmpFile, MAX_ATTACHMENT_SIZE)) { @@ -1439,7 +1470,7 @@ class Manager implements Signal { } private InputStream retrieveAttachmentAsStream(SignalServiceAttachmentPointer pointer, File tmpFile) throws IOException, InvalidMessageException { - final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null); + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null, timer); return messageReceiver.retrieveAttachment(pointer, tmpFile, MAX_ATTACHMENT_SIZE); } @@ -1465,9 +1496,11 @@ class Manager implements Signal { try (OutputStream fos = new FileOutputStream(groupsFile)) { DeviceGroupsOutputStream out = new DeviceGroupsOutputStream(fos); for (GroupInfo record : groupStore.getGroups()) { + ThreadInfo info = threadStore.getThread(Base64.encodeBytes(record.groupId)); out.write(new DeviceGroup(record.groupId, Optional.fromNullable(record.name), new ArrayList<>(record.members), createGroupAvatarAttachment(record.groupId), - record.active)); + record.active, Optional.fromNullable(info != null ? info.messageExpirationTime : null), + Optional.fromNullable(record.color))); } } @@ -1499,6 +1532,7 @@ class Manager implements Signal { DeviceContactsOutputStream out = new DeviceContactsOutputStream(fos); for (ContactInfo record : contactStore.getContacts()) { VerifiedMessage verifiedMessage = null; + ThreadInfo info = threadStore.getThread(record.number); if (getIdentities().containsKey(record.number)) { JsonIdentityKeyStore.Identity currentIdentity = null; for (JsonIdentityKeyStore.Identity id : getIdentities().get(record.number)) { @@ -1514,7 +1548,7 @@ class Manager implements Signal { // TODO include profile key out.write(new DeviceContact(record.number, Optional.fromNullable(record.name), createContactAvatarAttachment(record.number), Optional.fromNullable(record.color), - Optional.fromNullable(verifiedMessage), Optional.absent())); + Optional.fromNullable(verifiedMessage), Optional.absent(), false, Optional.fromNullable(info != null ? info.messageExpirationTime : null))); } }