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 f4d330a4cf..76b6a85c2a 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -43,6 +43,7 @@ import org.asamk.signal.manager.api.UpdateProfile; import org.asamk.signal.manager.api.UserStatus; import org.asamk.signal.manager.api.UsernameLinkUrl; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; @@ -125,7 +126,7 @@ void updateAccountAttributes( void startChangeNumber( String newNumber, boolean voiceVerification, String captcha - ) throws RateLimitException, IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, NotPrimaryDeviceException; + ) throws RateLimitException, IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, NotPrimaryDeviceException, VerificationMethoNotAvailableException; void finishChangeNumber( String newNumber, String verificationCode, String pin 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 8ba2bf70db..365dd39961 100644 --- a/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java +++ b/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java @@ -5,6 +5,7 @@ import org.asamk.signal.manager.api.NonNormalizedPhoneNumberException; import org.asamk.signal.manager.api.PinLockedException; import org.asamk.signal.manager.api.RateLimitException; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import java.io.Closeable; import java.io.IOException; @@ -13,7 +14,7 @@ public interface RegistrationManager extends Closeable { void register( boolean voiceVerification, String captcha - ) throws IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, RateLimitException; + ) throws IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, RateLimitException, VerificationMethoNotAvailableException; void verifyAccount( String verificationCode, String pin diff --git a/lib/src/main/java/org/asamk/signal/manager/api/VerificationMethoNotAvailableException.java b/lib/src/main/java/org/asamk/signal/manager/api/VerificationMethoNotAvailableException.java new file mode 100644 index 0000000000..172e44e495 --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/VerificationMethoNotAvailableException.java @@ -0,0 +1,8 @@ +package org.asamk.signal.manager.api; + +public class VerificationMethoNotAvailableException extends Exception { + + public VerificationMethoNotAvailableException() { + super("Invalid verification method"); + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java index 1f44e2a36f..06b1fe80fb 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java @@ -7,6 +7,7 @@ import org.asamk.signal.manager.api.NonNormalizedPhoneNumberException; import org.asamk.signal.manager.api.PinLockedException; import org.asamk.signal.manager.api.RateLimitException; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.asamk.signal.manager.internal.SignalDependencies; import org.asamk.signal.manager.jobs.SyncStorageJob; import org.asamk.signal.manager.storage.SignalAccount; @@ -164,7 +165,7 @@ public void setPni( public void startChangeNumber( String newNumber, boolean voiceVerification, String captcha - ) throws IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, RateLimitException { + ) throws IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, RateLimitException, VerificationMethoNotAvailableException { final var accountManager = dependencies.createUnauthenticatedAccountManager(newNumber, account.getPassword()); String sessionId = NumberVerificationUtils.handleVerificationSession(accountManager, account.getSessionId(newNumber), diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java index a25c92c03a..2caffc3842 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java @@ -64,6 +64,7 @@ import org.asamk.signal.manager.api.UpdateProfile; import org.asamk.signal.manager.api.UserStatus; import org.asamk.signal.manager.api.UsernameLinkUrl; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.helper.AccountFileUpdater; import org.asamk.signal.manager.helper.Context; @@ -374,7 +375,7 @@ public void deleteUsername() throws IOException { @Override public void startChangeNumber( String newNumber, boolean voiceVerification, String captcha - ) throws RateLimitException, IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, NotPrimaryDeviceException { + ) throws RateLimitException, IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, NotPrimaryDeviceException, VerificationMethoNotAvailableException { if (!account.isPrimaryDevice()) { throw new NotPrimaryDeviceException(); } diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java index 4518fb01c8..2df7ff4bad 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java @@ -24,6 +24,7 @@ import org.asamk.signal.manager.api.PinLockedException; import org.asamk.signal.manager.api.RateLimitException; import org.asamk.signal.manager.api.UpdateProfile; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.asamk.signal.manager.config.ServiceConfig; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.helper.AccountFileUpdater; @@ -104,7 +105,7 @@ public RegistrationManagerImpl( @Override public void register( boolean voiceVerification, String captcha - ) throws IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, RateLimitException { + ) throws IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, RateLimitException, VerificationMethoNotAvailableException { if (account.isRegistered() && account.getServiceEnvironment() != null && account.getServiceEnvironment() != serviceEnvironmentConfig.type()) { diff --git a/lib/src/main/java/org/asamk/signal/manager/util/NumberVerificationUtils.java b/lib/src/main/java/org/asamk/signal/manager/util/NumberVerificationUtils.java index a5c91f5b3b..9eb01cdbdb 100644 --- a/lib/src/main/java/org/asamk/signal/manager/util/NumberVerificationUtils.java +++ b/lib/src/main/java/org/asamk/signal/manager/util/NumberVerificationUtils.java @@ -6,6 +6,7 @@ import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.PinLockedException; import org.asamk.signal.manager.api.RateLimitException; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.asamk.signal.manager.helper.PinHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +35,7 @@ public static String handleVerificationSession( Consumer sessionIdSaver, boolean voiceVerification, String captcha - ) throws CaptchaRequiredException, IOException, RateLimitException { + ) throws CaptchaRequiredException, IOException, RateLimitException, VerificationMethoNotAvailableException { RegistrationSessionMetadataResponse sessionResponse; try { sessionResponse = getValidSession(accountManager, sessionId); @@ -61,7 +62,9 @@ public static String handleVerificationSession( final var nextAttempt = voiceVerification ? sessionResponse.getBody().getNextCall() : sessionResponse.getBody().getNextSms(); - if (nextAttempt != null && nextAttempt > 0) { + if (nextAttempt == null) { + throw new VerificationMethoNotAvailableException(); + } else if (nextAttempt > 0) { final var timestamp = sessionResponse.getHeaders().getTimestamp() + nextAttempt * 1000; throw new RateLimitException(timestamp); } diff --git a/src/main/java/org/asamk/signal/commands/RegisterCommand.java b/src/main/java/org/asamk/signal/commands/RegisterCommand.java index 876d1a8a99..4776ac6e2e 100644 --- a/src/main/java/org/asamk/signal/commands/RegisterCommand.java +++ b/src/main/java/org/asamk/signal/commands/RegisterCommand.java @@ -15,6 +15,7 @@ import org.asamk.signal.manager.api.CaptchaRequiredException; import org.asamk.signal.manager.api.NonNormalizedPhoneNumberException; import org.asamk.signal.manager.api.RateLimitException; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.asamk.signal.output.JsonWriter; import org.asamk.signal.util.CommandUtil; @@ -79,6 +80,12 @@ private void register( } catch (IOException e) { throw new IOErrorException("Failed to register: %s (%s)".formatted(e.getMessage(), e.getClass().getSimpleName()), e); + } catch (VerificationMethoNotAvailableException e) { + throw new UserErrorException("Failed to register: " + e.getMessage() + ( + voiceVerification + ? ": Before requesting voice verification you need to request SMS verification and wait a minute." + : "" + ), e); } } diff --git a/src/main/java/org/asamk/signal/commands/StartChangeNumberCommand.java b/src/main/java/org/asamk/signal/commands/StartChangeNumberCommand.java index 7b18dbf095..823a0c9289 100644 --- a/src/main/java/org/asamk/signal/commands/StartChangeNumberCommand.java +++ b/src/main/java/org/asamk/signal/commands/StartChangeNumberCommand.java @@ -13,6 +13,7 @@ import org.asamk.signal.manager.api.NonNormalizedPhoneNumberException; import org.asamk.signal.manager.api.NotPrimaryDeviceException; import org.asamk.signal.manager.api.RateLimitException; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.asamk.signal.output.OutputWriter; import org.asamk.signal.util.CommandUtil; @@ -59,6 +60,12 @@ public void handleCommand( } catch (IOException e) { throw new IOErrorException("Failed to change number: %s (%s)".formatted(e.getMessage(), e.getClass().getSimpleName()), e); + } catch (VerificationMethoNotAvailableException e) { + throw new UserErrorException("Failed to register: " + e.getMessage() + ( + voiceVerification + ? ": Before requesting voice verification you need to request SMS verification and wait a minute." + : "" + ), e); } } } diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalControlImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalControlImpl.java index f21dd40d7e..d8465d2678 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalControlImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalControlImpl.java @@ -13,6 +13,7 @@ import org.asamk.signal.manager.api.PinLockedException; import org.asamk.signal.manager.api.RateLimitException; import org.asamk.signal.manager.api.UserAlreadyExistsException; +import org.asamk.signal.manager.api.VerificationMethoNotAvailableException; import org.freedesktop.dbus.DBusPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,7 +74,7 @@ public void registerWithCaptcha( throw new Error.InvalidNumber(e.getMessage()); } catch (OverlappingFileLockException e) { throw new SignalControl.Error.Failure("Account is already in use"); - } catch (IOException e) { + } catch (IOException | VerificationMethoNotAvailableException e) { throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage()); } }