}
dependencies {
- api("com.github.turasa:signal-service-java:2.15.3_unofficial_31")
+ implementation("com.github.turasa:signal-service-java:2.15.3_unofficial_31")
api("com.fasterxml.jackson.core", "jackson-databind", "2.13.0")
implementation("com.google.protobuf:protobuf-javalite:3.10.0")
implementation("org.bouncycastle:bcprov-jdk15on:1.69")
return new ManagerImpl(account, pathConfig, serviceEnvironmentConfig, userAgent);
}
+ static void initLogger() {
+ LibSignalLogger.initLogger();
+ }
+
+ static boolean isValidNumber(final String e164Number, final String countryCode) {
+ return PhoneNumberFormatter.isValidNumber(e164Number, countryCode);
+ }
+
static List<String> getAllLocalNumbers(File settingsPath) {
var pathConfig = PathConfig.createDefault(settingsPath);
final var dataPath = pathConfig.dataPath();
import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.SendGroupMessageResults;
+import org.asamk.signal.manager.api.SendMessageResult;
import org.asamk.signal.manager.api.SendMessageResults;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UpdateGroup;
import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalSessionLock;
-import org.whispersystems.signalservice.api.messages.SendMessageResult;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
if (recipient instanceof RecipientIdentifier.Single single) {
final var recipientId = resolveRecipient(single);
final var result = sendHelper.sendMessage(messageBuilder, recipientId);
- results.put(recipient, List.of(result));
+ results.put(recipient,
+ List.of(SendMessageResult.from(result,
+ account.getRecipientStore(),
+ account.getRecipientStore()::resolveRecipientAddress)));
} else if (recipient instanceof RecipientIdentifier.NoteToSelf) {
final var result = sendHelper.sendSelfMessage(messageBuilder);
- results.put(recipient, List.of(result));
+ results.put(recipient,
+ List.of(SendMessageResult.from(result,
+ account.getRecipientStore(),
+ account.getRecipientStore()::resolveRecipientAddress)));
} else if (recipient instanceof RecipientIdentifier.Group group) {
final var result = sendHelper.sendAsGroupMessage(messageBuilder, group.groupId());
- results.put(recipient, result);
+ results.put(recipient,
+ result.stream()
+ .map(sendMessageResult -> SendMessageResult.from(sendMessageResult,
+ account.getRecipientStore(),
+ account.getRecipientStore()::resolveRecipientAddress))
+ .collect(Collectors.toList()));
}
}
return new SendMessageResults(timestamp, results);
}
private void handleIdentityFailure(
- final RecipientId recipientId, final SendMessageResult.IdentityFailure identityFailure
+ final RecipientId recipientId,
+ final org.whispersystems.signalservice.api.messages.SendMessageResult.IdentityFailure identityFailure
) {
this.identityHelper.handleIdentityFailure(recipientId, identityFailure);
}
*/
package org.asamk.signal.manager;
+import org.asamk.signal.manager.api.CaptchaRequiredException;
+import org.asamk.signal.manager.api.IncorrectPinException;
+import org.asamk.signal.manager.api.PinLockedException;
import org.asamk.signal.manager.config.ServiceConfig;
import org.asamk.signal.manager.config.ServiceEnvironment;
import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.KeyHelper;
import org.whispersystems.libsignal.util.guava.Optional;
+import org.whispersystems.signalservice.api.KbsPinData;
import org.whispersystems.signalservice.api.KeyBackupServicePinException;
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
return new RegistrationManager(account, pathConfig, serviceConfiguration, userAgent);
}
- public void register(boolean voiceVerification, String captcha) throws IOException {
+ public void register(boolean voiceVerification, String captcha) throws IOException, CaptchaRequiredException {
final ServiceResponse<RequestVerificationCodeResponse> response;
if (voiceVerification) {
response = accountManager.requestVoiceVerificationCode(getDefaultLocale(),
Optional.absent(),
Optional.absent());
}
- handleResponseException(response);
+ try {
+ handleResponseException(response);
+ } catch (org.whispersystems.signalservice.api.push.exceptions.CaptchaRequiredException e) {
+ throw new CaptchaRequiredException(e.getMessage(), e);
+ }
}
private Locale getDefaultLocale() {
public Manager verifyAccount(
String verificationCode, String pin
- ) throws IOException, LockedException, KeyBackupSystemNoDataException, KeyBackupServicePinException {
+ ) throws IOException, PinLockedException, IncorrectPinException {
verificationCode = verificationCode.replace("-", "");
VerifyAccountResponse response;
MasterKey masterKey;
pin = null;
} catch (LockedException e) {
if (pin == null) {
- throw e;
+ throw new PinLockedException(e.getTimeRemaining());
}
- var registrationLockData = pinHelper.getRegistrationLockData(pin, e);
+ KbsPinData registrationLockData;
+ try {
+ registrationLockData = pinHelper.getRegistrationLockData(pin, e);
+ } catch (KeyBackupSystemNoDataException ex) {
+ throw new IOException(e);
+ } catch (KeyBackupServicePinException ex) {
+ throw new IncorrectPinException(ex.getTriesRemaining());
+ }
if (registrationLockData == null) {
throw e;
}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+public class CaptchaRequiredException extends Exception {
+
+ public CaptchaRequiredException(final String message) {
+ super(message);
+ }
+
+ public CaptchaRequiredException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+public class IncorrectPinException extends Exception {
+
+ private final int triesRemaining;
+
+ public IncorrectPinException(int triesRemaining) {
+ this.triesRemaining = triesRemaining;
+ }
+
+ public int getTriesRemaining() {
+ return triesRemaining;
+ }
+}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+public class InvalidNumberException extends Exception {
+
+ InvalidNumberException(String message, Throwable e) {
+ super(message, e);
+ }
+}
Optional<Call> call
) {
- public static final record Receipt(long when, Type type, List<Long> timestamps) {
+ public record Receipt(long when, Type type, List<Long> timestamps) {
static Receipt from(final SignalServiceReceiptMessage receiptMessage) {
return new Receipt(receiptMessage.getWhen(),
}
}
- public static final record Typing(long timestamp, Type type, Optional<GroupId> groupId) {
+ public record Typing(long timestamp, Type type, Optional<GroupId> groupId) {
public static Typing from(final SignalServiceTypingMessage typingMessage) {
return new Typing(typingMessage.getTimestamp(),
}
}
- public static final record Data(
+ public record Data(
long timestamp,
Optional<GroupContext> groupContext,
Optional<GroupCallUpdate> groupCallUpdate,
return new Quote(quote.getId(),
addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(quote.getAuthor())),
Optional.ofNullable(quote.getText()),
- quote.getMentions()
- .stream()
- .map(m -> Mention.from(m, recipientResolver, addressResolver))
- .collect(Collectors.toList()),
- quote.getAttachments().stream().map(Attachment::from).collect(Collectors.toList()));
+ quote.getMentions() == null
+ ? List.of()
+ : quote.getMentions()
+ .stream()
+ .map(m -> Mention.from(m, recipientResolver, addressResolver))
+ .collect(Collectors.toList()),
+ quote.getAttachments() == null
+ ? List.of()
+ : quote.getAttachments().stream().map(Attachment::from).collect(Collectors.toList()));
}
}
}
}
- public static final record Sync(
+ public record Sync(
Optional<Sent> sent,
Optional<Blocked> blocked,
List<Read> read,
}
}
- public static final record Call(
+ public record Call(
Optional<Integer> destinationDeviceId,
Optional<GroupId> groupId,
Optional<Long> timestamp,
--- /dev/null
+package org.asamk.signal.manager.api;
+
+public class PinLockedException extends Exception {
+
+ private final long timeRemaining;
+
+ public PinLockedException(long timeRemaining) {
+ this.timeRemaining = timeRemaining;
+ }
+
+ public long getTimeRemaining() {
+ return timeRemaining;
+ }
+}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Thrown when rate-limited by the server and proof of humanity is required to continue messaging.
+ */
+public class ProofRequiredException extends Exception {
+
+ private final String token;
+ private final Set<Option> options;
+ private final long retryAfterSeconds;
+
+ public ProofRequiredException(org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException e) {
+ this.token = e.getToken();
+ this.options = e.getOptions().stream().map(Option::from).collect(Collectors.toSet());
+ this.retryAfterSeconds = e.getRetryAfterSeconds();
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public Set<Option> getOptions() {
+ return options;
+ }
+
+ public long getRetryAfterSeconds() {
+ return retryAfterSeconds;
+ }
+
+ public enum Option {
+ RECAPTCHA,
+ PUSH_CHALLENGE;
+
+ static Option from(org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException.Option option) {
+ return switch (option) {
+ case RECAPTCHA -> RECAPTCHA;
+ case PUSH_CHALLENGE -> PUSH_CHALLENGE;
+ };
+ }
+ }
+}
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
-import org.whispersystems.signalservice.api.push.SignalServiceAddress;
-import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import org.whispersystems.signalservice.api.util.UuidUtil;
sealed interface Single extends RecipientIdentifier {
static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
- return UuidUtil.isUuid(identifier)
- ? new Uuid(UUID.fromString(identifier))
- : new Number(PhoneNumberFormatter.formatNumber(identifier, localNumber));
- }
-
- static Single fromAddress(SignalServiceAddress address) {
- return new Uuid(address.getUuid());
+ try {
+ return UuidUtil.isUuid(identifier)
+ ? new Uuid(UUID.fromString(identifier))
+ : new Number(PhoneNumberFormatter.formatNumber(identifier, localNumber));
+ } catch (org.whispersystems.signalservice.api.util.InvalidNumberException e) {
+ throw new InvalidNumberException(e.getMessage(), e);
+ }
}
static Single fromAddress(RecipientAddress address) {
package org.asamk.signal.manager.api;
-import org.whispersystems.signalservice.api.messages.SendMessageResult;
-
import java.util.List;
public record SendGroupMessageResults(long timestamp, List<SendMessageResult> results) {}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+import org.asamk.signal.manager.helper.RecipientAddressResolver;
+import org.asamk.signal.manager.storage.recipients.RecipientAddress;
+import org.asamk.signal.manager.storage.recipients.RecipientResolver;
+import org.whispersystems.libsignal.IdentityKey;
+
+public record SendMessageResult(
+ RecipientAddress address,
+ boolean isSuccess,
+ boolean isNetworkFailure,
+ boolean isUnregisteredFailure,
+ boolean isIdentityFailure,
+ ProofRequiredException proofRequiredFailure
+) {
+
+ public static SendMessageResult success(RecipientAddress address) {
+ return new SendMessageResult(address, true, false, false, false, null);
+ }
+
+ public static SendMessageResult networkFailure(RecipientAddress address) {
+ return new SendMessageResult(address, false, true, false, false, null);
+ }
+
+ public static SendMessageResult unregisteredFailure(RecipientAddress address) {
+ return new SendMessageResult(address, false, false, true, false, null);
+ }
+
+ public static SendMessageResult identityFailure(RecipientAddress address, IdentityKey identityKey) {
+ return new SendMessageResult(address, false, false, false, true, null);
+ }
+
+ public static SendMessageResult proofRequiredFailure(
+ RecipientAddress address, ProofRequiredException proofRequiredException
+ ) {
+ return new SendMessageResult(address, false, true, false, false, proofRequiredException);
+ }
+
+ public static SendMessageResult from(
+ final org.whispersystems.signalservice.api.messages.SendMessageResult sendMessageResult,
+ RecipientResolver recipientResolver,
+ RecipientAddressResolver addressResolver
+ ) {
+ return new SendMessageResult(addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(
+ sendMessageResult.getAddress())),
+ sendMessageResult.isSuccess(),
+ sendMessageResult.isNetworkFailure(),
+ sendMessageResult.isUnregisteredFailure(),
+ sendMessageResult.getIdentityFailure() != null,
+ sendMessageResult.getProofRequiredFailure() == null
+ ? null
+ : new ProofRequiredException(sendMessageResult.getProofRequiredFailure()));
+ }
+
+ public record IdentityFailure(IdentityKey identityKey) {}
+}
package org.asamk.signal.manager.api;
-import org.whispersystems.signalservice.api.messages.SendMessageResult;
-
import java.util.List;
import java.util.Map;
}
}
+ public static boolean isZkgroupAvailable() {
+ return ServiceConfig.getCapabilities().isGv2();
+ }
+
public static boolean isSignalClientAvailable() {
try {
org.signal.client.internal.Native.DeviceTransfer_GeneratePrivateKey();
import org.asamk.signal.manager.api.InactiveGroupLinkException;
import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.SendGroupMessageResults;
+import org.asamk.signal.manager.api.SendMessageResult;
import org.asamk.signal.manager.config.ServiceConfig;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupIdV1;
final var timestamp = System.currentTimeMillis();
messageBuilder.withTimestamp(timestamp);
final var results = sendHelper.sendGroupMessage(messageBuilder.build(), members);
- return new SendGroupMessageResults(timestamp, results);
+ return new SendGroupMessageResults(timestamp,
+ results.stream()
+ .map(sendMessageResult -> SendMessageResult.from(sendMessageResult,
+ recipientResolver,
+ account.getRecipientStore()::resolveRecipientAddress))
+ .collect(Collectors.toList()));
}
}
package org.asamk.signal.manager.storage.recipients;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
-import org.whispersystems.signalservice.api.util.UuidUtil;
import java.util.Optional;
import java.util.UUID;
public class RecipientAddress {
+ public static final UUID UNKNOWN_UUID = new UUID(0, 0);
+
private final Optional<UUID> uuid;
private final Optional<String> e164;
* @param e164 The phone number of the user, if available.
*/
public RecipientAddress(Optional<UUID> uuid, Optional<String> e164) {
- uuid = uuid.isPresent() && uuid.get().equals(UuidUtil.UNKNOWN_UUID) ? Optional.empty() : uuid;
+ uuid = uuid.isPresent() && uuid.get().equals(UNKNOWN_UUID) ? Optional.empty() : uuid;
if (uuid.isEmpty() && e164.isEmpty()) {
throw new AssertionError("Must have either a UUID or E164 number!");
}
}
public SignalServiceAddress toSignalServiceAddress() {
- return new SignalServiceAddress(uuid.orElse(UuidUtil.UNKNOWN_UUID),
+ return new SignalServiceAddress(uuid.orElse(UNKNOWN_UUID),
org.whispersystems.libsignal.util.guava.Optional.fromNullable(e164.orElse(null)));
}
import org.freedesktop.dbus.exceptions.DBusExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import java.io.File;
import java.io.IOException;
dataPath = getDefaultDataPath();
}
- if (!ServiceConfig.getCapabilities().isGv2()) {
+ if (!ServiceConfig.isZkgroupAvailable()) {
logger.warn("WARNING: Support for new group V2 is disabled,"
+ " because the required native library dependency is missing: libzkgroup");
}
}
username = usernames.get(0);
- } else if (!PhoneNumberFormatter.isValidNumber(username, null)) {
+ } else if (!Manager.isValidNumber(username, null)) {
throw new UserErrorException("Invalid username (phone number), make sure you include the country code.");
}
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
import org.asamk.signal.commands.exceptions.UserErrorException;
-import org.asamk.signal.manager.LibSignalLogger;
+import org.asamk.signal.manager.Manager;
import org.asamk.signal.util.SecurityProvider;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
System.setProperty("org.slf4j.simpleLogger.showShortLogName", "false");
System.setProperty("org.slf4j.simpleLogger.showDateTime", "true");
System.setProperty("org.slf4j.simpleLogger.dateTimeFormat", "yyyy-MM-dd'T'HH:mm:ss.SSSXX");
- LibSignalLogger.initLogger();
+ Manager.initLogger();
} else {
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
) {
writer.println("Id: {}", quote.id());
writer.println("Author: {}", formatContact(quote.author()));
- writer.println("Text: {}", quote.text());
+ if (quote.text().isPresent()) {
+ writer.println("Text: {}", quote.text().get());
+ }
if (quote.mentions() != null && quote.mentions().size() > 0) {
writer.println("Mentions:");
for (var mention : quote.mentions()) {
if (quote.attachments().size() > 0) {
writer.println("Attachments:");
for (var attachment : quote.attachments()) {
- writer.println("- Filename: {}", attachment.fileName());
- writer.indent(w -> {
- w.println("Type: {}", attachment.contentType());
- w.println("Thumbnail:");
- if (attachment.thumbnail().isPresent()) {
- printAttachment(w, attachment.thumbnail().get());
- }
- });
+ writer.println("- Attachment:");
+ printAttachment(writer.indentedWriter(), attachment);
}
}
}
+ attachment.preview().get().length
+ " bytes)" : "");
}
+ if (attachment.thumbnail().isPresent()) {
+ writer.println("Thumbnail:");
+ printAttachment(writer.indentedWriter(), attachment.thumbnail().get());
+ }
final var flags = new ArrayList<String>();
if (attachment.isVoiceNote()) {
flags.add("voice note");
import org.asamk.signal.manager.api.InactiveGroupLinkException;
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
import org.freedesktop.dbus.exceptions.DBusExecutionException;
-import org.whispersystems.signalservice.internal.push.exceptions.GroupPatchNotAcceptedException;
import java.io.IOException;
import java.util.Map;
}
}
handleSendMessageResults(results.second().results());
- } catch (GroupPatchNotAcceptedException e) {
- throw new UserErrorException("Failed to join group, maybe already a member");
} catch (IOException e) {
throw new IOErrorException("Failed to send message: "
+ e.getMessage()
} else {
final var writer = (JsonWriter) outputWriter;
final var jsonIdentities = identities.stream().map(id -> {
- final var address = id.recipient().toSignalServiceAddress();
+ final var address = id.recipient();
var safetyNumber = Util.formatSafetyNumber(id.safetyNumber());
var scannableSafetyNumber = id.scannableSafetyNumber();
- return new JsonIdentity(address.getNumber().orNull(),
+ return new JsonIdentity(address.getNumber().orElse(null),
address.getUuid().toString(),
Hex.toString(id.getFingerprint()),
safetyNumber,
import org.asamk.signal.commands.exceptions.IOErrorException;
import org.asamk.signal.commands.exceptions.UserErrorException;
import org.asamk.signal.manager.RegistrationManager;
-import org.whispersystems.signalservice.api.push.exceptions.CaptchaRequiredException;
+import org.asamk.signal.manager.api.CaptchaRequiredException;
import java.io.IOException;
import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.IOErrorException;
-import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
import org.asamk.signal.commands.exceptions.UserErrorException;
import org.asamk.signal.manager.RegistrationManager;
-import org.whispersystems.signalservice.api.KeyBackupServicePinException;
-import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
-import org.whispersystems.signalservice.internal.push.LockedException;
+import org.asamk.signal.manager.api.IncorrectPinException;
+import org.asamk.signal.manager.api.PinLockedException;
import java.io.IOException;
try {
final var manager = m.verifyAccount(verificationCode, pin);
manager.close();
- } catch (LockedException e) {
+ } catch (PinLockedException e) {
throw new UserErrorException(
"Verification failed! This number is locked with a pin. Hours remaining until reset: "
+ (e.getTimeRemaining() / 1000 / 60 / 60)
+ "\nUse '--pin PIN_CODE' to specify the registration lock PIN");
- } catch (KeyBackupServicePinException e) {
+ } catch (IncorrectPinException e) {
throw new UserErrorException("Verification failed! Invalid pin, tries remaining: " + e.getTriesRemaining());
- } catch (KeyBackupSystemNoDataException e) {
- throw new UnexpectedErrorException("Verification failed! No KBS data.", e);
} catch (IOException e) {
throw new IOErrorException("Verify error: " + e.getMessage(), e);
}
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.interfaces.DBusInterface;
-import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
-import org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.File;
import java.io.IOException;
final var result = new HashMap<String, Pair<String, UUID>>();
for (var i = 0; i < numbersList.size(); i++) {
result.put(numbersList.get(i),
- new Pair<>(numbersList.get(i), registered.get(i) ? UuidUtil.UNKNOWN_UUID : null));
+ new Pair<>(numbersList.get(i), registered.get(i) ? RecipientAddress.UNKNOWN_UUID : null));
}
return result;
}
}
@Override
- public Profile getRecipientProfile(final RecipientIdentifier.Single recipient) throws UnregisteredUserException {
+ public Profile getRecipientProfile(final RecipientIdentifier.Single recipient) {
throw new UnsupportedOperationException();
}
@Override
public void setContactName(
final RecipientIdentifier.Single recipient, final String name
- ) throws NotMasterDeviceException, UnregisteredUserException {
+ ) throws NotMasterDeviceException {
signal.setContactName(recipient.getIdentifier(), name);
}
import org.asamk.signal.manager.ProvisioningManager;
import org.asamk.signal.manager.RegistrationManager;
import org.asamk.signal.manager.UserAlreadyExists;
+import org.asamk.signal.manager.api.CaptchaRequiredException;
+import org.asamk.signal.manager.api.IncorrectPinException;
import org.asamk.signal.manager.api.Pair;
+import org.asamk.signal.manager.api.PinLockedException;
import org.freedesktop.dbus.DBusPath;
-import org.whispersystems.signalservice.api.KeyBackupServicePinException;
-import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
-import org.whispersystems.signalservice.api.push.exceptions.CaptchaRequiredException;
-import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import java.io.IOException;
import java.net.URI;
public void registerWithCaptcha(
final String number, final boolean voiceVerification, final String captcha
) throws Error.Failure, Error.InvalidNumber {
- if (!PhoneNumberFormatter.isValidNumber(number, null)) {
+ if (!Manager.isValidNumber(number, null)) {
throw new SignalControl.Error.InvalidNumber(
"Invalid username (phone number), make sure you include the country code.");
}
try (final RegistrationManager registrationManager = c.getNewRegistrationManager(number)) {
final Manager manager = registrationManager.verifyAccount(verificationCode, pin);
addManager(manager);
- } catch (IOException | KeyBackupSystemNoDataException | KeyBackupServicePinException e) {
+ } catch (IOException | PinLockedException | IncorrectPinException e) {
throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage());
}
}
import org.asamk.signal.manager.api.Identity;
import org.asamk.signal.manager.api.InactiveGroupLinkException;
import org.asamk.signal.manager.api.InvalidDeviceLinkException;
+import org.asamk.signal.manager.api.InvalidNumberException;
import org.asamk.signal.manager.api.Message;
import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.RecipientIdentifier;
+import org.asamk.signal.manager.api.SendMessageResult;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UpdateGroup;
import org.asamk.signal.manager.groups.GroupId;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.exceptions.DBusExecutionException;
import org.freedesktop.dbus.types.Variant;
-import org.whispersystems.signalservice.api.messages.SendMessageResult;
-import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.io.File;
import java.io.IOException;
final var message = timestamp + "\nFailed to send message:\n" + error + '\n';
- if (result.getIdentityFailure() != null) {
+ if (result.isIdentityFailure()) {
throw new Error.UntrustedIdentity(message);
} else {
throw new Error.Failure(message);
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.UntrustedIdentityException;
+import org.asamk.signal.manager.api.InvalidNumberException;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.manager.api.RecipientIdentifier;
-import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.util.List;
import java.util.UUID;
import org.asamk.signal.commands.exceptions.UserErrorException;
import org.asamk.signal.manager.Manager;
+import org.asamk.signal.manager.api.InvalidNumberException;
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupIdFormatException;
-import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.util.Collection;
import java.util.HashSet;
import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.IOErrorException;
+import org.asamk.signal.manager.api.ProofRequiredException;
import org.asamk.signal.manager.api.RecipientIdentifier;
+import org.asamk.signal.manager.api.SendMessageResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.whispersystems.signalservice.api.messages.SendMessageResult;
-import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
-import static org.asamk.signal.util.Util.getLegacyIdentifier;
-
public class ErrorUtils {
private final static Logger logger = LoggerFactory.getLogger(ErrorUtils.class);
}
public static String getErrorMessageFromSendMessageResult(SendMessageResult result) {
- var identifier = getLegacyIdentifier(result.getAddress());
- if (result.getProofRequiredFailure() != null) {
- final var failure = result.getProofRequiredFailure();
+ var identifier = result.address().getLegacyIdentifier();
+ if (result.proofRequiredFailure() != null) {
+ final var failure = result.proofRequiredFailure();
return String.format(
"CAPTCHA proof required for sending to \"%s\", available options \"%s\" with challenge token \"%s\", or wait \"%d\" seconds.\n"
+ (
return String.format("Network failure for \"%s\"", identifier);
} else if (result.isUnregisteredFailure()) {
return String.format("Unregistered user \"%s\"", identifier);
- } else if (result.getIdentityFailure() != null) {
+ } else if (result.isIdentityFailure()) {
return String.format("Untrusted Identity for \"%s\"", identifier);
}
return null;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.whispersystems.signalservice.api.push.SignalServiceAddress;
-
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
return f.toString();
}
- public static String getLegacyIdentifier(final SignalServiceAddress address) {
- return address.getNumber().or(() -> address.getUuid().toString());
- }
-
public static ObjectMapper createJsonObjectMapper() {
var objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.PUBLIC_ONLY);