diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationNetworkController.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationNetworkController.kt index f6bcaaa6ff..0af3746999 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationNetworkController.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/v2/AppRegistrationNetworkController.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json import org.signal.core.models.MasterKey import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.libsignal.protocol.IdentityKey import org.signal.libsignal.protocol.IdentityKeyPair import org.signal.libsignal.protocol.ecc.ECPrivateKey @@ -33,7 +34,6 @@ import org.signal.registration.NetworkController.ProvisioningMessage import org.signal.registration.NetworkController.RegisterAccountError import org.signal.registration.NetworkController.RegisterAccountResponse import org.signal.registration.NetworkController.RegistrationLockResponse -import org.signal.registration.NetworkController.RegistrationNetworkResult import org.signal.registration.NetworkController.RequestVerificationCodeError import org.signal.registration.NetworkController.RestoreMasterKeyError import org.signal.registration.NetworkController.SessionMetadata @@ -89,58 +89,58 @@ class AppRegistrationNetworkController( fcmToken: String?, mcc: String?, mnc: String? - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.createVerificationSessionV2(e164, fcmToken, mcc, mnc).use { response -> when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 422 -> { - RegistrationNetworkResult.Failure(CreateSessionError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(CreateSessionError.InvalidRequest(response.body.string())) } 429 -> { - RegistrationNetworkResult.Failure(CreateSessionError.RateLimited(response.retryAfter())) + RequestResult.NonSuccess(CreateSessionError.RateLimited(response.retryAfter())) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } - override suspend fun getSession(sessionId: String): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun getSession(sessionId: String): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.getSessionStatusV2(sessionId).use { response -> when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(GetSessionStatusError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(GetSessionStatusError.InvalidRequest(response.body.string())) } 404 -> { - RegistrationNetworkResult.Failure(GetSessionStatusError.SessionNotFound(response.body.string())) + RequestResult.NonSuccess(GetSessionStatusError.SessionNotFound(response.body.string())) } 422 -> { - RegistrationNetworkResult.Failure(GetSessionStatusError.InvalidSessionId(response.body.string())) + RequestResult.NonSuccess(GetSessionStatusError.InvalidSessionId(response.body.string())) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -148,7 +148,7 @@ class AppRegistrationNetworkController( sessionId: String?, pushChallengeToken: String?, captchaToken: String? - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.patchVerificationSessionV2( sessionId, @@ -161,27 +161,27 @@ class AppRegistrationNetworkController( when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(UpdateSessionError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(UpdateSessionError.InvalidRequest(response.body.string())) } 409 -> { - RegistrationNetworkResult.Failure(UpdateSessionError.RejectedUpdate(response.body.string())) + RequestResult.NonSuccess(UpdateSessionError.RejectedUpdate(response.body.string())) } 429 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(UpdateSessionError.RateLimited(response.retryAfter(), session)) + RequestResult.NonSuccess(UpdateSessionError.RateLimited(response.retryAfter(), session)) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -190,7 +190,7 @@ class AppRegistrationNetworkController( locale: Locale?, androidSmsRetrieverSupported: Boolean, transport: VerificationCodeTransport - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val socketTransport = when (transport) { VerificationCodeTransport.SMS -> PushServiceSocket.VerificationCodeTransport.SMS @@ -206,76 +206,76 @@ class AppRegistrationNetworkController( when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(RequestVerificationCodeError.InvalidSessionId(response.body.string())) + RequestResult.NonSuccess(RequestVerificationCodeError.InvalidSessionId(response.body.string())) } 404 -> { - RegistrationNetworkResult.Failure(RequestVerificationCodeError.SessionNotFound(response.body.string())) + RequestResult.NonSuccess(RequestVerificationCodeError.SessionNotFound(response.body.string())) } 409 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.MissingRequestInformationOrAlreadyVerified(session)) + RequestResult.NonSuccess(RequestVerificationCodeError.MissingRequestInformationOrAlreadyVerified(session)) } 418 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(session)) + RequestResult.NonSuccess(RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(session)) } 429 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.RateLimited(response.retryAfter(), session)) + RequestResult.NonSuccess(RequestVerificationCodeError.RateLimited(response.retryAfter(), session)) } 440 -> { val errorBody = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.ThirdPartyServiceError(errorBody)) + RequestResult.NonSuccess(RequestVerificationCodeError.ThirdPartyServiceError(errorBody)) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun submitVerificationCode( sessionId: String, verificationCode: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.submitVerificationCodeV2(sessionId, verificationCode).use { response -> when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode(response.body.string())) + RequestResult.NonSuccess(SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode(response.body.string())) } 404 -> { - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.SessionNotFound(response.body.string())) + RequestResult.NonSuccess(SubmitVerificationCodeError.SessionNotFound(response.body.string())) } 409 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested(session)) + RequestResult.NonSuccess(SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested(session)) } 429 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.RateLimited(response.retryAfter(), session)) + RequestResult.NonSuccess(SubmitVerificationCodeError.RateLimited(response.retryAfter(), session)) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -289,7 +289,7 @@ class AppRegistrationNetworkController( pniPreKeys: PreKeyCollection, fcmToken: String?, skipDeviceTransfer: Boolean - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { check(sessionId != null || recoveryPassword != null) { "Either sessionId or recoveryPassword must be provided" } check(sessionId == null || recoveryPassword == null) { "Either sessionId or recoveryPassword must be provided, but not both" } @@ -308,36 +308,36 @@ class AppRegistrationNetworkController( when (response.code) { 200 -> { val result = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(result) + RequestResult.Success(result) } 401 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.SessionNotFoundOrNotVerified(response.body.string())) + RequestResult.NonSuccess(RegisterAccountError.SessionNotFoundOrNotVerified(response.body.string())) } 403 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.RegistrationRecoveryPasswordIncorrect(response.body.string())) + RequestResult.NonSuccess(RegisterAccountError.RegistrationRecoveryPasswordIncorrect(response.body.string())) } 409 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.DeviceTransferPossible) + RequestResult.NonSuccess(RegisterAccountError.DeviceTransferPossible) } 422 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(RegisterAccountError.InvalidRequest(response.body.string())) } 423 -> { val lockResponse = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RegisterAccountError.RegistrationLock(lockResponse)) + RequestResult.NonSuccess(RegisterAccountError.RegistrationLock(lockResponse)) } 429 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.RateLimited(response.retryAfter())) + RequestResult.NonSuccess(RegisterAccountError.RateLimited(response.retryAfter())) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -384,58 +384,58 @@ class AppRegistrationNetworkController( override suspend fun restoreMasterKeyFromSvr( svrCredentials: SvrCredentials, pin: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val authCredentials = AuthCredentials.create(svrCredentials.username, svrCredentials.password) val credentialSet = SvrAuthCredentialSet(svr2Credentials = authCredentials, svr3Credentials = null) val masterKey = SvrRepository.restoreMasterKeyPreRegistration(credentialSet, pin) - RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) } catch (e: SvrWrongPinException) { - RegistrationNetworkResult.Failure(RestoreMasterKeyError.WrongPin(e.triesRemaining)) + RequestResult.NonSuccess(RestoreMasterKeyError.WrongPin(e.triesRemaining)) } catch (e: SvrNoDataException) { - RegistrationNetworkResult.Failure(RestoreMasterKeyError.NoDataFound) + RequestResult.NonSuccess(RestoreMasterKeyError.NoDataFound) } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun setPinAndMasterKeyOnSvr( pin: String, masterKey: MasterKey - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val svr2 = AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV2(BuildConfig.SVR2_MRENCLAVE) val session = svr2.setPin(pin, masterKey) when (val response = session.execute()) { is BackupResponse.Success -> { - RegistrationNetworkResult.Success(SvrCredentials(response.authorization.username(), response.authorization.password())) + RequestResult.Success(SvrCredentials(response.authorization.username(), response.authorization.password())) } is BackupResponse.EnclaveNotFound -> { - RegistrationNetworkResult.Failure(BackupMasterKeyError.EnclaveNotFound) + RequestResult.NonSuccess(BackupMasterKeyError.EnclaveNotFound) } is BackupResponse.ExposeFailure -> { - RegistrationNetworkResult.Success(null) + RequestResult.Success(null) } is BackupResponse.NetworkError -> { - RegistrationNetworkResult.NetworkError(response.exception) + RequestResult.RetryableNetworkError(response.exception) } is BackupResponse.ApplicationError -> { - RegistrationNetworkResult.ApplicationError(response.exception) + RequestResult.ApplicationError(response.exception) } is BackupResponse.ServerRejected -> { - RegistrationNetworkResult.NetworkError(IOException("Server rejected backup request")) + RequestResult.RetryableNetworkError(IOException("Server rejected backup request")) } is BackupResponse.RateLimited -> { - RegistrationNetworkResult.NetworkError(IOException("Rate limited")) + RequestResult.RetryableNetworkError(IOException("Rate limited")) } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -443,96 +443,96 @@ class AppRegistrationNetworkController( AppDependencies.jobManager.add(ResetSvrGuessCountJob()) } - override suspend fun enableRegistrationLock(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun enableRegistrationLock(): RequestResult = withContext(Dispatchers.IO) { val masterKey = SignalStore.svr.masterKey if (masterKey == null) { - return@withContext RegistrationNetworkResult.Failure(SetRegistrationLockError.NoPinSet) + return@withContext RequestResult.NonSuccess(SetRegistrationLockError.NoPinSet) } when (val result = SignalNetwork.account.enableRegistrationLock(masterKey.deriveRegistrationLock())) { - is NetworkResult.Success -> RegistrationNetworkResult.Success(Unit) + is NetworkResult.Success -> RequestResult.Success(Unit) is NetworkResult.StatusCodeError -> { when (result.code) { - 401 -> RegistrationNetworkResult.Failure(SetRegistrationLockError.Unauthorized) - 422 -> RegistrationNetworkResult.Failure(SetRegistrationLockError.InvalidRequest(result.toString())) - else -> RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${result.code}")) + 401 -> RequestResult.NonSuccess(SetRegistrationLockError.Unauthorized) + 422 -> RequestResult.NonSuccess(SetRegistrationLockError.InvalidRequest(result.toString())) + else -> RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${result.code}")) } } - is NetworkResult.NetworkError -> RegistrationNetworkResult.NetworkError(result.exception) - is NetworkResult.ApplicationError -> RegistrationNetworkResult.ApplicationError(result.throwable) + is NetworkResult.NetworkError -> RequestResult.RetryableNetworkError(result.exception) + is NetworkResult.ApplicationError -> RequestResult.ApplicationError(result.throwable) } } - override suspend fun disableRegistrationLock(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun disableRegistrationLock(): RequestResult = withContext(Dispatchers.IO) { when (val result = SignalNetwork.account.disableRegistrationLock()) { - is NetworkResult.Success -> RegistrationNetworkResult.Success(Unit) + is NetworkResult.Success -> RequestResult.Success(Unit) is NetworkResult.StatusCodeError -> { when (result.code) { - 401 -> RegistrationNetworkResult.Failure(SetRegistrationLockError.Unauthorized) - else -> RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${result.code}")) + 401 -> RequestResult.NonSuccess(SetRegistrationLockError.Unauthorized) + else -> RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${result.code}")) } } - is NetworkResult.NetworkError -> RegistrationNetworkResult.NetworkError(result.exception) - is NetworkResult.ApplicationError -> RegistrationNetworkResult.ApplicationError(result.throwable) + is NetworkResult.NetworkError -> RequestResult.RetryableNetworkError(result.exception) + is NetworkResult.ApplicationError -> RequestResult.ApplicationError(result.throwable) } } - override suspend fun getSvrCredentials(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun getSvrCredentials(): RequestResult = withContext(Dispatchers.IO) { try { val svr2 = AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV2(BuildConfig.SVR2_MRENCLAVE) val auth = svr2.authorization() - RegistrationNetworkResult.Success(SvrCredentials(auth.username(), auth.password())) + RequestResult.Success(SvrCredentials(auth.username(), auth.password())) } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun checkSvrCredentials( e164: String, credentials: List - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val tokens = credentials.map { "${it.username}:${it.password}" } pushServiceSocket.checkSvr2AuthCredentialsV2(e164, tokens).use { response -> when (response.code) { 200 -> { val result = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(result) + RequestResult.Success(result) } 400, 422 -> { - RegistrationNetworkResult.Failure(CheckSvrCredentialsError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(CheckSvrCredentialsError.InvalidRequest(response.body.string())) } 401 -> { - RegistrationNetworkResult.Failure(CheckSvrCredentialsError.Unauthorized) + RequestResult.NonSuccess(CheckSvrCredentialsError.Unauthorized) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun setAccountAttributes( attributes: AccountAttributes - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { when (val result = SignalNetwork.account.setAccountAttributes(attributes.toServiceAccountAttributes())) { - is NetworkResult.Success -> RegistrationNetworkResult.Success(Unit) + is NetworkResult.Success -> RequestResult.Success(Unit) is NetworkResult.StatusCodeError -> { when (result.code) { - 401 -> RegistrationNetworkResult.Failure(SetAccountAttributesError.Unauthorized) - 422 -> RegistrationNetworkResult.Failure(SetAccountAttributesError.InvalidRequest(result.toString())) - else -> RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${result.code}")) + 401 -> RequestResult.NonSuccess(SetAccountAttributesError.Unauthorized) + 422 -> RequestResult.NonSuccess(SetAccountAttributesError.InvalidRequest(result.toString())) + else -> RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${result.code}")) } } - is NetworkResult.NetworkError -> RegistrationNetworkResult.NetworkError(result.exception) - is NetworkResult.ApplicationError -> RegistrationNetworkResult.ApplicationError(result.throwable) + is NetworkResult.NetworkError -> RequestResult.RetryableNetworkError(result.exception) + is NetworkResult.ApplicationError -> RequestResult.ApplicationError(result.throwable) } } diff --git a/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkController.kt b/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkController.kt index b6d670dce9..c2bbb13e63 100644 --- a/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkController.kt +++ b/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkController.kt @@ -8,6 +8,7 @@ package org.signal.registration.sample.debug import kotlinx.coroutines.flow.Flow import org.signal.core.models.MasterKey import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.NetworkController.AccountAttributes import org.signal.registration.NetworkController.BackupMasterKeyError @@ -21,7 +22,6 @@ import org.signal.registration.NetworkController.PreKeyCollection import org.signal.registration.NetworkController.ProvisioningEvent import org.signal.registration.NetworkController.RegisterAccountError import org.signal.registration.NetworkController.RegisterAccountResponse -import org.signal.registration.NetworkController.RegistrationNetworkResult import org.signal.registration.NetworkController.RequestVerificationCodeError import org.signal.registration.NetworkController.RestoreMasterKeyError import org.signal.registration.NetworkController.SessionMetadata @@ -55,16 +55,16 @@ class DebugNetworkController( fcmToken: String?, mcc: String?, mnc: String? - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("createSession")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("createSession")?.let { Log.d(TAG, "[createSession] Returning debug override") return it } return delegate.createSession(e164, fcmToken, mcc, mnc) } - override suspend fun getSession(sessionId: String): RegistrationNetworkResult { - NetworkDebugState.getOverride>("getSession")?.let { + override suspend fun getSession(sessionId: String): RequestResult { + NetworkDebugState.getOverride>("getSession")?.let { Log.d(TAG, "[getSession] Returning debug override") return it } @@ -75,8 +75,8 @@ class DebugNetworkController( sessionId: String?, pushChallengeToken: String?, captchaToken: String? - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("updateSession")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("updateSession")?.let { Log.d(TAG, "[updateSession] Returning debug override") return it } @@ -88,8 +88,8 @@ class DebugNetworkController( locale: Locale?, androidSmsRetrieverSupported: Boolean, transport: VerificationCodeTransport - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("requestVerificationCode")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("requestVerificationCode")?.let { Log.d(TAG, "[requestVerificationCode] Returning debug override") return it } @@ -99,8 +99,8 @@ class DebugNetworkController( override suspend fun submitVerificationCode( sessionId: String, verificationCode: String - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("submitVerificationCode")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("submitVerificationCode")?.let { Log.d(TAG, "[submitVerificationCode] Returning debug override") return it } @@ -117,8 +117,8 @@ class DebugNetworkController( pniPreKeys: PreKeyCollection, fcmToken: String?, skipDeviceTransfer: Boolean - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("registerAccount")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("registerAccount")?.let { Log.d(TAG, "[registerAccount] Returning debug override") return it } @@ -146,8 +146,8 @@ class DebugNetworkController( override suspend fun restoreMasterKeyFromSvr( svrCredentials: SvrCredentials, pin: String - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("restoreMasterKeyFromSvr")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("restoreMasterKeyFromSvr")?.let { Log.d(TAG, "[restoreMasterKeyFromSvr] Returning debug override") return it } @@ -157,8 +157,8 @@ class DebugNetworkController( override suspend fun setPinAndMasterKeyOnSvr( pin: String, masterKey: MasterKey - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("setPinAndMasterKeyOnSvr")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("setPinAndMasterKeyOnSvr")?.let { Log.d(TAG, "[setPinAndMasterKeyOnSvr] Returning debug override") return it } @@ -170,32 +170,32 @@ class DebugNetworkController( delegate.enqueueSvrGuessResetJob() } - override suspend fun enableRegistrationLock(): RegistrationNetworkResult { - NetworkDebugState.getOverride>("enableRegistrationLock")?.let { + override suspend fun enableRegistrationLock(): RequestResult { + NetworkDebugState.getOverride>("enableRegistrationLock")?.let { Log.d(TAG, "[enableRegistrationLock] Returning debug override") return it } return delegate.enableRegistrationLock() } - override suspend fun disableRegistrationLock(): RegistrationNetworkResult { - NetworkDebugState.getOverride>("disableRegistrationLock")?.let { + override suspend fun disableRegistrationLock(): RequestResult { + NetworkDebugState.getOverride>("disableRegistrationLock")?.let { Log.d(TAG, "[disableRegistrationLock] Returning debug override") return it } return delegate.disableRegistrationLock() } - override suspend fun setAccountAttributes(attributes: AccountAttributes): RegistrationNetworkResult { - NetworkDebugState.getOverride>("setAccountAttributes")?.let { + override suspend fun setAccountAttributes(attributes: AccountAttributes): RequestResult { + NetworkDebugState.getOverride>("setAccountAttributes")?.let { Log.d(TAG, "[setAccountAttributes] Returning debug override") return it } return delegate.setAccountAttributes(attributes) } - override suspend fun getSvrCredentials(): RegistrationNetworkResult { - NetworkDebugState.getOverride>("getSvrCredentials")?.let { + override suspend fun getSvrCredentials(): RequestResult { + NetworkDebugState.getOverride>("getSvrCredentials")?.let { Log.d(TAG, "[getSvrCredentials] Returning debug override") return it } @@ -209,8 +209,8 @@ class DebugNetworkController( override suspend fun checkSvrCredentials( e164: String, credentials: List - ): RegistrationNetworkResult { - NetworkDebugState.getOverride>("checkSvrCredentials")?.let { + ): RequestResult { + NetworkDebugState.getOverride>("checkSvrCredentials")?.let { Log.d(TAG, "[checkSvrCredentials] Returning debug override") return it } diff --git a/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkMockData.kt b/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkMockData.kt index 451cfa14ea..a4d7c0c7c0 100644 --- a/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkMockData.kt +++ b/demo/registration/src/main/java/org/signal/registration/sample/debug/DebugNetworkMockData.kt @@ -5,9 +5,10 @@ package org.signal.registration.sample.debug +import org.signal.libsignal.net.BadRequestError +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.NetworkController.RegistrationLockResponse -import org.signal.registration.NetworkController.RegistrationNetworkResult import org.signal.registration.NetworkController.SessionMetadata import org.signal.registration.NetworkController.SvrCredentials import org.signal.registration.NetworkController.ThirdPartyServiceErrorResponse @@ -79,7 +80,7 @@ object DebugNetworkMockData { private fun discoverMethods(): List { return NetworkController::class.memberFunctions - .filter { it.returnType.isRegistrationNetworkResult() } + .filter { it.returnType.isRequestResult() } .map { function -> val methodName = function.name val (_, errorType) = extractResultTypes(function.returnType) @@ -89,8 +90,8 @@ object DebugNetworkMockData { .sortedBy { it.methodName } } - private fun KType.isRegistrationNetworkResult(): Boolean { - return this.jvmErasure == RegistrationNetworkResult::class + private fun KType.isRequestResult(): Boolean { + return this.jvmErasure == RequestResult::class } private fun extractResultTypes(returnType: KType): Pair?, KClass<*>?> { @@ -118,12 +119,12 @@ object DebugNetworkMockData { // Always add NetworkError and ApplicationError options.add( ResultOption("network_error", "NetworkError") { - RegistrationNetworkResult.NetworkError(IOException("Mock network error")) + RequestResult.RetryableNetworkError(IOException("Mock network error")) } ) options.add( ResultOption("application_error", "ApplicationError") { - RegistrationNetworkResult.ApplicationError(RuntimeException("Mock application error")) + RequestResult.ApplicationError(RuntimeException("Mock application error")) } ) @@ -137,7 +138,7 @@ object DebugNetworkMockData { val name = subclass.simpleName?.toSnakeCase() ?: return@mapNotNull null val displayName = subclass.simpleName ?: return@mapNotNull null ResultOption(name, displayName) { - RegistrationNetworkResult.Failure(instance) + RequestResult.NonSuccess(instance as BadRequestError) } } else { null diff --git a/demo/registration/src/main/java/org/signal/registration/sample/dependencies/DemoNetworkController.kt b/demo/registration/src/main/java/org/signal/registration/sample/dependencies/DemoNetworkController.kt index 2e411be41e..81702ae67b 100644 --- a/demo/registration/src/main/java/org/signal/registration/sample/dependencies/DemoNetworkController.kt +++ b/demo/registration/src/main/java/org/signal/registration/sample/dependencies/DemoNetworkController.kt @@ -20,6 +20,7 @@ import okhttp3.Response import org.signal.core.models.MasterKey import org.signal.core.util.logging.Log import org.signal.libsignal.net.Network +import org.signal.libsignal.net.RequestResult import org.signal.libsignal.protocol.IdentityKey import org.signal.libsignal.protocol.IdentityKeyPair import org.signal.libsignal.protocol.ecc.ECPrivateKey @@ -36,7 +37,6 @@ import org.signal.registration.NetworkController.ProvisioningMessage import org.signal.registration.NetworkController.RegisterAccountError import org.signal.registration.NetworkController.RegisterAccountResponse import org.signal.registration.NetworkController.RegistrationLockResponse -import org.signal.registration.NetworkController.RegistrationNetworkResult import org.signal.registration.NetworkController.RequestVerificationCodeError import org.signal.registration.NetworkController.SessionMetadata import org.signal.registration.NetworkController.SubmitVerificationCodeError @@ -104,58 +104,58 @@ class DemoNetworkController( fcmToken: String?, mcc: String?, mnc: String? - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.createVerificationSessionV2(e164, fcmToken, mcc, mnc).use { response -> when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 422 -> { - RegistrationNetworkResult.Failure(CreateSessionError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(CreateSessionError.InvalidRequest(response.body.string())) } 429 -> { - RegistrationNetworkResult.Failure(CreateSessionError.RateLimited(response.retryAfter())) + RequestResult.NonSuccess(CreateSessionError.RateLimited(response.retryAfter())) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } - override suspend fun getSession(sessionId: String): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun getSession(sessionId: String): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.getSessionStatusV2(sessionId).use { response -> when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(GetSessionStatusError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(GetSessionStatusError.InvalidRequest(response.body.string())) } 404 -> { - RegistrationNetworkResult.Failure(GetSessionStatusError.SessionNotFound(response.body.string())) + RequestResult.NonSuccess(GetSessionStatusError.SessionNotFound(response.body.string())) } 422 -> { - RegistrationNetworkResult.Failure(GetSessionStatusError.InvalidSessionId(response.body.string())) + RequestResult.NonSuccess(GetSessionStatusError.InvalidSessionId(response.body.string())) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -163,7 +163,7 @@ class DemoNetworkController( sessionId: String?, pushChallengeToken: String?, captchaToken: String? - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.patchVerificationSessionV2( sessionId, @@ -176,27 +176,27 @@ class DemoNetworkController( when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(UpdateSessionError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(UpdateSessionError.InvalidRequest(response.body.string())) } 409 -> { - RegistrationNetworkResult.Failure(UpdateSessionError.RejectedUpdate(response.body.string())) + RequestResult.NonSuccess(UpdateSessionError.RejectedUpdate(response.body.string())) } 429 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(UpdateSessionError.RateLimited(response.retryAfter(), session)) + RequestResult.NonSuccess(UpdateSessionError.RateLimited(response.retryAfter(), session)) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -205,7 +205,7 @@ class DemoNetworkController( locale: Locale?, androidSmsRetrieverSupported: Boolean, transport: VerificationCodeTransport - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val socketTransport = when (transport) { VerificationCodeTransport.SMS -> PushServiceSocket.VerificationCodeTransport.SMS @@ -221,76 +221,76 @@ class DemoNetworkController( when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(RequestVerificationCodeError.InvalidSessionId(response.body.string())) + RequestResult.NonSuccess(RequestVerificationCodeError.InvalidSessionId(response.body.string())) } 404 -> { - RegistrationNetworkResult.Failure(RequestVerificationCodeError.SessionNotFound(response.body.string())) + RequestResult.NonSuccess(RequestVerificationCodeError.SessionNotFound(response.body.string())) } 409 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.MissingRequestInformationOrAlreadyVerified(session)) + RequestResult.NonSuccess(RequestVerificationCodeError.MissingRequestInformationOrAlreadyVerified(session)) } 418 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(session)) + RequestResult.NonSuccess(RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(session)) } 429 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.RateLimited(response.retryAfter(), session)) + RequestResult.NonSuccess(RequestVerificationCodeError.RateLimited(response.retryAfter(), session)) } 440 -> { val errorBody = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RequestVerificationCodeError.ThirdPartyServiceError(errorBody)) + RequestResult.NonSuccess(RequestVerificationCodeError.ThirdPartyServiceError(errorBody)) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun submitVerificationCode( sessionId: String, verificationCode: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { pushServiceSocket.submitVerificationCodeV2(sessionId, verificationCode).use { response -> when (response.code) { 200 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(session) + RequestResult.Success(session) } 400 -> { - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode(response.body.string())) + RequestResult.NonSuccess(SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode(response.body.string())) } 404 -> { - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.SessionNotFound(response.body.string())) + RequestResult.NonSuccess(SubmitVerificationCodeError.SessionNotFound(response.body.string())) } 409 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested(session)) + RequestResult.NonSuccess(SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested(session)) } 429 -> { val session = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(SubmitVerificationCodeError.RateLimited(response.retryAfter(), session)) + RequestResult.NonSuccess(SubmitVerificationCodeError.RateLimited(response.retryAfter(), session)) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -304,7 +304,7 @@ class DemoNetworkController( pniPreKeys: PreKeyCollection, fcmToken: String?, skipDeviceTransfer: Boolean - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { check(sessionId != null || recoveryPassword != null) { "Either sessionId or recoveryPassword must be provided" } check(sessionId == null || recoveryPassword == null) { "Either sessionId or recoveryPassword must be provided, but not both" } @@ -327,36 +327,36 @@ class DemoNetworkController( when (response.code) { 200 -> { val result = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(result) + RequestResult.Success(result) } 401 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.SessionNotFoundOrNotVerified(response.body.string())) + RequestResult.NonSuccess(RegisterAccountError.SessionNotFoundOrNotVerified(response.body.string())) } 403 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.RegistrationRecoveryPasswordIncorrect(response.body.string())) + RequestResult.NonSuccess(RegisterAccountError.RegistrationRecoveryPasswordIncorrect(response.body.string())) } 409 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.DeviceTransferPossible) + RequestResult.NonSuccess(RegisterAccountError.DeviceTransferPossible) } 422 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(RegisterAccountError.InvalidRequest(response.body.string())) } 423 -> { val lockResponse = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Failure(RegisterAccountError.RegistrationLock(lockResponse)) + RequestResult.NonSuccess(RegisterAccountError.RegistrationLock(lockResponse)) } 429 -> { - RegistrationNetworkResult.Failure(RegisterAccountError.RateLimited(response.retryAfter())) + RequestResult.NonSuccess(RegisterAccountError.RateLimited(response.retryAfter())) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -467,7 +467,7 @@ class DemoNetworkController( override suspend fun restoreMasterKeyFromSvr( svrCredentials: NetworkController.SvrCredentials, pin: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val authCredentials = AuthCredentials.create(svrCredentials.username, svrCredentials.password) @@ -487,42 +487,42 @@ class DemoNetworkController( when (val response = svr2.restoreDataPreRegistration(authCredentials, null, pin)) { is RestoreResponse.Success -> { Log.i(TAG, "[restoreMasterKeyFromSvr] Successfully restored master key from SVR2. Value: ${Hex.toStringCondensed(response.masterKey.serialize())}") - RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(response.masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(response.masterKey)) } is RestoreResponse.PinMismatch -> { Log.w(TAG, "[restoreMasterKeyFromSvr] PIN mismatch. Tries remaining: ${response.triesRemaining}") - RegistrationNetworkResult.Failure(NetworkController.RestoreMasterKeyError.WrongPin(response.triesRemaining)) + RequestResult.NonSuccess(NetworkController.RestoreMasterKeyError.WrongPin(response.triesRemaining)) } is RestoreResponse.Missing -> { Log.w(TAG, "[restoreMasterKeyFromSvr] No SVR data found for user") - RegistrationNetworkResult.Failure(NetworkController.RestoreMasterKeyError.NoDataFound) + RequestResult.NonSuccess(NetworkController.RestoreMasterKeyError.NoDataFound) } is RestoreResponse.NetworkError -> { Log.w(TAG, "[restoreMasterKeyFromSvr] Network error", response.exception) - RegistrationNetworkResult.NetworkError(response.exception) + RequestResult.RetryableNetworkError(response.exception) } is RestoreResponse.ApplicationError -> { Log.w(TAG, "[restoreMasterKeyFromSvr] Application error", response.exception) - RegistrationNetworkResult.ApplicationError(response.exception) + RequestResult.ApplicationError(response.exception) } is RestoreResponse.EnclaveNotFound -> { Log.w(TAG, "[restoreMasterKeyFromSvr] Enclave not found") - RegistrationNetworkResult.ApplicationError(IllegalStateException("SVR2 enclave not found")) + RequestResult.ApplicationError(IllegalStateException("SVR2 enclave not found")) } } } catch (e: IOException) { Log.w(TAG, "[restoreMasterKeyFromSvr] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[restoreMasterKeyFromSvr] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun setPinAndMasterKeyOnSvr( pin: String, masterKey: MasterKey - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val aci = RegistrationPreferences.aci val pni = RegistrationPreferences.pni @@ -531,7 +531,7 @@ class DemoNetworkController( if (aci == null || e164 == null || password == null) { Log.w(TAG, "[backupMasterKeyToSvr] Credentials not available, cannot authenticate") - return@withContext RegistrationNetworkResult.Failure(NetworkController.BackupMasterKeyError.NotRegistered) + return@withContext RequestResult.NonSuccess(NetworkController.BackupMasterKeyError.NotRegistered) } val network = Network(Network.Environment.STAGING, "Signal-Android-Registration-Sample", emptyMap(), Network.BuildVariant.PRODUCTION) @@ -567,38 +567,38 @@ class DemoNetworkController( when (response) { is BackupResponse.Success -> { Log.i(TAG, "[backupMasterKeyToSvr] Successfully backed up master key to SVR2. Value: ${Hex.toStringCondensed(masterKey.serialize())}") - RegistrationNetworkResult.Success(NetworkController.SvrCredentials(response.authorization.username(), response.authorization.password())) + RequestResult.Success(NetworkController.SvrCredentials(response.authorization.username(), response.authorization.password())) } is BackupResponse.ApplicationError -> { Log.w(TAG, "[backupMasterKeyToSvr] Application error", response.exception) - RegistrationNetworkResult.ApplicationError(response.exception) + RequestResult.ApplicationError(response.exception) } is BackupResponse.NetworkError -> { Log.w(TAG, "[backupMasterKeyToSvr] Network error", response.exception) - RegistrationNetworkResult.NetworkError(response.exception) + RequestResult.RetryableNetworkError(response.exception) } is BackupResponse.EnclaveNotFound -> { Log.w(TAG, "[backupMasterKeyToSvr] Enclave not found") - RegistrationNetworkResult.Failure(NetworkController.BackupMasterKeyError.EnclaveNotFound) + RequestResult.NonSuccess(NetworkController.BackupMasterKeyError.EnclaveNotFound) } is BackupResponse.ExposeFailure -> { Log.w(TAG, "[backupMasterKeyToSvr] Expose failure -- per spec, treat as success.") - RegistrationNetworkResult.Success(null) + RequestResult.Success(null) } is BackupResponse.ServerRejected -> { Log.w(TAG, "[backupMasterKeyToSvr] Server rejected") - RegistrationNetworkResult.NetworkError(IOException("Server rejected backup request")) + RequestResult.RetryableNetworkError(IOException("Server rejected backup request")) } is BackupResponse.RateLimited -> { - RegistrationNetworkResult.NetworkError(IOException("Rate limited")) + RequestResult.RetryableNetworkError(IOException("Rate limited")) } } } catch (e: IOException) { Log.w(TAG, "[backupMasterKeyToSvr] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[backupMasterKeyToSvr] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } @@ -607,24 +607,24 @@ class DemoNetworkController( val masterKey = checkNotNull(RegistrationPreferences.masterKey) { "Master key is not set!" } val result = setPinAndMasterKeyOnSvr(pin, masterKey) - if (result !is RegistrationNetworkResult.Success) { + if (result !is RequestResult.Success) { Log.w(TAG, "Failed to set pin and master key on SVR! A real app would retry. Result: $result") } } - override suspend fun enableRegistrationLock(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun enableRegistrationLock(): RequestResult = withContext(Dispatchers.IO) { val aci = RegistrationPreferences.aci val password = RegistrationPreferences.servicePassword val masterKey = RegistrationPreferences.masterKey if (aci == null || password == null) { Log.w(TAG, "[enableRegistrationLock] Credentials not available") - return@withContext RegistrationNetworkResult.Failure(NetworkController.SetRegistrationLockError.NotRegistered) + return@withContext RequestResult.NonSuccess(NetworkController.SetRegistrationLockError.NotRegistered) } if (masterKey == null) { Log.w(TAG, "[enableRegistrationLock] Master key not available") - return@withContext RegistrationNetworkResult.Failure(NetworkController.SetRegistrationLockError.NoPinSet) + return@withContext RequestResult.NonSuccess(NetworkController.SetRegistrationLockError.NoPinSet) } val registrationLockToken = masterKey.deriveRegistrationLock() @@ -645,35 +645,35 @@ class DemoNetworkController( when (response.code) { 200, 204 -> { Log.i(TAG, "[enableRegistrationLock] Successfully enabled registration lock") - RegistrationNetworkResult.Success(Unit) + RequestResult.Success(Unit) } 401 -> { - RegistrationNetworkResult.Failure(NetworkController.SetRegistrationLockError.Unauthorized) + RequestResult.NonSuccess(NetworkController.SetRegistrationLockError.Unauthorized) } 422 -> { - RegistrationNetworkResult.Failure(NetworkController.SetRegistrationLockError.InvalidRequest(response.body?.string() ?: "")) + RequestResult.NonSuccess(NetworkController.SetRegistrationLockError.InvalidRequest(response.body?.string() ?: "")) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}")) } } } } catch (e: IOException) { Log.w(TAG, "[enableRegistrationLock] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[enableRegistrationLock] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } - override suspend fun disableRegistrationLock(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun disableRegistrationLock(): RequestResult = withContext(Dispatchers.IO) { val aci = RegistrationPreferences.aci val password = RegistrationPreferences.servicePassword if (aci == null || password == null) { Log.w(TAG, "[disableRegistrationLock] Credentials not available") - return@withContext RegistrationNetworkResult.Failure(NetworkController.SetRegistrationLockError.NotRegistered) + return@withContext RequestResult.NonSuccess(NetworkController.SetRegistrationLockError.NotRegistered) } try { @@ -690,34 +690,34 @@ class DemoNetworkController( when (response.code) { 200, 204 -> { Log.i(TAG, "[disableRegistrationLock] Successfully disabled registration lock") - RegistrationNetworkResult.Success(Unit) + RequestResult.Success(Unit) } 401 -> { - RegistrationNetworkResult.Failure(NetworkController.SetRegistrationLockError.Unauthorized) + RequestResult.NonSuccess(NetworkController.SetRegistrationLockError.Unauthorized) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}")) } } } } catch (e: IOException) { Log.w(TAG, "[disableRegistrationLock] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[disableRegistrationLock] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun setAccountAttributes( attributes: AccountAttributes - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { val aci = RegistrationPreferences.aci val password = RegistrationPreferences.servicePassword if (aci == null || password == null) { Log.w(TAG, "[setAccountAttributes] Credentials not available") - return@withContext RegistrationNetworkResult.Failure(NetworkController.SetAccountAttributesError.Unauthorized) + return@withContext RequestResult.NonSuccess(NetworkController.SetAccountAttributesError.Unauthorized) } try { @@ -736,35 +736,35 @@ class DemoNetworkController( when (response.code) { 200, 204 -> { Log.i(TAG, "[setAccountAttributes] Successfully updated account attributes") - RegistrationNetworkResult.Success(Unit) + RequestResult.Success(Unit) } 401 -> { - RegistrationNetworkResult.Failure(NetworkController.SetAccountAttributesError.Unauthorized) + RequestResult.NonSuccess(NetworkController.SetAccountAttributesError.Unauthorized) } 422 -> { - RegistrationNetworkResult.Failure(NetworkController.SetAccountAttributesError.InvalidRequest(response.body?.string() ?: "")) + RequestResult.NonSuccess(NetworkController.SetAccountAttributesError.InvalidRequest(response.body?.string() ?: "")) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body?.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body?.string()}")) } } } } catch (e: IOException) { Log.w(TAG, "[setAccountAttributes] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[setAccountAttributes] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } - override suspend fun getSvrCredentials(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + override suspend fun getSvrCredentials(): RequestResult = withContext(Dispatchers.IO) { val aci = RegistrationPreferences.aci val password = RegistrationPreferences.servicePassword if (aci == null || password == null) { Log.w(TAG, "[getSvrCredentials] Credentials not available") - return@withContext RegistrationNetworkResult.Failure(NetworkController.GetSvrCredentialsError.NoServiceCredentialsAvailable) + return@withContext RequestResult.NonSuccess(NetworkController.GetSvrCredentialsError.NoServiceCredentialsAvailable) } try { @@ -781,29 +781,29 @@ class DemoNetworkController( when (response.code) { 200 -> { val svrCredentials = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(svrCredentials) + RequestResult.Success(svrCredentials) } 401 -> { - RegistrationNetworkResult.Failure(NetworkController.GetSvrCredentialsError.Unauthorized) + RequestResult.NonSuccess(NetworkController.GetSvrCredentialsError.Unauthorized) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body.string()}")) } } } } catch (e: IOException) { Log.w(TAG, "[getSvrCredentials] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[getSvrCredentials] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } override suspend fun checkSvrCredentials( e164: String, credentials: List - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { try { val baseUrl = serviceConfiguration.signalServiceUrls[0].url @@ -821,25 +821,25 @@ class DemoNetworkController( when (response.code) { 200 -> { val result = json.decodeFromString(response.body.string()) - RegistrationNetworkResult.Success(result) + RequestResult.Success(result) } 400, 422 -> { - RegistrationNetworkResult.Failure(NetworkController.CheckSvrCredentialsError.InvalidRequest(response.body.string())) + RequestResult.NonSuccess(NetworkController.CheckSvrCredentialsError.InvalidRequest(response.body.string())) } 401 -> { - RegistrationNetworkResult.Failure(NetworkController.CheckSvrCredentialsError.Unauthorized) + RequestResult.NonSuccess(NetworkController.CheckSvrCredentialsError.Unauthorized) } else -> { - RegistrationNetworkResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body?.string()}")) + RequestResult.ApplicationError(IllegalStateException("Unexpected response code: ${response.code}, body: ${response.body?.string()}")) } } } } catch (e: IOException) { Log.w(TAG, "[checkSvrCredentials] IOException", e) - RegistrationNetworkResult.NetworkError(e) + RequestResult.RetryableNetworkError(e) } catch (e: Exception) { Log.w(TAG, "[checkSvrCredentials] Exception", e) - RegistrationNetworkResult.ApplicationError(e) + RequestResult.ApplicationError(e) } } diff --git a/demo/registration/src/main/java/org/signal/registration/sample/screens/main/MainScreenViewModel.kt b/demo/registration/src/main/java/org/signal/registration/sample/screens/main/MainScreenViewModel.kt index 9f91460af1..42eac2f5c5 100644 --- a/demo/registration/src/main/java/org/signal/registration/sample/screens/main/MainScreenViewModel.kt +++ b/demo/registration/src/main/java/org/signal/registration/sample/screens/main/MainScreenViewModel.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.launch import kotlinx.serialization.json.Json import org.signal.core.util.Base64 import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.PersistedFlowState import org.signal.registration.StorageController @@ -110,10 +111,10 @@ class MainScreenViewModel( private suspend fun checkRegistrationStatus() { when (val result = networkController.getSvrCredentials()) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.d(TAG, "[CheckRegistration] Still registered.") } - is NetworkController.RegistrationNetworkResult.Failure -> { + is RequestResult.NonSuccess -> { when (result.error) { NetworkController.GetSvrCredentialsError.Unauthorized -> { Log.w(TAG, "[CheckRegistration] No longer registered (401).") @@ -125,11 +126,11 @@ class MainScreenViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[CheckRegistration] Network error, can't verify status.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[CheckRegistration] Network error, can't verify status.", result.networkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[CheckRegistration] Application error, can't verify status.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[CheckRegistration] Application error, can't verify status.", result.cause) } } } diff --git a/demo/registration/src/main/java/org/signal/registration/sample/screens/pinsettings/PinSettingsViewModel.kt b/demo/registration/src/main/java/org/signal/registration/sample/screens/pinsettings/PinSettingsViewModel.kt index b4d933db08..b6602bf63b 100644 --- a/demo/registration/src/main/java/org/signal/registration/sample/screens/pinsettings/PinSettingsViewModel.kt +++ b/demo/registration/src/main/java/org/signal/registration/sample/screens/pinsettings/PinSettingsViewModel.kt @@ -13,8 +13,8 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController -import org.signal.registration.NetworkController.RegistrationNetworkResult import org.signal.registration.sample.storage.RegistrationPreferences /** @@ -75,7 +75,7 @@ class PinSettingsViewModel( } when (val result = networkController.setPinAndMasterKeyOnSvr(pin, masterKey)) { - is RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "Successfully backed up PIN to SVR") RegistrationPreferences.pin = pin _state.value = _state.value.copy( @@ -84,25 +84,25 @@ class PinSettingsViewModel( toastMessage = "PIN has been set successfully" ) } - is RegistrationNetworkResult.Failure -> { + is RequestResult.NonSuccess -> { Log.w(TAG, "Failed to backup PIN: ${result.error}") _state.value = _state.value.copy( loading = false, toastMessage = "Failed to set PIN: ${result.error::class.simpleName}" ) } - is RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "Network error while setting PIN", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "Network error while setting PIN", result.networkError) _state.value = _state.value.copy( loading = false, toastMessage = "Network error. Please check your connection." ) } - is RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "Application error while setting PIN", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "Application error while setting PIN", result.cause) _state.value = _state.value.copy( loading = false, - toastMessage = "An error occurred: ${result.exception.message}" + toastMessage = "An error occurred: ${result.cause.message}" ) } } @@ -120,7 +120,7 @@ class PinSettingsViewModel( } when (result) { - is RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { val newEnabled = !currentlyEnabled RegistrationPreferences.registrationLockEnabled = newEnabled Log.i(TAG, "Registration lock ${if (newEnabled) "enabled" else "disabled"}") @@ -130,25 +130,25 @@ class PinSettingsViewModel( toastMessage = if (newEnabled) "Registration lock enabled" else "Registration lock disabled" ) } - is RegistrationNetworkResult.Failure -> { + is RequestResult.NonSuccess -> { Log.w(TAG, "Failed to toggle registration lock: ${result.error}") _state.value = _state.value.copy( loading = false, toastMessage = "Failed to update registration lock" ) } - is RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "Network error while toggling registration lock", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "Network error while toggling registration lock", result.networkError) _state.value = _state.value.copy( loading = false, toastMessage = "Network error. Please check your connection." ) } - is RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "Application error while toggling registration lock", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "Application error while toggling registration lock", result.cause) _state.value = _state.value.copy( loading = false, - toastMessage = "An error occurred: ${result.exception.message}" + toastMessage = "An error occurred: ${result.cause.message}" ) } } @@ -182,7 +182,7 @@ class PinSettingsViewModel( ) when (val result = networkController.setAccountAttributes(attributes)) { - is RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { RegistrationPreferences.pinsOptedOut = newOptedOut Log.i(TAG, "PINs opt-out ${if (newOptedOut) "enabled" else "disabled"}") _state.value = _state.value.copy( @@ -191,25 +191,25 @@ class PinSettingsViewModel( toastMessage = if (newOptedOut) "Opted out of PINs" else "Opted back into PINs" ) } - is RegistrationNetworkResult.Failure -> { + is RequestResult.NonSuccess -> { Log.w(TAG, "Failed to toggle PINs opt-out: ${result.error}") _state.value = _state.value.copy( loading = false, toastMessage = "Failed to update PIN settings" ) } - is RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "Network error while toggling PINs opt-out", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "Network error while toggling PINs opt-out", result.networkError) _state.value = _state.value.copy( loading = false, toastMessage = "Network error. Please check your connection." ) } - is RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "Application error while toggling PINs opt-out", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "Application error while toggling PINs opt-out", result.cause) _state.value = _state.value.copy( loading = false, - toastMessage = "An error occurred: ${result.exception.message}" + toastMessage = "An error occurred: ${result.cause.message}" ) } } diff --git a/feature/registration/src/main/java/org/signal/registration/NetworkController.kt b/feature/registration/src/main/java/org/signal/registration/NetworkController.kt index 8aefe5029a..9fb888eb2e 100644 --- a/feature/registration/src/main/java/org/signal/registration/NetworkController.kt +++ b/feature/registration/src/main/java/org/signal/registration/NetworkController.kt @@ -12,11 +12,12 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import org.signal.core.models.MasterKey import org.signal.core.util.serialization.ByteArrayToBase64Serializer +import org.signal.libsignal.net.BadRequestError +import org.signal.libsignal.net.RequestResult import org.signal.libsignal.protocol.IdentityKey import org.signal.libsignal.protocol.IdentityKeyPair import org.signal.libsignal.protocol.state.KyberPreKeyRecord import org.signal.libsignal.protocol.state.SignedPreKeyRecord -import java.io.IOException import java.util.Locale import kotlin.time.Duration @@ -27,21 +28,21 @@ interface NetworkController { * * `POST /v1/verification/session` */ - suspend fun createSession(e164: String, fcmToken: String?, mcc: String?, mnc: String?): RegistrationNetworkResult + suspend fun createSession(e164: String, fcmToken: String?, mcc: String?, mnc: String?): RequestResult /** * Retrieve current status of a registration session. * * `GET /v1/verification/session/{session-id}` */ - suspend fun getSession(sessionId: String): RegistrationNetworkResult + suspend fun getSession(sessionId: String): RequestResult /** * Update the session with new information. * * `PATCH /v1/verification/session/{session-id}` */ - suspend fun updateSession(sessionId: String?, pushChallengeToken: String?, captchaToken: String?): RegistrationNetworkResult + suspend fun updateSession(sessionId: String?, pushChallengeToken: String?, captchaToken: String?): RequestResult /** * Request an SMS verification code. On success, the server will send an SMS verification code to this Signal user. @@ -55,14 +56,14 @@ interface NetworkController { locale: Locale?, androidSmsRetrieverSupported: Boolean, transport: VerificationCodeTransport - ): RegistrationNetworkResult + ): RequestResult /** * Submit a verification code sent by the service via one of the supported channels (SMS, phone call) to prove the registrant's control of the phone number. * * `PUT /v1/verification/session/{session-id}/code` */ - suspend fun submitVerificationCode(sessionId: String, verificationCode: String): RegistrationNetworkResult + suspend fun submitVerificationCode(sessionId: String, verificationCode: String): RequestResult /** * Officially register an account. @@ -83,7 +84,7 @@ interface NetworkController { pniPreKeys: PreKeyCollection, fcmToken: String?, skipDeviceTransfer: Boolean - ): RegistrationNetworkResult + ): RequestResult /** * Retrieves an FCM token, if possible. Null means that this device does not support FCM. @@ -117,7 +118,7 @@ interface NetworkController { suspend fun restoreMasterKeyFromSvr( svrCredentials: SvrCredentials, pin: String - ): RegistrationNetworkResult + ): RequestResult /** * Backs up the master key to SVR, protected by the user's PIN. @@ -129,7 +130,7 @@ interface NetworkController { suspend fun setPinAndMasterKeyOnSvr( pin: String, masterKey: MasterKey - ): RegistrationNetworkResult + ): RequestResult /** * Requests that the currently-set PIN and [MasterKey] are backed up to SVR. @@ -144,14 +145,14 @@ interface NetworkController { * * @return Success or an appropriate error. */ - suspend fun enableRegistrationLock(): RegistrationNetworkResult + suspend fun enableRegistrationLock(): RequestResult /** * Disables registration lock on the account. * * @return Success or an appropriate error. */ - suspend fun disableRegistrationLock(): RegistrationNetworkResult + suspend fun disableRegistrationLock(): RequestResult /** * Retrieves SVR2 authentication credentials for the authenticated account. @@ -160,7 +161,7 @@ interface NetworkController { * * @return SVR credentials on success, or an appropriate error. */ - suspend fun getSvrCredentials(): RegistrationNetworkResult + suspend fun getSvrCredentials(): RequestResult /** * Checks if the SVR2 credentials are valid for the given phone number. @@ -169,7 +170,7 @@ interface NetworkController { * * @return A response containing a mapping of which credentials are matches. */ - suspend fun checkSvrCredentials(e164: String, credentials: List): RegistrationNetworkResult + suspend fun checkSvrCredentials(e164: String, credentials: List): RequestResult /** * Updates account attributes on the server. @@ -179,7 +180,7 @@ interface NetworkController { * @param attributes The account attributes to set. * @return Success or an appropriate error. */ - suspend fun setAccountAttributes(attributes: AccountAttributes): RegistrationNetworkResult + suspend fun setAccountAttributes(attributes: AccountAttributes): RequestResult /** * Starts a provisioning session for QR-based quick restore. @@ -212,40 +213,24 @@ interface NetworkController { // */ // suspend fun registerAsSecondaryDevice(verificationCode: String, attributes: AccountAttributes, aciPreKeys: PreKeyCollection, pniPreKeys: PreKeyCollection, fcmToken: String?) - sealed interface RegistrationNetworkResult { - data class Success(val data: T) : RegistrationNetworkResult - data class Failure(val error: T) : RegistrationNetworkResult - data class NetworkError(val exception: IOException) : RegistrationNetworkResult - data class ApplicationError(val exception: Throwable) : RegistrationNetworkResult - - fun mapSuccess(transform: (SuccessModel) -> NewSuccessModel): RegistrationNetworkResult { - return when (this) { - is Success -> Success(transform(this.data)) - is Failure -> Failure(this.error) - is NetworkError -> NetworkError(this.exception) - is ApplicationError -> ApplicationError(this.exception) - } - } - } - - sealed class CreateSessionError() { + sealed class CreateSessionError() : BadRequestError { data class InvalidRequest(val message: String) : CreateSessionError() data class RateLimited(val retryAfter: Duration) : CreateSessionError() } - sealed class GetSessionStatusError() { + sealed class GetSessionStatusError() : BadRequestError { data class InvalidSessionId(val message: String) : GetSessionStatusError() data class SessionNotFound(val message: String) : GetSessionStatusError() data class InvalidRequest(val message: String) : GetSessionStatusError() } - sealed class UpdateSessionError() { + sealed class UpdateSessionError() : BadRequestError { data class RejectedUpdate(val message: String) : UpdateSessionError() data class InvalidRequest(val message: String) : UpdateSessionError() data class RateLimited(val retryAfter: Duration, val session: SessionMetadata) : UpdateSessionError() } - sealed class RequestVerificationCodeError() { + sealed class RequestVerificationCodeError() : BadRequestError { data class InvalidSessionId(val message: String) : RequestVerificationCodeError() data class SessionNotFound(val message: String) : RequestVerificationCodeError() data class MissingRequestInformationOrAlreadyVerified(val session: SessionMetadata) : RequestVerificationCodeError() @@ -255,14 +240,14 @@ interface NetworkController { data class ThirdPartyServiceError(val data: ThirdPartyServiceErrorResponse) : RequestVerificationCodeError() } - sealed class SubmitVerificationCodeError() { + sealed class SubmitVerificationCodeError() : BadRequestError { data class InvalidSessionIdOrVerificationCode(val message: String) : SubmitVerificationCodeError() data class SessionNotFound(val message: String) : SubmitVerificationCodeError() data class SessionAlreadyVerifiedOrNoCodeRequested(val session: SessionMetadata) : SubmitVerificationCodeError() data class RateLimited(val retryAfter: Duration, val session: SessionMetadata) : SubmitVerificationCodeError() } - sealed class RegisterAccountError() { + sealed class RegisterAccountError() : BadRequestError { data class SessionNotFoundOrNotVerified(val message: String) : RegisterAccountError() data class RegistrationRecoveryPasswordIncorrect(val message: String) : RegisterAccountError() data object DeviceTransferPossible : RegisterAccountError() @@ -271,34 +256,34 @@ interface NetworkController { data class RateLimited(val retryAfter: Duration) : RegisterAccountError() } - sealed class RestoreMasterKeyError() { + sealed class RestoreMasterKeyError() : BadRequestError { data class WrongPin(val triesRemaining: Int) : RestoreMasterKeyError() data object NoDataFound : RestoreMasterKeyError() } - sealed class BackupMasterKeyError() { + sealed class BackupMasterKeyError() : BadRequestError { data object EnclaveNotFound : BackupMasterKeyError() data object NotRegistered : BackupMasterKeyError() } - sealed class SetRegistrationLockError() { + sealed class SetRegistrationLockError() : BadRequestError { data class InvalidRequest(val message: String) : SetRegistrationLockError() data object Unauthorized : SetRegistrationLockError() data object NotRegistered : SetRegistrationLockError() data object NoPinSet : SetRegistrationLockError() } - sealed class SetAccountAttributesError() { + sealed class SetAccountAttributesError() : BadRequestError { data class InvalidRequest(val message: String) : SetAccountAttributesError() data object Unauthorized : SetAccountAttributesError() } - sealed class GetSvrCredentialsError() { + sealed class GetSvrCredentialsError() : BadRequestError { data object Unauthorized : GetSvrCredentialsError() data object NoServiceCredentialsAvailable : GetSvrCredentialsError() } - sealed class CheckSvrCredentialsError() { + sealed class CheckSvrCredentialsError() : BadRequestError { data object Unauthorized : CheckSvrCredentialsError() data class InvalidRequest(val message: String) : CheckSvrCredentialsError() } diff --git a/feature/registration/src/main/java/org/signal/registration/RegistrationRepository.kt b/feature/registration/src/main/java/org/signal/registration/RegistrationRepository.kt index 9bf52b98e9..6c81654784 100644 --- a/feature/registration/src/main/java/org/signal/registration/RegistrationRepository.kt +++ b/feature/registration/src/main/java/org/signal/registration/RegistrationRepository.kt @@ -18,6 +18,7 @@ import org.signal.core.models.AccountEntropyPool import org.signal.core.models.MasterKey import org.signal.core.util.Base64 import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.libsignal.protocol.IdentityKeyPair import org.signal.libsignal.protocol.ecc.ECKeyPair import org.signal.libsignal.protocol.kem.KEMKeyPair @@ -32,7 +33,6 @@ import org.signal.registration.NetworkController.PreKeyCollection import org.signal.registration.NetworkController.ProvisioningEvent import org.signal.registration.NetworkController.RegisterAccountError import org.signal.registration.NetworkController.RegisterAccountResponse -import org.signal.registration.NetworkController.RegistrationNetworkResult import org.signal.registration.NetworkController.RequestVerificationCodeError import org.signal.registration.NetworkController.RestoreMasterKeyError import org.signal.registration.NetworkController.SessionMetadata @@ -56,7 +56,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ private val json = Json { ignoreUnknownKeys = true } } - suspend fun createSession(e164: String): RegistrationNetworkResult = withContext(Dispatchers.IO) { + suspend fun createSession(e164: String): RequestResult = withContext(Dispatchers.IO) { val fcmToken = networkController.getFcmToken() networkController.createSession( e164 = e164, @@ -70,7 +70,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ sessionId: String, smsAutoRetrieveCodeSupported: Boolean, transport: NetworkController.VerificationCodeTransport - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { networkController.requestVerificationCode( sessionId = sessionId, locale = Locale.getDefault(), @@ -84,7 +84,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ suspend fun submitCaptchaToken( sessionId: String, captchaToken: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { networkController.updateSession( sessionId = sessionId, pushChallengeToken = null, @@ -99,7 +99,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ suspend fun submitPushChallengeToken( sessionId: String, pushChallengeToken: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { networkController.updateSession( sessionId = sessionId, pushChallengeToken = pushChallengeToken, @@ -110,18 +110,18 @@ class RegistrationRepository(val context: Context, val networkController: Networ suspend fun submitVerificationCode( sessionId: String, verificationCode: String - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { networkController.submitVerificationCode( sessionId = sessionId, verificationCode = verificationCode ) } - suspend fun getSvrCredentials(): RegistrationNetworkResult = withContext(Dispatchers.IO) { + suspend fun getSvrCredentials(): RequestResult = withContext(Dispatchers.IO) { networkController.getSvrCredentials().also { - if (it is RegistrationNetworkResult.Success) { + if (it is RequestResult.Success) { storageController.updateInProgressRegistrationData { - svrCredentials = svrCredentials + SvrCredential(username = it.data.username, password = it.data.password) + svrCredentials = svrCredentials + SvrCredential(username = it.result.username, password = it.result.password) } BackupManager(context).dataChanged() } @@ -133,7 +133,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ data.svrCredentials.map { SvrCredentials(username = it.username, password = it.password) } } - suspend fun checkSvrCredentials(e164: String, credentials: List): RegistrationNetworkResult = withContext(Dispatchers.IO) { + suspend fun checkSvrCredentials(e164: String, credentials: List): RequestResult = withContext(Dispatchers.IO) { networkController.checkSvrCredentials(e164, credentials) } @@ -142,16 +142,16 @@ class RegistrationRepository(val context: Context, val networkController: Networ pin: String, isAlphanumeric: Boolean, forRegistrationLock: Boolean - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { networkController.restoreMasterKeyFromSvr( svrCredentials = svrCredentials, pin = pin ).also { - if (it is RegistrationNetworkResult.Success) { + if (it is RequestResult.Success) { storageController.updateInProgressRegistrationData { this.pin = pin this.pinIsAlphanumeric = isAlphanumeric - this.temporaryMasterKey = it.data.masterKey.serialize().toByteString() + this.temporaryMasterKey = it.result.masterKey.serialize().toByteString() this.registrationLockEnabled = forRegistrationLock this.svrCredentials += SvrCredential(username = svrCredentials.username, password = svrCredentials.password) } @@ -189,7 +189,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ skipDeviceTransfer: Boolean = true, preExistingRegistrationData: PreExistingRegistrationData? = null, existingAccountEntropyPool: AccountEntropyPool? = null - ): RegistrationNetworkResult, RegisterAccountError> = withContext(Dispatchers.IO) { + ): RequestResult, RegisterAccountError> = withContext(Dispatchers.IO) { registerAccount( e164 = e164, sessionId = null, @@ -222,7 +222,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ sessionId: String, registrationLock: String? = null, skipDeviceTransfer: Boolean = true - ): RegistrationNetworkResult, RegisterAccountError> = withContext(Dispatchers.IO) { + ): RequestResult, RegisterAccountError> = withContext(Dispatchers.IO) { registerAccount(e164, sessionId, recoveryPassword = null, registrationLock, skipDeviceTransfer) } @@ -245,7 +245,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ */ suspend fun registerAccountWithProvisioningData( provisioningMessage: NetworkController.ProvisioningMessage - ): RegistrationNetworkResult, RegisterAccountError> = withContext(Dispatchers.IO) { + ): RequestResult, RegisterAccountError> = withContext(Dispatchers.IO) { storageController.updateInProgressRegistrationData { provisioningData = ProvisioningData( restoreMethodToken = provisioningMessage.restoreMethodToken, @@ -304,7 +304,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ existingAccountEntropyPool: AccountEntropyPool? = null, existingAciIdentityKeyPair: IdentityKeyPair? = null, existingPniIdentityKeyPair: IdentityKeyPair? = null - ): RegistrationNetworkResult, RegisterAccountError> = withContext(Dispatchers.IO) { + ): RequestResult, RegisterAccountError> = withContext(Dispatchers.IO) { check(sessionId != null || recoveryPassword != null) { "Either sessionId or recoveryPassword must be provided" } check(sessionId == null || recoveryPassword == null) { "Either sessionId or recoveryPassword must be provided, but not both" } @@ -382,32 +382,32 @@ class RegistrationRepository(val context: Context, val networkController: Networ skipDeviceTransfer = skipDeviceTransfer ) - if (result is RegistrationNetworkResult.Success) { + if (result is RequestResult.Success) { storageController.updateInProgressRegistrationData { - this.e164 = result.data.e164 - this.aci = result.data.aci - this.pni = result.data.pni + this.e164 = result.result.e164 + this.aci = result.result.aci + this.pni = result.result.pni this.servicePassword = keyMaterial.servicePassword this.accountEntropyPool = keyMaterial.accountEntropyPool.value } storageController.commitRegistrationData() } - result.mapSuccess { it to keyMaterial } + result.map { it to keyMaterial } } suspend fun setNewlyCreatedPin( pin: String, isAlphanumeric: Boolean, masterKey: MasterKey - ): RegistrationNetworkResult = withContext(Dispatchers.IO) { + ): RequestResult = withContext(Dispatchers.IO) { val result = networkController.setPinAndMasterKeyOnSvr(pin, masterKey) - if (result is RegistrationNetworkResult.Success) { + if (result is RequestResult.Success) { storageController.updateInProgressRegistrationData { this.pin = pin this.pinIsAlphanumeric = isAlphanumeric - result.data?.let { credential -> + result.result?.let { credential -> this.svrCredentials += SvrCredential(username = credential.username, password = credential.password) } } @@ -483,7 +483,7 @@ class RegistrationRepository(val context: Context, val networkController: Networ */ suspend fun validateSession(sessionId: String): SessionMetadata? = withContext(Dispatchers.IO) { when (val result = networkController.getSession(sessionId)) { - is RegistrationNetworkResult.Success -> result.data + is RequestResult.Success -> result.result else -> null } } diff --git a/feature/registration/src/main/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModel.kt index 89755aabf6..ee5e5f0647 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModel.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withTimeoutOrNull import org.signal.core.models.AccountEntropyPool import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.PendingRestoreOption import org.signal.registration.RegistrationFlowEvent @@ -195,9 +196,9 @@ class PhoneNumberEntryViewModel( val registrationLock = masterKey.deriveRegistrationLock().takeIf { state.preExistingRegistrationData.registrationLockEnabled } when (val registerResult = repository.registerAccountWithRecoveryPassword(e164, recoveryPassword, registrationLock, skipDeviceTransfer = true, state.preExistingRegistrationData)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[Register] Successfully re-registered using RRP from pre-existing data.") - val (response, keyMaterial) = registerResult.data + val (response, keyMaterial) = registerResult.result parentEventEmitter(RegistrationFlowEvent.Registered(keyMaterial.accountEntropyPool)) @@ -208,8 +209,8 @@ class PhoneNumberEntryViewModel( } return state } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (registerResult.error) { + is RequestResult.NonSuccess -> { + when (val error = registerResult.error) { is NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified -> { Log.w(TAG, "[Register] Got told that our session could not be found when registering with RRP. We should never get into this state. Resetting.") parentEventEmitter(RegistrationFlowEvent.ResetState) @@ -224,34 +225,34 @@ class PhoneNumberEntryViewModel( Log.w(TAG, "[Register] Reglocked. This implies that the user still had reglock enabled despite the pre-existing data not thinking it was.") parentEventEmitter.navigateTo( RegistrationRoute.PinEntryForRegistrationLock( - timeRemaining = registerResult.error.data.timeRemaining, - svrCredentials = registerResult.error.data.svr2Credentials + timeRemaining = error.data.timeRemaining, + svrCredentials = error.data.svr2Credentials ) ) return state } is NetworkController.RegisterAccountError.RateLimited -> { - Log.w(TAG, "[Register] Rate limited (retryAfter: ${registerResult.error.retryAfter}).") - return state.copy(oneTimeEvent = OneTimeEvent.RateLimited(registerResult.error.retryAfter)) + Log.w(TAG, "[Register] Rate limited (retryAfter: ${error.retryAfter}).") + return state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RegisterAccountError.InvalidRequest -> { - Log.w(TAG, "[Register] Invalid request when registering account with RRP. Ditching pre-existing data and continuing with session creation. Message: ${registerResult.error.message}") + Log.w(TAG, "[Register] Invalid request when registering account with RRP. Ditching pre-existing data and continuing with session creation. Message: ${error.message}") parentEventEmitter(RegistrationFlowEvent.RecoveryPasswordInvalid) state = state.copy(preExistingRegistrationData = null) } is NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect -> { - Log.w(TAG, "[Register] Registration recovery password incorrect. Ditching pre-existing data and continuing with session creation. Message: ${registerResult.error.message}") + Log.w(TAG, "[Register] Registration recovery password incorrect. Ditching pre-existing data and continuing with session creation. Message: ${error.message}") parentEventEmitter(RegistrationFlowEvent.RecoveryPasswordInvalid) state = state.copy(preExistingRegistrationData = null) } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[Register] Network error.", registerResult.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[Register] Network error.", registerResult.networkError) return state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[Register] Unknown error when registering account.", registerResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[Register] Unknown error when registering account.", registerResult.cause) return state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -285,9 +286,9 @@ class PhoneNumberEntryViewModel( val recoveryPassword = aep.deriveMasterKey().deriveRegistrationRecoveryPassword() return when (val result = repository.registerAccountWithRecoveryPassword(e164, recoveryPassword, existingAccountEntropyPool = aep)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[LocalRestore] Successfully registered using RRP from restored AEP.") - val (response, keyMaterial) = result.data + val (response, keyMaterial) = result.result parentEventEmitter(RegistrationFlowEvent.Registered(keyMaterial.accountEntropyPool)) @@ -298,15 +299,15 @@ class PhoneNumberEntryViewModel( } state } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect -> { Log.w(TAG, "[LocalRestore] RRP incorrect. Falling back to session-based registration.") parentEventEmitter(RegistrationFlowEvent.RecoveryPasswordInvalid) applySessionBasedRegistration(state, e164, parentEventEmitter) } is NetworkController.RegisterAccountError.InvalidRequest -> { - Log.w(TAG, "[LocalRestore] Invalid request. Falling back to session-based registration. Message: ${result.error.message}") + Log.w(TAG, "[LocalRestore] Invalid request. Falling back to session-based registration. Message: ${error.message}") parentEventEmitter(RegistrationFlowEvent.RecoveryPasswordInvalid) applySessionBasedRegistration(state, e164, parentEventEmitter) } @@ -314,15 +315,15 @@ class PhoneNumberEntryViewModel( Log.w(TAG, "[LocalRestore] Registration locked.") parentEventEmitter.navigateTo( RegistrationRoute.PinEntryForRegistrationLock( - timeRemaining = result.error.data.timeRemaining, - svrCredentials = result.error.data.svr2Credentials + timeRemaining = error.data.timeRemaining, + svrCredentials = error.data.svr2Credentials ) ) state } is NetworkController.RegisterAccountError.RateLimited -> { - Log.w(TAG, "[LocalRestore] Rate limited (retryAfter: ${result.error.retryAfter}).") - state.copy(oneTimeEvent = OneTimeEvent.RateLimited(result.error.retryAfter)) + Log.w(TAG, "[LocalRestore] Rate limited (retryAfter: ${error.retryAfter}).") + state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified -> { Log.w(TAG, "[LocalRestore] Session not found. Falling back to session-based registration.") @@ -334,12 +335,12 @@ class PhoneNumberEntryViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[LocalRestore] Network error.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[LocalRestore] Network error.", result.networkError) state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[LocalRestore] Application error.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[LocalRestore] Application error.", result.cause) state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -360,25 +361,25 @@ class PhoneNumberEntryViewModel( // If they successfully restore the master key at that screen, we can use that to build the RRP and register without SMS. if (state.restoredSvrCredentials.isNotEmpty()) { when (val result = repository.checkSvrCredentials(e164, state.restoredSvrCredentials)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[CheckSVRCredentials] Successfully validated credentials for $e164.") - val credential = result.data.validCredential + val credential = result.result.validCredential if (credential != null) { parentEventEmitter(RegistrationFlowEvent.E164Chosen(e164)) parentEventEmitter.navigateTo(RegistrationRoute.PinEntryForSmsBypass(credential)) return state } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[CheckSVRCredentials] Network error. Ignoring error and continuing without RRP.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[CheckSVRCredentials] Network error. Ignoring error and continuing without RRP.", result.networkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[CheckSVRCredentials] Application error. Ignoring error and continuing without RRP.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[CheckSVRCredentials] Application error. Ignoring error and continuing without RRP.", result.cause) } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.CheckSvrCredentialsError.InvalidRequest -> { - Log.w(TAG, "[CheckSVRCredentials] Invalid request. Ignoring error and continuing without RRP. Message: ${result.error.message}") + Log.w(TAG, "[CheckSVRCredentials] Invalid request. Ignoring error and continuing without RRP. Message: ${error.message}") } NetworkController.CheckSvrCredentialsError.Unauthorized -> { @@ -395,27 +396,27 @@ class PhoneNumberEntryViewModel( } var sessionMetadata: NetworkController.SessionMetadata = state.sessionMetadata ?: when (val response = this@PhoneNumberEntryViewModel.repository.createSession(e164)) { - is NetworkController.RegistrationNetworkResult.Success -> { - response.data + is RequestResult.Success -> { + response.result } - is NetworkController.RegistrationNetworkResult.Failure -> { - return when (response.error) { + is RequestResult.NonSuccess -> { + return when (val error = response.error) { is NetworkController.CreateSessionError.InvalidRequest -> { - Log.w(TAG, "[CreateSession] Invalid request when creating session. Message: ${response.error.message}") + Log.w(TAG, "[CreateSession] Invalid request when creating session. Message: ${error.message}") state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } is NetworkController.CreateSessionError.RateLimited -> { - Log.w(TAG, "[CreateSession] Rate limited (retryAfter: ${response.error.retryAfter}).") - state.copy(oneTimeEvent = OneTimeEvent.RateLimited(response.error.retryAfter)) + Log.w(TAG, "[CreateSession] Rate limited (retryAfter: ${error.retryAfter}).") + state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[CreateSession] Network error.", response.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[CreateSession] Network error.", response.networkError) return state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "Unknown error when creating session.", response.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "Unknown error when creating session.", response.cause) return state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -432,20 +433,20 @@ class PhoneNumberEntryViewModel( Log.d(TAG, "Received push challenge token, submitting...") val updateResult = repository.submitPushChallengeToken(sessionMetadata.id, pushChallengeToken) sessionMetadata = when (updateResult) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.d(TAG, "[SubmitPushChallengeToken] Successfully submitted push challenge token.") - updateResult.data + updateResult.result } - is NetworkController.RegistrationNetworkResult.Failure -> { + is RequestResult.NonSuccess -> { Log.w(TAG, "[SubmitPushChallengeToken] Failed to submit push challenge token: ${updateResult.error}") sessionMetadata } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[SubmitPushChallengeToken] Network error submitting push challenge token", updateResult.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[SubmitPushChallengeToken] Network error submitting push challenge token", updateResult.networkError) sessionMetadata } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[SubmitPushChallengeToken] Application error submitting push challenge token", updateResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[SubmitPushChallengeToken] Application error submitting push challenge token", updateResult.cause) sessionMetadata } } @@ -469,19 +470,19 @@ class PhoneNumberEntryViewModel( ) sessionMetadata = when (verificationCodeResponse) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.d(TAG, "[RequestVerificationCode] Successfully requested verification code.") - verificationCodeResponse.data + verificationCodeResponse.result } - is NetworkController.RegistrationNetworkResult.Failure -> { - return when (verificationCodeResponse.error) { + is RequestResult.NonSuccess -> { + return when (val error = verificationCodeResponse.error) { is NetworkController.RequestVerificationCodeError.InvalidRequest -> { - Log.w(TAG, "[RequestVerificationCode] Invalid request when requesting verification code. Message: ${verificationCodeResponse.error.message}") + Log.w(TAG, "[RequestVerificationCode] Invalid request when requesting verification code. Message: ${error.message}") state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } is NetworkController.RequestVerificationCodeError.RateLimited -> { - Log.w(TAG, "[RequestVerificationCode] Rate limited (retryAfter: ${verificationCodeResponse.error.retryAfter}).") - state.copy(oneTimeEvent = OneTimeEvent.RateLimited(verificationCodeResponse.error.retryAfter)) + Log.w(TAG, "[RequestVerificationCode] Rate limited (retryAfter: ${error.retryAfter}).") + state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport -> { Log.w(TAG, "[RequestVerificationCode] Could not fulfill with requested transport.") @@ -507,12 +508,12 @@ class PhoneNumberEntryViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[RequestVerificationCode] Network error.", verificationCodeResponse.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[RequestVerificationCode] Network error.", verificationCodeResponse.networkError) return state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[RequestVerificationCode] Unknown error when creating session.", verificationCodeResponse.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[RequestVerificationCode] Unknown error when creating session.", verificationCodeResponse.cause) return state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -537,9 +538,9 @@ class PhoneNumberEntryViewModel( val updateResult = this@PhoneNumberEntryViewModel.repository.submitCaptchaToken(sessionMetadata.id, token) sessionMetadata = when (updateResult) { - is NetworkController.RegistrationNetworkResult.Success -> updateResult.data - is NetworkController.RegistrationNetworkResult.Failure -> { - return when (updateResult.error) { + is RequestResult.Success -> updateResult.result + is RequestResult.NonSuccess -> { + return when (val error = updateResult.error) { is NetworkController.UpdateSessionError.InvalidRequest -> { state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } @@ -547,15 +548,15 @@ class PhoneNumberEntryViewModel( state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } is NetworkController.UpdateSessionError.RateLimited -> { - state.copy(oneTimeEvent = OneTimeEvent.RateLimited(updateResult.error.retryAfter)) + state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { + is RequestResult.RetryableNetworkError -> { return state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "Unknown error when submitting captcha.", updateResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "Unknown error when submitting captcha.", updateResult.cause) return state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -575,14 +576,14 @@ class PhoneNumberEntryViewModel( ) sessionMetadata = when (verificationCodeResponse) { - is NetworkController.RegistrationNetworkResult.Success -> verificationCodeResponse.data - is NetworkController.RegistrationNetworkResult.Failure -> { - return when (verificationCodeResponse.error) { + is RequestResult.Success -> verificationCodeResponse.result + is RequestResult.NonSuccess -> { + return when (val error = verificationCodeResponse.error) { is NetworkController.RequestVerificationCodeError.InvalidRequest -> { state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } is NetworkController.RequestVerificationCodeError.RateLimited -> { - state.copy(oneTimeEvent = OneTimeEvent.RateLimited(verificationCodeResponse.error.retryAfter)) + state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport -> { state.copy(oneTimeEvent = OneTimeEvent.CouldNotRequestCodeWithSelectedTransport) @@ -604,11 +605,11 @@ class PhoneNumberEntryViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { + is RequestResult.RetryableNetworkError -> { return state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "Unknown error when requesting verification code.", verificationCodeResponse.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "Unknown error when requesting verification code.", verificationCodeResponse.cause) return state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } diff --git a/feature/registration/src/main/java/org/signal/registration/screens/pincreation/PinCreationViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/pincreation/PinCreationViewModel.kt index 3e75c9bfb6..4d709b6dab 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/pincreation/PinCreationViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/pincreation/PinCreationViewModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationFlowState @@ -93,14 +94,14 @@ class PinCreationViewModel( val masterKey = state.accountEntropyPool.deriveMasterKey() return when (val result = repository.setNewlyCreatedPin(pin, state.isAlphanumericKeyboard, masterKey)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[PinSubmitted] Successfully backed up master key to SVR.") // TODO profile creation parentEventEmitter.navigateTo(RegistrationRoute.FullyComplete) state } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.BackupMasterKeyError.EnclaveNotFound -> { Log.w(TAG, "[PinSubmitted] SVR enclave not found.") // TODO [registration] - Report to UI and indicate to library user that pin could not be created @@ -113,13 +114,13 @@ class PinCreationViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[PinSubmitted] Network error when backing up master key.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[PinSubmitted] Network error when backing up master key.", result.networkError) // TODO [registration] - Report to UI and indicate to library user that pin could not be created throw NotImplementedError("Report to UI and indicate to library user that pin could not be created") } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[PinSubmitted] Application error when backing up master key.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[PinSubmitted] Application error when backing up master key.", result.cause) // TODO [registration] - Report to UI and indicate to library user that pin could not be created throw NotImplementedError("Report to UI and indicate to library user that pin could not be created") } diff --git a/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModel.kt index 940f7a4512..dc27af9c7c 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import org.signal.core.models.MasterKey import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationFlowState @@ -81,15 +82,15 @@ class PinEntryForRegistrationLockViewModel( val restoreResult = repository.restoreMasterKeyFromSvr(svrCredentials, event.pin, state.isAlphanumericKeyboard, forRegistrationLock = true) val masterKey: MasterKey = when (restoreResult) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[PinEntered] Successfully restored master key from SVR.") - restoreResult.data.masterKey + restoreResult.result.masterKey } - is NetworkController.RegistrationNetworkResult.Failure -> { - return when (restoreResult.error) { + is RequestResult.NonSuccess -> { + return when (val error = restoreResult.error) { is NetworkController.RestoreMasterKeyError.WrongPin -> { - Log.w(TAG, "[PinEntered] Wrong PIN. Tries remaining: ${restoreResult.error.triesRemaining}") - state.copy(triesRemaining = restoreResult.error.triesRemaining) + Log.w(TAG, "[PinEntered] Wrong PIN. Tries remaining: ${error.triesRemaining}") + state.copy(triesRemaining = error.triesRemaining) } is NetworkController.RestoreMasterKeyError.NoDataFound -> { Log.w(TAG, "[PinEntered] No SVR data found. Account is locked.") @@ -98,12 +99,12 @@ class PinEntryForRegistrationLockViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[PinEntered] Network error when restoring master key.", restoreResult.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[PinEntered] Network error when restoring master key.", restoreResult.networkError) return state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[PinEntered] Application error when restoring master key.", restoreResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[PinEntered] Application error when restoring master key.", restoreResult.cause) return state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } } @@ -130,9 +131,9 @@ class PinEntryForRegistrationLockViewModel( ) return when (registerResult) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[PinEntered] Successfully registered!") - val (response, keyMaterial) = registerResult.data + val (response, keyMaterial) = registerResult.result parentEventEmitter(RegistrationFlowEvent.Registered(keyMaterial.accountEntropyPool)) // TODO storage service restore + profile screen when { @@ -141,10 +142,10 @@ class PinEntryForRegistrationLockViewModel( } state } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (registerResult.error) { + is RequestResult.NonSuccess -> { + when (val error = registerResult.error) { is NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified -> { - Log.w(TAG, "[PinEntered] Session not found or verified: ${registerResult.error.message}") + Log.w(TAG, "[PinEntered] Session not found or verified: ${error.message}") // TODO [registration] - Handle session not found or verified. throw NotImplementedError("Handle session not found or verified") } @@ -154,11 +155,11 @@ class PinEntryForRegistrationLockViewModel( state } is NetworkController.RegisterAccountError.RateLimited -> { - Log.w(TAG, "[PinEntered] Rate limited when registering. Retry After: ${registerResult.error.retryAfter}") - state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.RateLimited(registerResult.error.retryAfter)) + Log.w(TAG, "[PinEntered] Rate limited when registering. Retry After: ${error.retryAfter}") + state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RegisterAccountError.InvalidRequest -> { - Log.w(TAG, "[PinEntered] Invalid request when registering: ${registerResult.error.message}") + Log.w(TAG, "[PinEntered] Invalid request when registering: ${error.message}") state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } is NetworkController.RegisterAccountError.DeviceTransferPossible -> { @@ -166,18 +167,18 @@ class PinEntryForRegistrationLockViewModel( state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } is NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect -> { - Log.w(TAG, "[PinEntered] Registration recovery password incorrect: ${registerResult.error.message}") + Log.w(TAG, "[PinEntered] Registration recovery password incorrect: ${error.message}") // TODO [registration] - Handle incorrect password throw NotImplementedError("Handle incorrect password") } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[PinEntered] Network error when registering.", registerResult.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[PinEntered] Network error when registering.", registerResult.networkError) state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[PinEntered] Application error when registering.", registerResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[PinEntered] Application error when registering.", registerResult.cause) state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } } diff --git a/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModel.kt index a5b47f9acf..6e7eb6215b 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModel.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import org.signal.core.models.MasterKey import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.libsignal.protocol.util.Hex import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent @@ -102,16 +103,16 @@ class PinEntryForSmsBypassViewModel( } return when (val result = repository.restoreMasterKeyFromSvr(svrCredentials, event.pin, state.isAlphanumericKeyboard, forRegistrationLock = false)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[PinEntered] Successfully restored master key from SVR.") - parentEventEmitter(RegistrationFlowEvent.MasterKeyRestoredFromSvr(result.data.masterKey)) - attemptToRegister(state, state.e164, result.data.masterKey, provideRegistrationLock = false, parentEventEmitter) + parentEventEmitter(RegistrationFlowEvent.MasterKeyRestoredFromSvr(result.result.masterKey)) + attemptToRegister(state, state.e164, result.result.masterKey, provideRegistrationLock = false, parentEventEmitter) } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.RestoreMasterKeyError.WrongPin -> { - Log.w(TAG, "[PinEntered] Wrong PIN. Tries remaining: ${result.error.triesRemaining}") - state.copy(triesRemaining = result.error.triesRemaining) + Log.w(TAG, "[PinEntered] Wrong PIN. Tries remaining: ${error.triesRemaining}") + state.copy(triesRemaining = error.triesRemaining) } is NetworkController.RestoreMasterKeyError.NoDataFound -> { Log.w(TAG, "[PinEntered] No SVR data found for sms-bypass credential. Marking RRP as invalid and navigating back.") @@ -121,12 +122,12 @@ class PinEntryForSmsBypassViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[PinEntered] Network error when restoring master key (sms-bypass).", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[PinEntered] Network error when restoring master key (sms-bypass).", result.networkError) state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[PinEntered] Application error when restoring master key (sms-bypass).", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[PinEntered] Application error when restoring master key (sms-bypass).", result.cause) state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } } @@ -150,33 +151,33 @@ class PinEntryForSmsBypassViewModel( SensitiveLog.d(TAG, "Attempting registration using master key [${Hex.toStringCondensed(masterKey.serialize())}] and RRP [$recoveryPassword]") return when (val result = repository.registerAccountWithRecoveryPassword(e164, recoveryPassword, registrationLock, skipDeviceTransfer = true)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { parentEventEmitter.navigateTo(RegistrationRoute.FullyComplete) repository.enqueueSvrResetGuessCountJob() state } - is NetworkController.RegistrationNetworkResult.NetworkError -> { + is RequestResult.RetryableNetworkError -> { state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { + is RequestResult.ApplicationError -> { state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { NetworkController.RegisterAccountError.DeviceTransferPossible -> { Log.w(TAG, "[Register] Got told a device transfer is possible. We should never get into this state. Resetting.") parentEventEmitter(RegistrationFlowEvent.ResetState) state } is NetworkController.RegisterAccountError.InvalidRequest -> { - Log.w(TAG, "[Register] Invalid request when registering account with RRP. Marking RRP as invalid and navigating back. Message: ${result.error.message}") + Log.w(TAG, "[Register] Invalid request when registering account with RRP. Marking RRP as invalid and navigating back. Message: ${error.message}") parentEventEmitter(RegistrationFlowEvent.RecoveryPasswordInvalid) parentEventEmitter.navigateBack() state } is NetworkController.RegisterAccountError.RateLimited -> { - Log.w(TAG, "[Register] Rate limited (retryAfter: ${result.error.retryAfter}).") - state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.RateLimited(result.error.retryAfter)) + Log.w(TAG, "[Register] Rate limited (retryAfter: ${error.retryAfter}).") + state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RegisterAccountError.RegistrationLock -> { if (provideRegistrationLock) { diff --git a/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModel.kt index 28dce14b59..9c3025f27c 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModel.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationFlowState @@ -85,11 +86,11 @@ class PinEntryForSvrRestoreViewModel( Log.d(TAG, "[PinEntered] Attempting to restore master key from SVR...") val svrCredentials = when (val result = repository.getSvrCredentials()) { - is NetworkController.RegistrationNetworkResult.Success -> { - result.data + is RequestResult.Success -> { + result.result } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { NetworkController.GetSvrCredentialsError.NoServiceCredentialsAvailable -> { Log.w(TAG, "[PinEntered] No service credentials available when restoring from SVR. This should not happen. Resetting.") parentEventEmitter(RegistrationFlowEvent.ResetState) @@ -102,27 +103,27 @@ class PinEntryForSvrRestoreViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { + is RequestResult.RetryableNetworkError -> { return state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { + is RequestResult.ApplicationError -> { return state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } } return when (val result = repository.restoreMasterKeyFromSvr(svrCredentials, event.pin, state.isAlphanumericKeyboard, forRegistrationLock = false)) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[PinEntered] Successfully restored master key from SVR.") repository.enqueueSvrResetGuessCountJob() - parentEventEmitter(RegistrationFlowEvent.MasterKeyRestoredFromSvr(result.data.masterKey)) + parentEventEmitter(RegistrationFlowEvent.MasterKeyRestoredFromSvr(result.result.masterKey)) parentEventEmitter.navigateTo(RegistrationRoute.FullyComplete) state } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.RestoreMasterKeyError.WrongPin -> { - Log.w(TAG, "[PinEntered] Wrong PIN. Tries remaining: ${result.error.triesRemaining}") - state.copy(triesRemaining = result.error.triesRemaining) + Log.w(TAG, "[PinEntered] Wrong PIN. Tries remaining: ${error.triesRemaining}") + state.copy(triesRemaining = error.triesRemaining) } is NetworkController.RestoreMasterKeyError.NoDataFound -> { Log.w(TAG, "[PinEntered] No SVR data found. Need to create a PIN instead.") @@ -131,12 +132,12 @@ class PinEntryForSvrRestoreViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[PinEntered] Network error when restoring master key.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[PinEntered] Network error when restoring master key.", result.networkError) state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[PinEntered] Application error when restoring master key.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[PinEntered] Application error when restoring master key.", result.cause) state.copy(oneTimeEvent = PinEntryState.OneTimeEvent.UnknownError) } } diff --git a/feature/registration/src/main/java/org/signal/registration/screens/quickrestore/QuickRestoreQrViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/quickrestore/QuickRestoreQrViewModel.kt index 8bc76b06f0..0799f58212 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/quickrestore/QuickRestoreQrViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/quickrestore/QuickRestoreQrViewModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.signal.core.ui.compose.QrCodeData import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationRepository @@ -107,16 +108,16 @@ class QuickRestoreQrViewModel( val registerResult = repository.registerAccountWithProvisioningData(message) when (registerResult) { - is NetworkController.RegistrationNetworkResult.Success -> { - val (response, keyMaterial) = registerResult.data + is RequestResult.Success -> { + val (response, keyMaterial) = registerResult.result Log.i(TAG, "[Register] Success! reregistration: ${response.reregistration}") parentEventEmitter(RegistrationFlowEvent.Registered(keyMaterial.accountEntropyPool)) parentEventEmitter.navigateTo(RegistrationRoute.ChooseRestoreOptionAfterRegistration) } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (registerResult.error) { + is RequestResult.NonSuccess -> { + when (val error = registerResult.error) { is NetworkController.RegisterAccountError.RateLimited -> { - Log.w(TAG, "[Register] Rate limited (retryAfter: ${registerResult.error.retryAfter}).") + Log.w(TAG, "[Register] Rate limited (retryAfter: ${error.retryAfter}).") _localState.value = _localState.value.copy( isRegistering = false, showRegistrationError = true, @@ -124,7 +125,7 @@ class QuickRestoreQrViewModel( ) } is NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect -> { - Log.w(TAG, "[Register] Recovery password incorrect: ${registerResult.error.message}") + Log.w(TAG, "[Register] Recovery password incorrect: ${error.message}") _localState.value = _localState.value.copy( isRegistering = false, showRegistrationError = true, @@ -135,13 +136,13 @@ class QuickRestoreQrViewModel( Log.w(TAG, "[Register] Registration locked.") parentEventEmitter.navigateTo( RegistrationRoute.PinEntryForRegistrationLock( - timeRemaining = registerResult.error.data.timeRemaining, - svrCredentials = registerResult.error.data.svr2Credentials + timeRemaining = error.data.timeRemaining, + svrCredentials = error.data.svr2Credentials ) ) } is NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified -> { - Log.w(TAG, "[Register] Session not found or not verified: ${registerResult.error.message}") + Log.w(TAG, "[Register] Session not found or not verified: ${error.message}") _localState.value = _localState.value.copy( isRegistering = false, showRegistrationError = true, @@ -153,7 +154,7 @@ class QuickRestoreQrViewModel( parentEventEmitter(RegistrationFlowEvent.ResetState) } is NetworkController.RegisterAccountError.InvalidRequest -> { - Log.w(TAG, "[Register] Invalid request: ${registerResult.error.message}") + Log.w(TAG, "[Register] Invalid request: ${error.message}") _localState.value = _localState.value.copy( isRegistering = false, showRegistrationError = true, @@ -162,16 +163,16 @@ class QuickRestoreQrViewModel( } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[Register] Network error.", registerResult.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[Register] Network error.", registerResult.networkError) _localState.value = _localState.value.copy( isRegistering = false, showRegistrationError = true, errorMessage = null ) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[Register] Application error.", registerResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[Register] Application error.", registerResult.cause) _localState.value = _localState.value.copy( isRegistering = false, showRegistrationError = true, diff --git a/feature/registration/src/main/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModel.kt b/feature/registration/src/main/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModel.kt index 0f5edd4204..7532912769 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModel.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import org.signal.core.util.logging.Log +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationFlowState @@ -115,26 +116,26 @@ class VerificationCodeViewModel( val result = repository.submitVerificationCode(sessionMetadata.id, code) sessionMetadata = when (result) { - is NetworkController.RegistrationNetworkResult.Success -> { - result.data + is RequestResult.Success -> { + result.result } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode -> { - Log.w(TAG, "[SubmitCode] Invalid sessionId or verification code entered. This is distinct from an *incorrect* verification code. Body: ${result.error.message}") + Log.w(TAG, "[SubmitCode] Invalid sessionId or verification code entered. This is distinct from an *incorrect* verification code. Body: ${error.message}") val newAttempts = state.incorrectCodeAttempts + 1 return state.copy(oneTimeEvent = OneTimeEvent.IncorrectVerificationCode, incorrectCodeAttempts = newAttempts) } is NetworkController.SubmitVerificationCodeError.SessionNotFound -> { - Log.w(TAG, "[SubmitCode] Session not found: ${result.error.message}") + Log.w(TAG, "[SubmitCode] Session not found: ${error.message}") // TODO don't start over, go back to phone number entry parentEventEmitter(RegistrationFlowEvent.ResetState) return state } is NetworkController.SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested -> { - if (result.error.session.verified) { + if (error.session.verified) { Log.i(TAG, "[SubmitCode] Session already had number verified, continuing with registration.") - result.error.session + error.session } else { Log.w(TAG, "[SubmitCode] No code was requested for this session? Need to have user re-submit.") parentEventEmitter.navigateBack() @@ -142,17 +143,17 @@ class VerificationCodeViewModel( } } is NetworkController.SubmitVerificationCodeError.RateLimited -> { - Log.w(TAG, "[SubmitCode] Rate limited (retryAfter: ${result.error.retryAfter}).") - return state.copy(oneTimeEvent = OneTimeEvent.RateLimited(result.error.retryAfter)) + Log.w(TAG, "[SubmitCode] Rate limited (retryAfter: ${error.retryAfter}).") + return state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[SubmitCode] Network error.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[SubmitCode] Network error.", result.networkError) return state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[SubmitCode] Unknown error when submitting verification code.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[SubmitCode] Unknown error when submitting verification code.", result.cause) return state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -169,8 +170,8 @@ class VerificationCodeViewModel( val registerResult = repository.registerAccountWithSession(e164 = state.e164, sessionId = sessionMetadata.id, skipDeviceTransfer = true) return when (registerResult) { - is NetworkController.RegistrationNetworkResult.Success -> { - val (response, keyMaterial) = registerResult.data + is RequestResult.Success -> { + val (response, keyMaterial) = registerResult.result parentEventEmitter(RegistrationFlowEvent.Registered(keyMaterial.accountEntropyPool)) @@ -181,8 +182,8 @@ class VerificationCodeViewModel( } state } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (registerResult.error) { + is RequestResult.NonSuccess -> { + when (val error = registerResult.error) { is NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified -> { // TODO [registration] Handle session not found or not verified case. throw NotImplementedError("Handle session not found or not verified case.") @@ -196,33 +197,33 @@ class VerificationCodeViewModel( Log.w(TAG, "[Register] Reglocked.") parentEventEmitter.navigateTo( RegistrationRoute.PinEntryForRegistrationLock( - timeRemaining = registerResult.error.data.timeRemaining, - svrCredentials = registerResult.error.data.svr2Credentials + timeRemaining = error.data.timeRemaining, + svrCredentials = error.data.svr2Credentials ) ) state } is NetworkController.RegisterAccountError.RateLimited -> { - Log.w(TAG, "[Register] Rate limited (retryAfter: ${registerResult.error.retryAfter}).") - state.copy(oneTimeEvent = OneTimeEvent.RateLimited(registerResult.error.retryAfter)) + Log.w(TAG, "[Register] Rate limited (retryAfter: ${error.retryAfter}).") + state.copy(oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter)) } is NetworkController.RegisterAccountError.InvalidRequest -> { - Log.w(TAG, "[Register] Invalid request when registering account: ${registerResult.error.message}") + Log.w(TAG, "[Register] Invalid request when registering account: ${error.message}") state.copy(oneTimeEvent = OneTimeEvent.RegistrationError) } is NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect -> { - Log.w(TAG, "[Register] Got told the registration recovery password incorrect. We don't use the RRP in this flow, and should never get this error. Resetting. Message: ${registerResult.error.message}") + Log.w(TAG, "[Register] Got told the registration recovery password incorrect. We don't use the RRP in this flow, and should never get this error. Resetting. Message: ${error.message}") parentEventEmitter(RegistrationFlowEvent.ResetState) state } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[Register] Network error.", registerResult.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[Register] Network error.", registerResult.networkError) state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[Register] Unknown error when registering account.", registerResult.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[Register] Unknown error when registering account.", registerResult.cause) state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } @@ -244,71 +245,71 @@ class VerificationCodeViewModel( ) return when (result) { - is NetworkController.RegistrationNetworkResult.Success -> { + is RequestResult.Success -> { Log.i(TAG, "[RequestCode][$transport] Successfully requested verification code.") - parentEventEmitter(RegistrationFlowEvent.SessionUpdated(result.data)) + parentEventEmitter(RegistrationFlowEvent.SessionUpdated(result.result)) state.copy( - sessionMetadata = result.data, - rateLimits = computeRateLimits(result.data) + sessionMetadata = result.result, + rateLimits = computeRateLimits(result.result) ) } - is NetworkController.RegistrationNetworkResult.Failure -> { - when (result.error) { + is RequestResult.NonSuccess -> { + when (val error = result.error) { is NetworkController.RequestVerificationCodeError.InvalidRequest -> { - Log.w(TAG, "[RequestCode][$transport] Invalid request: ${result.error.message}") + Log.w(TAG, "[RequestCode][$transport] Invalid request: ${error.message}") state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } is NetworkController.RequestVerificationCodeError.RateLimited -> { - Log.w(TAG, "[RequestCode][$transport] Rate limited (retryAfter: ${result.error.retryAfter}).") - parentEventEmitter(RegistrationFlowEvent.SessionUpdated(result.error.session)) + Log.w(TAG, "[RequestCode][$transport] Rate limited (retryAfter: ${error.retryAfter}).") + parentEventEmitter(RegistrationFlowEvent.SessionUpdated(error.session)) state.copy( - oneTimeEvent = OneTimeEvent.RateLimited(result.error.retryAfter), - sessionMetadata = result.error.session, - rateLimits = computeRateLimits(result.error.session) + oneTimeEvent = OneTimeEvent.RateLimited(error.retryAfter), + sessionMetadata = error.session, + rateLimits = computeRateLimits(error.session) ) } is NetworkController.RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport -> { Log.w(TAG, "[RequestCode][$transport] Could not fulfill with requested transport.") - parentEventEmitter(RegistrationFlowEvent.SessionUpdated(result.error.session)) + parentEventEmitter(RegistrationFlowEvent.SessionUpdated(error.session)) state.copy( oneTimeEvent = OneTimeEvent.CouldNotRequestCodeWithSelectedTransport, - sessionMetadata = result.error.session, - rateLimits = computeRateLimits(result.error.session) + sessionMetadata = error.session, + rateLimits = computeRateLimits(error.session) ) } is NetworkController.RequestVerificationCodeError.InvalidSessionId -> { - Log.w(TAG, "[RequestCode][$transport] Invalid session ID: ${result.error.message}") + Log.w(TAG, "[RequestCode][$transport] Invalid session ID: ${error.message}") // TODO don't start over, go back to phone number entry parentEventEmitter(RegistrationFlowEvent.ResetState) state } is NetworkController.RequestVerificationCodeError.MissingRequestInformationOrAlreadyVerified -> { Log.w(TAG, "[RequestCode][$transport] Missing request information or already verified.") - parentEventEmitter(RegistrationFlowEvent.SessionUpdated(result.error.session)) + parentEventEmitter(RegistrationFlowEvent.SessionUpdated(error.session)) state.copy( oneTimeEvent = OneTimeEvent.NetworkError, - sessionMetadata = result.error.session, - rateLimits = computeRateLimits(result.error.session) + sessionMetadata = error.session, + rateLimits = computeRateLimits(error.session) ) } is NetworkController.RequestVerificationCodeError.SessionNotFound -> { - Log.w(TAG, "[RequestCode][$transport] Session not found: ${result.error.message}") + Log.w(TAG, "[RequestCode][$transport] Session not found: ${error.message}") // TODO don't start over, go back to phone number entry parentEventEmitter(RegistrationFlowEvent.ResetState) state } is NetworkController.RequestVerificationCodeError.ThirdPartyServiceError -> { - Log.w(TAG, "[RequestCode][$transport] Third party service error. ${result.error.data}") + Log.w(TAG, "[RequestCode][$transport] Third party service error. ${error.data}") state.copy(oneTimeEvent = OneTimeEvent.ThirdPartyError) } } } - is NetworkController.RegistrationNetworkResult.NetworkError -> { - Log.w(TAG, "[RequestCode][$transport] Network error.", result.exception) + is RequestResult.RetryableNetworkError -> { + Log.w(TAG, "[RequestCode][$transport] Network error.", result.networkError) state.copy(oneTimeEvent = OneTimeEvent.NetworkError) } - is NetworkController.RegistrationNetworkResult.ApplicationError -> { - Log.w(TAG, "[RequestCode][$transport] Unknown application error.", result.exception) + is RequestResult.ApplicationError -> { + Log.w(TAG, "[RequestCode][$transport] Unknown application error.", result.cause) state.copy(oneTimeEvent = OneTimeEvent.UnknownError) } } diff --git a/feature/registration/src/test/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModelTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModelTest.kt index 8ed7297566..52c5fd97a7 100644 --- a/feature/registration/src/test/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModelTest.kt +++ b/feature/registration/src/test/java/org/signal/registration/screens/phonenumber/PhoneNumberEntryViewModelTest.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test +import org.signal.libsignal.net.RequestResult import org.signal.registration.KeyMaterial import org.signal.registration.NetworkController import org.signal.registration.PreExistingRegistrationData @@ -276,9 +277,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -306,7 +307,7 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = listOf("captcha")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -331,7 +332,7 @@ class PhoneNumberEntryViewModelTest { @Test fun `PhoneNumberSubmitted handles rate limiting from createSession`() = runTest { coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.CreateSessionError.RateLimited(60.seconds) ) @@ -355,7 +356,7 @@ class PhoneNumberEntryViewModelTest { @Test fun `PhoneNumberSubmitted handles invalid request from createSession`() = runTest { coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.CreateSessionError.InvalidRequest("Bad request") ) @@ -376,7 +377,7 @@ class PhoneNumberEntryViewModelTest { @Test fun `PhoneNumberSubmitted handles network error`() = runTest { coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -395,7 +396,7 @@ class PhoneNumberEntryViewModelTest { @Test fun `PhoneNumberSubmitted handles application error`() = runTest { coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected error")) + RequestResult.ApplicationError(RuntimeException("Unexpected error")) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -421,7 +422,7 @@ class PhoneNumberEntryViewModelTest { ) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(existingSession) + RequestResult.Success(existingSession) viewModel.applyEvent(initialState, PhoneNumberEntryScreenEvents.PhoneNumberSubmitted, parentEventEmitter, stateEmitter) @@ -444,9 +445,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata() coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.RateLimited(30.seconds, sessionMetadata) ) @@ -469,9 +470,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata() coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.SessionNotFound("Session expired") ) @@ -495,9 +496,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata() coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(sessionMetadata) ) @@ -520,9 +521,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata() coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.ThirdPartyServiceError( NetworkController.ThirdPartyServiceErrorResponse("Provider error", false) ) @@ -550,12 +551,12 @@ class PhoneNumberEntryViewModelTest { val sessionAfterPushChallenge = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) coEvery { mockRepository.awaitPushChallengeToken() } returns "test-push-challenge-token" coEvery { mockRepository.submitPushChallengeToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionAfterPushChallenge) + RequestResult.Success(sessionAfterPushChallenge) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionAfterPushChallenge) + RequestResult.Success(sessionAfterPushChallenge) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -586,10 +587,10 @@ class PhoneNumberEntryViewModelTest { val sessionWithPushChallenge = createSessionMetadata(requestedInformation = listOf("pushChallenge")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) coEvery { mockRepository.awaitPushChallengeToken() } returns null coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -620,14 +621,14 @@ class PhoneNumberEntryViewModelTest { val sessionWithPushChallenge = createSessionMetadata(requestedInformation = listOf("pushChallenge")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) coEvery { mockRepository.awaitPushChallengeToken() } returns "test-push-challenge-token" coEvery { mockRepository.submitPushChallengeToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.UpdateSessionError.RejectedUpdate("Invalid token") ) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -655,12 +656,12 @@ class PhoneNumberEntryViewModelTest { val sessionWithPushChallenge = createSessionMetadata(requestedInformation = listOf("pushChallenge")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) coEvery { mockRepository.awaitPushChallengeToken() } returns "test-push-challenge-token" coEvery { mockRepository.submitPushChallengeToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Connection lost")) + RequestResult.RetryableNetworkError(java.io.IOException("Connection lost")) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -688,12 +689,12 @@ class PhoneNumberEntryViewModelTest { val sessionWithPushChallenge = createSessionMetadata(requestedInformation = listOf("pushChallenge")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) coEvery { mockRepository.awaitPushChallengeToken() } returns "test-push-challenge-token" coEvery { mockRepository.submitPushChallengeToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected error")) + RequestResult.ApplicationError(RuntimeException("Unexpected error")) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -722,10 +723,10 @@ class PhoneNumberEntryViewModelTest { val sessionAfterPushChallenge = createSessionMetadata(requestedInformation = listOf("captcha")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithPushChallenge) + RequestResult.Success(sessionWithPushChallenge) coEvery { mockRepository.awaitPushChallengeToken() } returns "test-push-challenge-token" coEvery { mockRepository.submitPushChallengeToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionAfterPushChallenge) + RequestResult.Success(sessionAfterPushChallenge) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -756,9 +757,9 @@ class PhoneNumberEntryViewModelTest { val initialState = PhoneNumberEntryState(sessionMetadata = sessionMetadata) coEvery { mockRepository.submitCaptchaToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) viewModel.applyEvent(initialState, PhoneNumberEntryScreenEvents.CaptchaCompleted("captcha-token"), parentEventEmitter, stateEmitter) @@ -787,7 +788,7 @@ class PhoneNumberEntryViewModelTest { val initialState = PhoneNumberEntryState(sessionMetadata = sessionWithCaptcha) coEvery { mockRepository.submitCaptchaToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionWithCaptcha) + RequestResult.Success(sessionWithCaptcha) viewModel.applyEvent(initialState, PhoneNumberEntryScreenEvents.CaptchaCompleted("captcha-token"), parentEventEmitter, stateEmitter) @@ -804,7 +805,7 @@ class PhoneNumberEntryViewModelTest { val initialState = PhoneNumberEntryState(sessionMetadata = sessionMetadata) coEvery { mockRepository.submitCaptchaToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.UpdateSessionError.RateLimited(45.seconds, sessionMetadata) ) @@ -823,7 +824,7 @@ class PhoneNumberEntryViewModelTest { val initialState = PhoneNumberEntryState(sessionMetadata = sessionMetadata) coEvery { mockRepository.submitCaptchaToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.UpdateSessionError.RejectedUpdate("Invalid captcha") ) @@ -839,7 +840,7 @@ class PhoneNumberEntryViewModelTest { val initialState = PhoneNumberEntryState(sessionMetadata = sessionMetadata) coEvery { mockRepository.submitCaptchaToken(any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Connection lost")) + RequestResult.RetryableNetworkError(java.io.IOException("Connection lost")) viewModel.applyEvent(initialState, PhoneNumberEntryScreenEvents.CaptchaCompleted("captcha-token"), parentEventEmitter, stateEmitter) @@ -898,7 +899,7 @@ class PhoneNumberEntryViewModelTest { val registerResponse = createRegisterAccountResponse(storageCapable = true) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(registerResponse to keyMaterial) + RequestResult.Success(registerResponse to keyMaterial) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -925,7 +926,7 @@ class PhoneNumberEntryViewModelTest { val registerResponse = createRegisterAccountResponse(storageCapable = false) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(registerResponse to keyMaterial) + RequestResult.Success(registerResponse to keyMaterial) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -950,7 +951,7 @@ class PhoneNumberEntryViewModelTest { } coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified("Not found") ) @@ -974,7 +975,7 @@ class PhoneNumberEntryViewModelTest { } coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.DeviceTransferPossible ) @@ -1003,7 +1004,7 @@ class PhoneNumberEntryViewModelTest { ) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationLock(registrationLockData) ) @@ -1030,7 +1031,7 @@ class PhoneNumberEntryViewModelTest { } coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RateLimited(30.seconds) ) @@ -1057,13 +1058,13 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.InvalidRequest("Bad request") ) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1088,13 +1089,13 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect("Wrong password") ) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1116,7 +1117,7 @@ class PhoneNumberEntryViewModelTest { } coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(IOException("Network error")) + RequestResult.RetryableNetworkError(IOException("Network error")) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1137,7 +1138,7 @@ class PhoneNumberEntryViewModelTest { } coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1159,9 +1160,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1192,7 +1193,7 @@ class PhoneNumberEntryViewModelTest { ) coEvery { mockRepository.checkSvrCredentials(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(checkResponse) + RequestResult.Success(checkResponse) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1221,11 +1222,11 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.checkSvrCredentials(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(checkResponse) + RequestResult.Success(checkResponse) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1250,11 +1251,11 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.checkSvrCredentials(any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(IOException("Network error")) + RequestResult.RetryableNetworkError(IOException("Network error")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1279,11 +1280,11 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.checkSvrCredentials(any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1307,13 +1308,13 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.checkSvrCredentials(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.CheckSvrCredentialsError.InvalidRequest("Bad request") ) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1337,13 +1338,13 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.checkSvrCredentials(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.CheckSvrCredentialsError.Unauthorized ) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", @@ -1364,9 +1365,9 @@ class PhoneNumberEntryViewModelTest { val sessionMetadata = createSessionMetadata(requestedInformation = emptyList()) coEvery { mockRepository.createSession(any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) val initialState = PhoneNumberEntryState( countryCode = "1", diff --git a/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModelTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModelTest.kt index b7db543478..a5b9bc9618 100644 --- a/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModelTest.kt +++ b/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForRegistrationLockViewModelTest.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.signal.core.models.MasterKey +import org.signal.libsignal.net.RequestResult import org.signal.registration.KeyMaterial import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent @@ -73,9 +74,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(registerResponse to keyMaterial) + RequestResult.Success(registerResponse to keyMaterial) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -94,7 +95,7 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RestoreMasterKeyError.WrongPin(triesRemaining) ) @@ -109,7 +110,7 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RestoreMasterKeyError.NoDataFound ) @@ -129,7 +130,7 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -142,7 +143,7 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -161,7 +162,7 @@ class PinEntryForRegistrationLockViewModelTest { ) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -181,7 +182,7 @@ class PinEntryForRegistrationLockViewModelTest { ) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -199,9 +200,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationLock(registrationLockData) ) @@ -219,9 +220,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RateLimited(retryAfter) ) @@ -241,9 +242,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.InvalidRequest("Bad request") ) @@ -260,9 +261,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.DeviceTransferPossible ) @@ -279,9 +280,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -296,9 +297,9 @@ class PinEntryForRegistrationLockViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.RegistrationLock) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = true) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithSession(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) diff --git a/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModelTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModelTest.kt index 40463f9bda..1ab177392f 100644 --- a/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModelTest.kt +++ b/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSmsBypassViewModelTest.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.signal.core.models.MasterKey +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationFlowState @@ -70,9 +71,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(mockk(relaxed = true)) + RequestResult.Success(mockk(relaxed = true)) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -90,9 +91,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(mockk(relaxed = true)) + RequestResult.Success(mockk(relaxed = true)) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -105,7 +106,7 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RestoreMasterKeyError.WrongPin(triesRemaining) ) @@ -120,7 +121,7 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RestoreMasterKeyError.NoDataFound ) @@ -136,7 +137,7 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.NetworkError(IOException("Network error")) + RequestResult.RetryableNetworkError(IOException("Network error")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -149,7 +150,7 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -175,9 +176,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(IOException("Network error")) + RequestResult.RetryableNetworkError(IOException("Network error")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -192,9 +193,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -209,9 +210,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.DeviceTransferPossible ) @@ -228,9 +229,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.InvalidRequest("Bad request") ) @@ -249,9 +250,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RateLimited(retryAfter) ) @@ -272,14 +273,14 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) // First call (without reglock) returns RegistrationLock error, second call (with reglock) succeeds coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), registrationLock = null, any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationLock(registrationLockData) ) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), registrationLock = any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(mockk(relaxed = true)) + RequestResult.Success(mockk(relaxed = true)) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -298,10 +299,10 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) // Both calls (with and without reglock) return RegistrationLock error coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationLock(registrationLockData) ) @@ -320,9 +321,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect("Wrong password") ) @@ -340,9 +341,9 @@ class PinEntryForSmsBypassViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SmsBypass, e164 = "+15551234567") coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) coEvery { mockRepository.registerAccountWithRecoveryPassword(any(), any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.SessionNotFoundOrNotVerified("Not found") ) diff --git a/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModelTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModelTest.kt index 6f32985dda..2c72d7e816 100644 --- a/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModelTest.kt +++ b/feature/registration/src/test/java/org/signal/registration/screens/pinentry/PinEntryForSvrRestoreViewModelTest.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.signal.core.models.MasterKey +import org.signal.libsignal.net.RequestResult import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent import org.signal.registration.RegistrationFlowState @@ -65,9 +66,9 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Success(svrCredentials) + RequestResult.Success(svrCredentials) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Success(NetworkController.MasterKeyResponse(masterKey)) + RequestResult.Success(NetworkController.MasterKeyResponse(masterKey)) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -86,7 +87,7 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.GetSvrCredentialsError.NoServiceCredentialsAvailable ) @@ -101,7 +102,7 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.GetSvrCredentialsError.Unauthorized ) @@ -116,7 +117,7 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -129,7 +130,7 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -149,9 +150,9 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Success(svrCredentials) + RequestResult.Success(svrCredentials) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RestoreMasterKeyError.WrongPin(triesRemaining) ) @@ -170,9 +171,9 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Success(svrCredentials) + RequestResult.Success(svrCredentials) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RestoreMasterKeyError.NoDataFound ) @@ -194,9 +195,9 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Success(svrCredentials) + RequestResult.Success(svrCredentials) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) @@ -213,9 +214,9 @@ class PinEntryForSvrRestoreViewModelTest { val initialState = PinEntryState(mode = PinEntryState.Mode.SvrRestore) coEvery { mockRepository.getSvrCredentials() } returns - NetworkController.RegistrationNetworkResult.Success(svrCredentials) + RequestResult.Success(svrCredentials) coEvery { mockRepository.restoreMasterKeyFromSvr(any(), any(), any(), forRegistrationLock = false) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, PinEntryScreenEvents.PinEntered("123456"), parentEventEmitter, stateEmitter) diff --git a/feature/registration/src/test/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModelTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModelTest.kt index aea3de272c..03df4c6591 100644 --- a/feature/registration/src/test/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModelTest.kt +++ b/feature/registration/src/test/java/org/signal/registration/screens/verificationcode/VerificationCodeViewModelTest.kt @@ -20,6 +20,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Ignore import org.junit.Test +import org.signal.libsignal.net.RequestResult import org.signal.registration.KeyMaterial import org.signal.registration.NetworkController import org.signal.registration.RegistrationFlowEvent @@ -186,7 +187,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode("Wrong code") ) @@ -230,9 +231,9 @@ class VerificationCodeViewModelTest { val keyMaterial = mockk(relaxed = true) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(registerResponse to keyMaterial) + RequestResult.Success(registerResponse to keyMaterial) viewModel.applyEvent(initialState, VerificationCodeScreenEvents.CodeEntered("123456"), stateEmitter) @@ -253,7 +254,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.SubmitVerificationCodeError.InvalidSessionIdOrVerificationCode("Wrong code") ) @@ -275,7 +276,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.SubmitVerificationCodeError.SessionNotFound("Session expired") ) @@ -297,11 +298,11 @@ class VerificationCodeViewModelTest { val keyMaterial = mockk(relaxed = true) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested(verifiedSession) ) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(registerResponse to keyMaterial) + RequestResult.Success(registerResponse to keyMaterial) viewModel.applyEvent(initialState, VerificationCodeScreenEvents.CodeEntered("123456"), stateEmitter) @@ -322,7 +323,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.SubmitVerificationCodeError.SessionAlreadyVerifiedOrNoCodeRequested(unverifiedSession) ) @@ -341,7 +342,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.SubmitVerificationCodeError.RateLimited(60.seconds, sessionMetadata) ) @@ -366,7 +367,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent( initialState, @@ -386,7 +387,7 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent( initialState, @@ -409,9 +410,9 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.DeviceTransferPossible ) @@ -431,9 +432,9 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RateLimited(30.seconds) ) @@ -459,9 +460,9 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.InvalidRequest("Bad request") ) @@ -484,9 +485,9 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RegisterAccountError.RegistrationRecoveryPasswordIncorrect("Wrong password") ) @@ -509,9 +510,9 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent( initialState, @@ -532,9 +533,9 @@ class VerificationCodeViewModelTest { ) coEvery { mockRepository.submitVerificationCode(any(), any()) } returns - NetworkController.RegistrationNetworkResult.Success(sessionMetadata) + RequestResult.Success(sessionMetadata) coEvery { mockRepository.registerAccountWithSession(any(), any(), any()) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent( initialState, @@ -565,7 +566,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Success(updatedSession) + RequestResult.Success(updatedSession) viewModel.applyEvent(initialState, VerificationCodeScreenEvents.ResendSms, stateEmitter) @@ -578,7 +579,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.RateLimited(45.seconds, sessionMetadata) ) @@ -596,7 +597,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.InvalidRequest("Bad request") ) @@ -611,7 +612,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(sessionMetadata) ) @@ -626,7 +627,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.InvalidSessionId("Invalid session") ) @@ -642,7 +643,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.SessionNotFound("Session not found") ) @@ -658,7 +659,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.MissingRequestInformationOrAlreadyVerified(sessionMetadata) ) @@ -673,7 +674,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.ThirdPartyServiceError( NetworkController.ThirdPartyServiceErrorResponse("Provider error", false) ) @@ -690,7 +691,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.NetworkError(java.io.IOException("Network error")) + RequestResult.RetryableNetworkError(java.io.IOException("Network error")) viewModel.applyEvent(initialState, VerificationCodeScreenEvents.ResendSms, stateEmitter) @@ -703,7 +704,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.SMS)) } returns - NetworkController.RegistrationNetworkResult.ApplicationError(RuntimeException("Unexpected")) + RequestResult.ApplicationError(RuntimeException("Unexpected")) viewModel.applyEvent(initialState, VerificationCodeScreenEvents.ResendSms, stateEmitter) @@ -730,7 +731,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.VOICE)) } returns - NetworkController.RegistrationNetworkResult.Success(updatedSession) + RequestResult.Success(updatedSession) viewModel.applyEvent(initialState, VerificationCodeScreenEvents.CallMe, stateEmitter) @@ -743,7 +744,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.VOICE)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.RateLimited(90.seconds, sessionMetadata) ) @@ -761,7 +762,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.VOICE)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.CouldNotFulfillWithRequestedTransport(sessionMetadata) ) @@ -776,7 +777,7 @@ class VerificationCodeViewModelTest { val initialState = VerificationCodeState(sessionMetadata = sessionMetadata) coEvery { mockRepository.requestVerificationCode(any(), any(), eq(NetworkController.VerificationCodeTransport.VOICE)) } returns - NetworkController.RegistrationNetworkResult.Failure( + RequestResult.NonSuccess( NetworkController.RequestVerificationCodeError.ThirdPartyServiceError( NetworkController.ThirdPartyServiceErrorResponse("Voice provider error", true) )