From: AsamK Date: Sat, 6 Nov 2021 12:29:26 +0000 (+0100) Subject: Remove libsignal-service from manager lib API X-Git-Tag: v0.10.0~89 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/2ab42ca5471e8fc1e1a31cde954e19564178f114 Remove libsignal-service from manager lib API --- diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index c12ad0a4..91726ae1 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -14,7 +14,7 @@ repositories { } 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") diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index 77be3074..b4579274 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -67,6 +67,14 @@ public interface Manager extends Closeable { 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 getAllLocalNumbers(File settingsPath) { var pathConfig = PathConfig.createDefault(settingsPath); final var dataPath = pathConfig.dataPath(); diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index 9994ad65..59cfbbaa 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -26,6 +26,7 @@ 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.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; @@ -69,7 +70,6 @@ import org.whispersystems.libsignal.InvalidKeyException; 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; @@ -581,13 +581,24 @@ public class ManagerImpl implements Manager { 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); @@ -1292,7 +1303,8 @@ public class ManagerImpl implements Manager { } 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); } diff --git a/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java b/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java index 8a96dad0..97361ec5 100644 --- a/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java +++ b/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java @@ -16,6 +16,9 @@ */ 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; @@ -27,6 +30,7 @@ import org.slf4j.Logger; 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; @@ -116,7 +120,7 @@ public class RegistrationManager implements Closeable { 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 response; if (voiceVerification) { response = accountManager.requestVoiceVerificationCode(getDefaultLocale(), @@ -129,7 +133,11 @@ public class RegistrationManager implements Closeable { 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() { @@ -146,7 +154,7 @@ public class RegistrationManager implements Closeable { public Manager verifyAccount( String verificationCode, String pin - ) throws IOException, LockedException, KeyBackupSystemNoDataException, KeyBackupServicePinException { + ) throws IOException, PinLockedException, IncorrectPinException { verificationCode = verificationCode.replace("-", ""); VerifyAccountResponse response; MasterKey masterKey; @@ -157,10 +165,17 @@ public class RegistrationManager implements Closeable { 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; } diff --git a/lib/src/main/java/org/asamk/signal/manager/api/CaptchaRequiredException.java b/lib/src/main/java/org/asamk/signal/manager/api/CaptchaRequiredException.java new file mode 100644 index 00000000..9504d240 --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/CaptchaRequiredException.java @@ -0,0 +1,12 @@ +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); + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/api/IncorrectPinException.java b/lib/src/main/java/org/asamk/signal/manager/api/IncorrectPinException.java new file mode 100644 index 00000000..6de58f5f --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/IncorrectPinException.java @@ -0,0 +1,14 @@ +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; + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/api/InvalidNumberException.java b/lib/src/main/java/org/asamk/signal/manager/api/InvalidNumberException.java new file mode 100644 index 00000000..ba71ef2e --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/InvalidNumberException.java @@ -0,0 +1,8 @@ +package org.asamk.signal.manager.api; + +public class InvalidNumberException extends Exception { + + InvalidNumberException(String message, Throwable e) { + super(message, e); + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java b/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java index 98b754e2..dd40c81b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java @@ -48,7 +48,7 @@ public record MessageEnvelope( Optional call ) { - public static final record Receipt(long when, Type type, List timestamps) { + public record Receipt(long when, Type type, List timestamps) { static Receipt from(final SignalServiceReceiptMessage receiptMessage) { return new Receipt(receiptMessage.getWhen(), @@ -73,7 +73,7 @@ public record MessageEnvelope( } } - public static final record Typing(long timestamp, Type type, Optional groupId) { + public record Typing(long timestamp, Type type, Optional groupId) { public static Typing from(final SignalServiceTypingMessage typingMessage) { return new Typing(typingMessage.getTimestamp(), @@ -87,7 +87,7 @@ public record MessageEnvelope( } } - public static final record Data( + public record Data( long timestamp, Optional groupContext, Optional groupCallUpdate, @@ -204,11 +204,15 @@ public record MessageEnvelope( 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())); } } @@ -455,7 +459,7 @@ public record MessageEnvelope( } } - public static final record Sync( + public record Sync( Optional sent, Optional blocked, List read, @@ -631,7 +635,7 @@ public record MessageEnvelope( } } - public static final record Call( + public record Call( Optional destinationDeviceId, Optional groupId, Optional timestamp, diff --git a/lib/src/main/java/org/asamk/signal/manager/api/PinLockedException.java b/lib/src/main/java/org/asamk/signal/manager/api/PinLockedException.java new file mode 100644 index 00000000..161a1b69 --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/PinLockedException.java @@ -0,0 +1,14 @@ +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; + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/api/ProofRequiredException.java b/lib/src/main/java/org/asamk/signal/manager/api/ProofRequiredException.java new file mode 100644 index 00000000..949dc4eb --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/ProofRequiredException.java @@ -0,0 +1,44 @@ +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