Don't complete onboarding on registration error (#2646)

- Add specific error if the app encounters a HTTP 404 response during onboarding registration, because that means the mobile_app integration is missing
 - After an error, clean up the session data to make sure a new registration attempt is made
This commit is contained in:
Joris Pelgröm 2022-07-01 03:58:24 +02:00 committed by GitHub
parent aa256676c4
commit 7b401abddc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 28 deletions

View file

@ -26,6 +26,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException
import javax.inject.Inject import javax.inject.Inject
import javax.net.ssl.SSLException import javax.net.ssl.SSLException
import javax.net.ssl.SSLHandshakeException import javax.net.ssl.SSLHandshakeException
@ -145,15 +146,24 @@ class LaunchActivity : AppCompatActivity(), LaunchView {
) )
} catch (e: Exception) { } catch (e: Exception) {
// Fatal errors: if one of these calls fail, the app cannot proceed. // Fatal errors: if one of these calls fail, the app cannot proceed.
// Because this runs after the webview, the only expected errors are system // Show an error, clean up the session and require new registration.
// version related in OkHttp (cryptography), or general connection issues (offline/unknown). // Because this runs after the webview, the only expected errors are:
// - missing mobile_app integration
// - system version related in OkHttp (cryptography)
// - general connection issues (offline/unknown)
Log.e(TAG, "Exception while registering", e) Log.e(TAG, "Exception while registering", e)
try {
authenticationRepository.revokeSession()
} catch (e: Exception) {
Log.e(TAG, "Can't revoke session", e)
}
AlertDialog.Builder(this@LaunchActivity) AlertDialog.Builder(this@LaunchActivity)
.setTitle(commonR.string.error_connection_failed) .setTitle(commonR.string.error_connection_failed)
.setMessage( .setMessage(
when (e) { when {
is SSLHandshakeException -> commonR.string.webview_error_FAILED_SSL_HANDSHAKE e is HttpException && e.code() == 404 -> commonR.string.error_with_registration
is SSLException -> commonR.string.webview_error_SSL_INVALID e is SSLHandshakeException -> commonR.string.webview_error_FAILED_SSL_HANDSHAKE
e is SSLException -> commonR.string.webview_error_SSL_INVALID
else -> commonR.string.webview_error else -> commonR.string.webview_error
} }
) )

View file

@ -94,13 +94,13 @@ class IntegrationRepositoryImpl @Inject constructor(
Log.e(TAG, "Unable to register device due to missing URL") Log.e(TAG, "Unable to register device due to missing URL")
return return
} }
try {
val response = val response =
integrationService.registerDevice( integrationService.registerDevice(
url.newBuilder().addPathSegments("api/mobile_app/registrations").build(), url.newBuilder().addPathSegments("api/mobile_app/registrations").build(),
authenticationRepository.buildBearerToken(), authenticationRepository.buildBearerToken(),
request request
) )
try {
persistDeviceRegistration(deviceRegistration) persistDeviceRegistration(deviceRegistration)
urlRepository.saveRegistrationUrls( urlRepository.saveRegistrationUrls(
response.cloudhookUrl, response.cloudhookUrl,
@ -109,7 +109,7 @@ class IntegrationRepositoryImpl @Inject constructor(
) )
localStorage.putString(PREF_SECRET, response.secret) localStorage.putString(PREF_SECRET, response.secret)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unable to register device", e) Log.e(TAG, "Unable to save device registration", e)
} }
} }

View file

@ -193,7 +193,7 @@
<string name="error_loading_entities">Error loading entities</string> <string name="error_loading_entities">Error loading entities</string>
<string name="error_onboarding_connection_failed">Unable to connect to Home Assistant.</string> <string name="error_onboarding_connection_failed">Unable to connect to Home Assistant.</string>
<string name="error_ssl">Unable to communicate with Home Assistant because of a SSL error. Please ensure your certificate is valid.</string> <string name="error_ssl">Unable to communicate with Home Assistant because of a SSL error. Please ensure your certificate is valid.</string>
<string name="error_with_registration">Please check to ensure you have the mobile_app\nintegration enabled on your home assistant instance.</string> <string name="error_with_registration">The \'Mobile App\' integration is required to use the app, but it is not available on your Home Assistant server. Please check your server configuration and try again.</string>
<string name="errors">Errors</string> <string name="errors">Errors</string>
<string name="event_error">Failed to notify HA of picked option.</string> <string name="event_error">Failed to notify HA of picked option.</string>
<string name="exit">Exit</string> <string name="exit">Exit</string>

View file

@ -109,6 +109,7 @@ class PhoneSettingsListener : WearableListenerService(), DataClient.OnDataChange
} }
private fun login(dataMap: DataMap) = mainScope.launch { private fun login(dataMap: DataMap) = mainScope.launch {
try {
val url = dataMap.getString("URL") val url = dataMap.getString("URL")
val authCode = dataMap.getString("AuthCode") val authCode = dataMap.getString("AuthCode")
val deviceName = dataMap.getString("DeviceName") val deviceName = dataMap.getString("DeviceName")
@ -123,11 +124,14 @@ class PhoneSettingsListener : WearableListenerService(), DataClient.OnDataChange
) )
) )
sendPhoneData()
val intent = HomeActivity.newInstance(applicationContext) val intent = HomeActivity.newInstance(applicationContext)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent) startActivity(intent)
} catch (e: Exception) {
Log.e(TAG, "Unable to login to Home Assistant", e)
}
sendPhoneData()
} }
private fun saveFavorites(dataMap: DataMap) { private fun saveFavorites(dataMap: DataMap) {