1 package org
.asamk
.signal
.manager
.util
;
3 import org
.asamk
.signal
.manager
.api
.CaptchaRequiredException
;
4 import org
.asamk
.signal
.manager
.api
.IncorrectPinException
;
5 import org
.asamk
.signal
.manager
.api
.NonNormalizedPhoneNumberException
;
6 import org
.asamk
.signal
.manager
.api
.Pair
;
7 import org
.asamk
.signal
.manager
.api
.PinLockedException
;
8 import org
.asamk
.signal
.manager
.helper
.PinHelper
;
9 import org
.whispersystems
.signalservice
.api
.KbsPinData
;
10 import org
.whispersystems
.signalservice
.api
.SignalServiceAccountManager
;
11 import org
.whispersystems
.signalservice
.api
.kbs
.MasterKey
;
12 import org
.whispersystems
.signalservice
.internal
.ServiceResponse
;
13 import org
.whispersystems
.signalservice
.internal
.push
.LockedException
;
14 import org
.whispersystems
.signalservice
.internal
.push
.RequestVerificationCodeResponse
;
15 import org
.whispersystems
.signalservice
.internal
.push
.VerifyAccountResponse
;
17 import java
.io
.IOException
;
18 import java
.util
.Locale
;
19 import java
.util
.Optional
;
21 public class NumberVerificationUtils
{
23 public static void requestVerificationCode(
24 SignalServiceAccountManager accountManager
, String captcha
, boolean voiceVerification
25 ) throws IOException
, CaptchaRequiredException
, NonNormalizedPhoneNumberException
{
26 captcha
= captcha
== null ?
null : captcha
.replace("signalcaptcha://", "");
27 final ServiceResponse
<RequestVerificationCodeResponse
> response
;
28 if (voiceVerification
) {
29 response
= accountManager
.requestVoiceVerificationCode(Utils
.getDefaultLocale(Locale
.US
),
30 Optional
.ofNullable(captcha
),
34 response
= accountManager
.requestSmsVerificationCode(false,
35 Optional
.ofNullable(captcha
),
40 handleResponseException(response
);
41 } catch (org
.whispersystems
.signalservice
.api
.push
.exceptions
.CaptchaRequiredException e
) {
42 throw new CaptchaRequiredException(e
.getMessage(), e
);
43 } catch (org
.whispersystems
.signalservice
.api
.push
.exceptions
.NonNormalizedPhoneNumberException e
) {
44 throw new NonNormalizedPhoneNumberException("Phone number is not normalized ("
46 + "). Expected normalized: "
47 + e
.getNormalizedNumber(), e
);
51 public static Pair
<VerifyAccountResponse
, MasterKey
> verifyNumber(
52 String verificationCode
, String pin
, PinHelper pinHelper
, Verifier verifier
53 ) throws IOException
, PinLockedException
, IncorrectPinException
{
54 verificationCode
= verificationCode
.replace("-", "");
56 final var response
= verifyAccountWithCode(verificationCode
, null, verifier
);
58 return new Pair
<>(response
, null);
59 } catch (LockedException e
) {
61 throw new PinLockedException(e
.getTimeRemaining());
64 KbsPinData registrationLockData
;
65 registrationLockData
= pinHelper
.getRegistrationLockData(pin
, e
);
66 if (registrationLockData
== null) {
70 var registrationLock
= registrationLockData
.getMasterKey().deriveRegistrationLock();
71 VerifyAccountResponse response
;
73 response
= verifyAccountWithCode(verificationCode
, registrationLock
, verifier
);
74 } catch (LockedException _e
) {
75 throw new AssertionError("KBS Pin appeared to matched but reg lock still failed!");
78 return new Pair
<>(response
, registrationLockData
.getMasterKey());
82 private static VerifyAccountResponse
verifyAccountWithCode(
83 final String verificationCode
, final String registrationLock
, final Verifier verifier
84 ) throws IOException
{
85 final var response
= verifier
.verify(verificationCode
, registrationLock
);
86 handleResponseException(response
);
87 return response
.getResult().get();
90 private static void handleResponseException(final ServiceResponse
<?
> response
) throws IOException
{
91 final var throwableOptional
= response
.getExecutionError().or(response
::getApplicationError
);
92 if (throwableOptional
.isPresent()) {
93 if (throwableOptional
.get() instanceof IOException
) {
94 throw (IOException
) throwableOptional
.get();
96 throw new IOException(throwableOptional
.get());
101 public interface Verifier
{
103 ServiceResponse
<VerifyAccountResponse
> verify(
104 String verificationCode
, String registrationLock