This commit is contained in:
Gabriel Fernández Valdés 2019-10-21 21:33:11 -04:00
commit 2e52a7ffd5
47 changed files with 434 additions and 37 deletions

View file

@ -15,5 +15,11 @@
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="0" />
<arrangement>
<rules />
</arrangement>
</codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View file

@ -20,8 +20,8 @@ repositories {
} }
dependencies { dependencies {
compile 'com.github.turasa:signal-service-java:2.13.8_unofficial_1' compile 'com.github.turasa:signal-service-java:2.13.9_unofficial_1'
compile 'org.bouncycastle:bcprov-jdk15on:1.62' compile 'org.bouncycastle:bcprov-jdk15on:1.64'
compile 'net.sourceforge.argparse4j:argparse4j:0.8.1' compile 'net.sourceforge.argparse4j:argparse4j:0.8.1'
compile 'org.freedesktop.dbus:dbus-java:2.7.0' compile 'org.freedesktop.dbus:dbus-java:2.7.0'
} }

View file

@ -208,6 +208,38 @@ number::
Specify the safety number or fingerprint of the key, only use this option if you have verified Specify the safety number or fingerprint of the key, only use this option if you have verified
the fingerprint. the fingerprint.
updateProfile
--------------
Update the name and/or avatar image visible by message recipients for the current users.
The profile is stored encrypted on the Signal servers. The decryption key is sent
with every outgoing messages (excluding group messages).
*--name*::
New name visible by message recipients.
*--avatar*::
Path to the new avatar visible by message recipients.
*--remove-avatar*::
Remove the avatar visible by message recipients.
updateContact
--------------
Update the info associated to a number on our contact list. This change is only
local but can be synchronized to other devices by using `sendContacts` (see
below).
If the contact doesn't exist yet, it will be added.
NUMBER::
Specify the contact phone number.
*-n*, *--name*::
Specify the new name for this contact.
sendContacts
------------
Send a synchronization message with the local contacts list to all linked devices.
This command should only be used if this is the master device.
daemon daemon
~~~~~~ ~~~~~~

View file

@ -1,6 +1,11 @@
package org.asamk.signal; package org.asamk.signal;
import org.whispersystems.signalservice.api.messages.calls.*; import org.whispersystems.signalservice.api.messages.calls.AnswerMessage;
import org.whispersystems.signalservice.api.messages.calls.BusyMessage;
import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
import org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage;
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
import java.util.List; import java.util.List;

View file

@ -4,7 +4,11 @@ import org.asamk.Signal;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.freedesktop.dbus.DBusConnection; import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusException;
import org.whispersystems.signalservice.api.messages.*; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View file

@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceContent; import org.whispersystems.signalservice.api.messages.SignalServiceContent;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;

View file

@ -2,9 +2,6 @@ package org.asamk.signal;
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage; import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage;
import java.util.ArrayList;
import java.util.List;
class JsonSyncDataMessage extends JsonDataMessage { class JsonSyncDataMessage extends JsonDataMessage {
String destination; String destination;

View file

@ -18,9 +18,19 @@ package org.asamk.signal;
import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.*; import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.commands.*; import org.asamk.signal.commands.Command;
import org.asamk.signal.commands.Commands;
import org.asamk.signal.commands.DbusCommand;
import org.asamk.signal.commands.ExtendedDbusCommand;
import org.asamk.signal.commands.LocalCommand;
import org.asamk.signal.manager.BaseConfig; import org.asamk.signal.manager.BaseConfig;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.asamk.signal.util.IOUtils; import org.asamk.signal.util.IOUtils;

View file

@ -5,9 +5,27 @@ import org.asamk.signal.storage.contacts.ContactInfo;
import org.asamk.signal.storage.groups.GroupInfo; import org.asamk.signal.storage.groups.GroupInfo;
import org.asamk.signal.util.DateUtils; import org.asamk.signal.util.DateUtils;
import org.asamk.signal.util.Util; import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.*; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.calls.*; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
import org.whispersystems.signalservice.api.messages.multidevice.*; import org.whispersystems.signalservice.api.messages.SignalServiceContent;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage;
import org.whispersystems.signalservice.api.messages.calls.AnswerMessage;
import org.whispersystems.signalservice.api.messages.calls.BusyMessage;
import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
import org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage;
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;

View file

@ -20,11 +20,14 @@ public class Commands {
addCommand("removeDevice", new RemoveDeviceCommand()); addCommand("removeDevice", new RemoveDeviceCommand());
addCommand("removePin", new RemovePinCommand()); addCommand("removePin", new RemovePinCommand());
addCommand("send", new SendCommand()); addCommand("send", new SendCommand());
addCommand("sendContacts", new SendContactsCommand());
addCommand("updateContact", new UpdateContactCommand());
addCommand("setPin", new SetPinCommand()); addCommand("setPin", new SetPinCommand());
addCommand("trust", new TrustCommand()); addCommand("trust", new TrustCommand());
addCommand("unregister", new UnregisterCommand()); addCommand("unregister", new UnregisterCommand());
addCommand("updateAccount", new UpdateAccountCommand()); addCommand("updateAccount", new UpdateAccountCommand());
addCommand("updateGroup", new UpdateGroupCommand()); addCommand("updateGroup", new UpdateGroupCommand());
addCommand("updateProfile", new UpdateProfileCommand());
addCommand("verify", new VerifyCommand()); addCommand("verify", new VerifyCommand());
} }

View file

@ -3,6 +3,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.DbusReceiveMessageHandler; import org.asamk.signal.DbusReceiveMessageHandler;
import org.asamk.signal.JsonDbusReceiveMessageHandler; import org.asamk.signal.JsonDbusReceiveMessageHandler;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;

View file

@ -1,6 +1,7 @@
package org.asamk.signal.commands; package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.Signal; import org.asamk.Signal;
public interface DbusCommand extends Command { public interface DbusCommand extends Command {

View file

@ -1,6 +1,7 @@
package org.asamk.signal.commands; package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.Signal; import org.asamk.Signal;
import org.freedesktop.dbus.DBusConnection; import org.freedesktop.dbus.DBusConnection;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.UserAlreadyExists; import org.asamk.signal.UserAlreadyExists;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.asamk.signal.util.DateUtils; import org.asamk.signal.util.DateUtils;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo; import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo;

View file

@ -3,6 +3,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.asamk.signal.storage.groups.GroupInfo; import org.asamk.signal.storage.groups.GroupInfo;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.asamk.signal.storage.protocol.JsonIdentityKeyStore; import org.asamk.signal.storage.protocol.JsonIdentityKeyStore;
import org.asamk.signal.util.Hex; import org.asamk.signal.util.Hex;

View file

@ -1,6 +1,7 @@
package org.asamk.signal.commands; package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
public interface LocalCommand extends Command { public interface LocalCommand extends Command {

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.GroupIdFormatException; import org.asamk.signal.GroupIdFormatException;
import org.asamk.signal.GroupNotFoundException; import org.asamk.signal.GroupNotFoundException;
import org.asamk.signal.NotAGroupMemberException; import org.asamk.signal.NotAGroupMemberException;
@ -11,7 +12,12 @@ import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptio
import java.io.IOException; import java.io.IOException;
import static org.asamk.signal.util.ErrorUtils.*; import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
import static org.asamk.signal.util.ErrorUtils.handleEncapsulatedExceptions;
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
import static org.asamk.signal.util.ErrorUtils.handleGroupNotFoundException;
import static org.asamk.signal.util.ErrorUtils.handleIOException;
import static org.asamk.signal.util.ErrorUtils.handleNotAGroupMemberException;
public class QuitGroupCommand implements LocalCommand { public class QuitGroupCommand implements LocalCommand {

View file

@ -3,6 +3,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.JsonReceiveMessageHandler; import org.asamk.signal.JsonReceiveMessageHandler;
import org.asamk.signal.ReceiveMessageHandler; import org.asamk.signal.ReceiveMessageHandler;

View file

@ -3,6 +3,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import java.io.IOException; import java.io.IOException;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import java.io.IOException; import java.io.IOException;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.libsignal.util.guava.Optional;

View file

@ -3,6 +3,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.AttachmentInvalidException; import org.asamk.signal.AttachmentInvalidException;
import org.asamk.signal.GroupIdFormatException; import org.asamk.signal.GroupIdFormatException;
@ -18,7 +19,13 @@ import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.asamk.signal.util.ErrorUtils.*; import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
import static org.asamk.signal.util.ErrorUtils.handleDBusExecutionException;
import static org.asamk.signal.util.ErrorUtils.handleEncapsulatedExceptions;
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
import static org.asamk.signal.util.ErrorUtils.handleGroupNotFoundException;
import static org.asamk.signal.util.ErrorUtils.handleIOException;
import static org.asamk.signal.util.ErrorUtils.handleNotAGroupMemberException;
public class SendCommand implements DbusCommand { public class SendCommand implements DbusCommand {

View file

@ -0,0 +1,31 @@
package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import java.io.IOException;
public class SendContactsCommand implements LocalCommand {
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Send a synchronization message with the local contacts list to all linked devices.");
}
@Override
public int handleCommand(final Namespace ns, final Manager m) {
if (!m.isRegistered()) {
System.err.println("User is not registered.");
return 1;
}
try {
m.sendContacts();
return 0;
} catch (IOException | UntrustedIdentityException e) {
System.err.println("SendContacts error: " + e.getMessage());
return 3;
}
}
}

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.libsignal.util.guava.Optional;

View file

@ -4,6 +4,7 @@ import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.asamk.signal.util.Hex; import org.asamk.signal.util.Hex;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import java.io.IOException; import java.io.IOException;

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import java.io.IOException; import java.io.IOException;

View file

@ -0,0 +1,34 @@
package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager;
public class UpdateContactCommand implements LocalCommand {
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.addArgument("number")
.help("Contact number");
subparser.addArgument("-n", "--name")
.required(true)
.help("New contact name");
subparser.help("Update the details of a given contact");
}
@Override
public int handleCommand(final Namespace ns, final Manager m) {
if (!m.isRegistered()) {
System.err.println("User is not registered.");
return 1;
}
String number = ns.getString("number");
String name = ns.getString("name");
m.setContactName(number, name);
return 0;
}
}

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.AttachmentInvalidException; import org.asamk.signal.AttachmentInvalidException;
import org.asamk.signal.GroupIdFormatException; import org.asamk.signal.GroupIdFormatException;
@ -15,7 +16,11 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.asamk.signal.util.ErrorUtils.*; import static org.asamk.signal.util.ErrorUtils.handleEncapsulatedExceptions;
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
import static org.asamk.signal.util.ErrorUtils.handleGroupNotFoundException;
import static org.asamk.signal.util.ErrorUtils.handleIOException;
import static org.asamk.signal.util.ErrorUtils.handleNotAGroupMemberException;
public class UpdateGroupCommand implements DbusCommand { public class UpdateGroupCommand implements DbusCommand {

View file

@ -0,0 +1,73 @@
package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager;
import java.io.File;
import java.io.IOException;
public class UpdateProfileCommand implements LocalCommand {
@Override
public void attachToSubparser(final Subparser subparser) {
final MutuallyExclusiveGroup avatarOptions = subparser.addMutuallyExclusiveGroup();
avatarOptions.addArgument("--avatar")
.help("Path to new profile avatar");
avatarOptions.addArgument("--remove-avatar")
.action(Arguments.storeTrue());
subparser.addArgument("--name")
.help("New profile name");
subparser.help("Set a name and/or avatar image for the user profile");
}
@Override
public int handleCommand(final Namespace ns, final Manager m) {
if (!m.isRegistered()) {
System.err.println("User is not registered.");
return 1;
}
String name = ns.getString("name");
if (name != null) {
try {
m.setProfileName(name);
} catch (IOException e) {
System.err.println("UpdateAccount error: " + e.getMessage());
return 3;
}
}
String avatarPath = ns.getString("avatar");
if (avatarPath != null) {
File avatarFile = new File(avatarPath);
try {
m.setProfileAvatar(avatarFile);
} catch (IOException e) {
System.err.println("UpdateAccount error: " + e.getMessage());
return 3;
}
}
boolean removeAvatar = ns.getBoolean("remove_avatar");
if (removeAvatar) {
try {
m.removeProfileAvatar();
} catch (IOException e) {
System.err.println("UpdateAccount error: " + e.getMessage());
return 3;
}
}
return 0;
}
}

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.internal.push.LockedException; import org.whispersystems.signalservice.internal.push.LockedException;

View file

@ -17,7 +17,11 @@
package org.asamk.signal.manager; package org.asamk.signal.manager;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.*; import org.asamk.signal.AttachmentInvalidException;
import org.asamk.signal.GroupNotFoundException;
import org.asamk.signal.NotAGroupMemberException;
import org.asamk.signal.TrustLevel;
import org.asamk.signal.UserAlreadyExists;
import org.asamk.signal.storage.SignalAccount; import org.asamk.signal.storage.SignalAccount;
import org.asamk.signal.storage.contacts.ContactInfo; import org.asamk.signal.storage.contacts.ContactInfo;
import org.asamk.signal.storage.groups.GroupInfo; import org.asamk.signal.storage.groups.GroupInfo;
@ -26,8 +30,22 @@ import org.asamk.signal.storage.protocol.JsonIdentityKeyStore;
import org.asamk.signal.storage.threads.ThreadInfo; import org.asamk.signal.storage.threads.ThreadInfo;
import org.asamk.signal.util.IOUtils; import org.asamk.signal.util.IOUtils;
import org.asamk.signal.util.Util; import org.asamk.signal.util.Util;
import org.signal.libsignal.metadata.*; import org.signal.libsignal.metadata.InvalidMetadataMessageException;
import org.whispersystems.libsignal.*; import org.signal.libsignal.metadata.InvalidMetadataVersionException;
import org.signal.libsignal.metadata.ProtocolDuplicateMessageException;
import org.signal.libsignal.metadata.ProtocolInvalidKeyException;
import org.signal.libsignal.metadata.ProtocolInvalidKeyIdException;
import org.signal.libsignal.metadata.ProtocolInvalidMessageException;
import org.signal.libsignal.metadata.ProtocolInvalidVersionException;
import org.signal.libsignal.metadata.ProtocolLegacyMessageException;
import org.signal.libsignal.metadata.ProtocolNoSessionException;
import org.signal.libsignal.metadata.ProtocolUntrustedIdentityException;
import org.signal.libsignal.metadata.SelfSendException;
import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.IdentityKeyPair;
import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.InvalidMessageException;
import org.whispersystems.libsignal.InvalidVersionException;
import org.whispersystems.libsignal.ecc.Curve; import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECKeyPair; import org.whispersystems.libsignal.ecc.ECKeyPair;
import org.whispersystems.libsignal.ecc.ECPublicKey; import org.whispersystems.libsignal.ecc.ECPublicKey;
@ -44,8 +62,26 @@ import org.whispersystems.signalservice.api.crypto.SignalServiceCipher;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.*; import org.whispersystems.signalservice.api.messages.SendMessageResult;
import org.whispersystems.signalservice.api.messages.multidevice.*; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroup;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroupsInputStream;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroupsOutputStream;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo;
import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.ContactTokenDetails; import org.whispersystems.signalservice.api.push.ContactTokenDetails;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
@ -54,17 +90,35 @@ import org.whispersystems.signalservice.api.push.exceptions.NetworkFailureExcept
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.SleepTimer;
import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException; import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;
import java.io.*; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI; import java.net.URI;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -204,6 +258,20 @@ public class Manager implements Signal {
accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), getSelfUnidentifiedAccessKey(), false); accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), getSelfUnidentifiedAccessKey(), false);
} }
public void setProfileName(String name) throws IOException {
accountManager.setProfileName(account.getProfileKey(), name);
}
public void setProfileAvatar(File avatar) throws IOException {
final StreamDetails streamDetails = Utils.createStreamDetailsFromFile(avatar);
accountManager.setProfileAvatar(account.getProfileKey(), streamDetails);
streamDetails.getStream().close();
}
public void removeProfileAvatar() throws IOException {
accountManager.setProfileAvatar(account.getProfileKey(), null);
}
public void unregister() throws IOException { public void unregister() throws IOException {
// When setting an empty GCM id, the Signal-Server also sets the fetchesMessages property to false. // When setting an empty GCM id, the Signal-Server also sets the fetchesMessages property to false.
// If this is the master device, other users can't send messages to this number anymore. // If this is the master device, other users can't send messages to this number anymore.
@ -564,6 +632,7 @@ public class Manager implements Signal {
if (attachments != null) { if (attachments != null) {
messageBuilder.withAttachments(Utils.getSignalServiceAttachments(attachments)); messageBuilder.withAttachments(Utils.getSignalServiceAttachments(attachments));
} }
messageBuilder.withProfileKey(account.getProfileKey());
sendMessageLegacy(messageBuilder, recipients); sendMessageLegacy(messageBuilder, recipients);
} }
@ -1347,7 +1416,7 @@ public class Manager implements Signal {
} }
} }
private void sendContacts() throws IOException, UntrustedIdentityException { public void sendContacts() throws IOException, UntrustedIdentityException {
File contactsFile = IOUtils.createTempFile(); File contactsFile = IOUtils.createTempFile();
try { try {

View file

@ -15,14 +15,30 @@ import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;
import java.io.*; import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.whispersystems.signalservice.internal.util.Util.isEmpty; import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
@ -53,7 +69,18 @@ class Utils {
// TODO mabybe add a parameter to set the voiceNote, preview, width, height and caption option // TODO mabybe add a parameter to set the voiceNote, preview, width, height and caption option
Optional<byte[]> preview = Optional.absent(); Optional<byte[]> preview = Optional.absent();
Optional<String> caption = Optional.absent(); Optional<String> caption = Optional.absent();
return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, preview, 0, 0, caption, null); Optional<String> blurHash = Optional.absent();
return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, preview, 0, 0, caption, blurHash, null);
}
static StreamDetails createStreamDetailsFromFile(File file) throws IOException {
InputStream stream = new FileInputStream(file);
final long size = file.length();
String mime = Files.probeContentType(file.toPath());
if (mime == null) {
mime = "application/octet-stream";
}
return new StreamDetails(stream, mime, size);
} }
static CertificateValidator getCertificateValidator() { static CertificateValidator getCertificateValidator() {

View file

@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.asamk.signal.storage.contacts.JsonContactsStore; import org.asamk.signal.storage.contacts.JsonContactsStore;
import org.asamk.signal.storage.groups.JsonGroupStore; import org.asamk.signal.storage.groups.JsonGroupStore;
import org.asamk.signal.storage.protocol.JsonSignalProtocolStore; import org.asamk.signal.storage.protocol.JsonSignalProtocolStore;
@ -139,7 +140,9 @@ public class SignalAccount {
if (node != null) { if (node != null) {
deviceId = node.asInt(); deviceId = node.asInt();
} }
if (rootNode.has("isMultiDevice")) isMultiDevice = Util.getNotNullNode(rootNode, "isMultiDevice").asBoolean(); if (rootNode.has("isMultiDevice")) {
isMultiDevice = Util.getNotNullNode(rootNode, "isMultiDevice").asBoolean();
}
username = Util.getNotNullNode(rootNode, "username").asText(); username = Util.getNotNullNode(rootNode, "username").asText();
password = Util.getNotNullNode(rootNode, "password").asText(); password = Util.getNotNullNode(rootNode, "password").asText();
JsonNode pinNode = rootNode.get("registrationLockPin"); JsonNode pinNode = rootNode.get("registrationLockPin");

View file

@ -3,7 +3,12 @@ package org.asamk.signal.storage.contacts;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;

View file

@ -3,9 +3,15 @@ package org.asamk.signal.storage.groups;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;
import java.io.IOException; import java.io.IOException;

View file

@ -2,7 +2,12 @@ package org.asamk.signal.storage.protocol;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.asamk.signal.TrustLevel; import org.asamk.signal.TrustLevel;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.IdentityKeyPair;
@ -12,7 +17,11 @@ import org.whispersystems.libsignal.state.IdentityKeyStore;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JsonIdentityKeyStore implements IdentityKeyStore { public class JsonIdentityKeyStore implements IdentityKeyStore {

View file

@ -2,7 +2,12 @@ package org.asamk.signal.storage.protocol;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.whispersystems.libsignal.InvalidKeyIdException; import org.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.state.PreKeyRecord; import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.PreKeyStore; import org.whispersystems.libsignal.state.PreKeyStore;

View file

@ -2,14 +2,23 @@ package org.asamk.signal.storage.protocol;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.state.SessionRecord; import org.whispersystems.libsignal.state.SessionRecord;
import org.whispersystems.libsignal.state.SessionStore; import org.whispersystems.libsignal.state.SessionStore;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
class JsonSessionStore implements SessionStore { class JsonSessionStore implements SessionStore {

View file

@ -3,6 +3,7 @@ package org.asamk.signal.storage.protocol;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.asamk.signal.TrustLevel; import org.asamk.signal.TrustLevel;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.IdentityKeyPair;

View file

@ -2,7 +2,12 @@ package org.asamk.signal.storage.protocol;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.whispersystems.libsignal.InvalidKeyIdException; import org.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.state.SignedPreKeyRecord; import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyStore; import org.whispersystems.libsignal.state.SignedPreKeyStore;

View file

@ -3,7 +3,12 @@ package org.asamk.signal.storage.threads;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;

View file

@ -12,7 +12,9 @@ import java.nio.file.attribute.PosixFilePermissions;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Set; import java.util.Set;
import static java.nio.file.attribute.PosixFilePermission.*; import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE;
import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
public class IOUtils { public class IOUtils {

View file

@ -1,6 +1,7 @@
package org.asamk.signal.util; package org.asamk.signal.util;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.asamk.signal.GroupIdFormatException; import org.asamk.signal.GroupIdFormatException;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;