Merge pull request #8463 from vector-im/dla/feature/always_allow_signout

Always allow users sign out
This commit is contained in:
Benoit Marty 2023-06-01 14:55:39 +02:00 committed by GitHub
commit f741c4e7d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 20 deletions

1
changelog.d/4855.bugfix Normal file
View file

@ -0,0 +1 @@
Fix: Allow users to sign out even if the sign out request fails.

View file

@ -328,6 +328,9 @@
<string name="backup">Back up</string> <string name="backup">Back up</string>
<string name="sign_out_bottom_sheet_will_lose_secure_messages">Youll lose access to your encrypted messages unless you back up your keys before signing out.</string> <string name="sign_out_bottom_sheet_will_lose_secure_messages">Youll lose access to your encrypted messages unless you back up your keys before signing out.</string>
<string name="sign_out_failed_dialog_message">Cannot reach the homeserver. If you sign out anyway, this device will not be erased from your device list, you may want to remove it using another client.</string>
<string name="sign_out_anyway">Sign out anyway</string>
<!-- splash screen accessibility --> <!-- splash screen accessibility -->
<string name="loading">Loading…</string> <string name="loading">Loading…</string>

View file

@ -37,6 +37,7 @@ interface SignOutService {
/** /**
* Sign out, and release the session, clear all the session data, including crypto data. * Sign out, and release the session, clear all the session data, including crypto data.
* @param signOutFromHomeserver true if the sign out request has to be done * @param signOutFromHomeserver true if the sign out request has to be done
* @param ignoreServerRequestError true to ignore server error if any
*/ */
suspend fun signOut(signOutFromHomeserver: Boolean) suspend fun signOut(signOutFromHomeserver: Boolean, ignoreServerRequestError: Boolean = false)
} }

View file

@ -35,7 +35,12 @@ internal class DefaultSignOutService @Inject constructor(
sessionParamsStore.updateCredentials(credentials) sessionParamsStore.updateCredentials(credentials)
} }
override suspend fun signOut(signOutFromHomeserver: Boolean) { override suspend fun signOut(signOutFromHomeserver: Boolean, ignoreServerRequestError: Boolean) {
return signOutTask.execute(SignOutTask.Params(signOutFromHomeserver)) return signOutTask.execute(
SignOutTask.Params(
signOutFromHomeserver = signOutFromHomeserver,
ignoreServerRequestError = ignoreServerRequestError
)
)
} }
} }

View file

@ -30,7 +30,8 @@ import javax.inject.Inject
internal interface SignOutTask : Task<SignOutTask.Params, Unit> { internal interface SignOutTask : Task<SignOutTask.Params, Unit> {
data class Params( data class Params(
val signOutFromHomeserver: Boolean val signOutFromHomeserver: Boolean,
val ignoreServerRequestError: Boolean,
) )
} }
@ -59,7 +60,9 @@ internal class DefaultSignOutTask @Inject constructor(
// Ignore // Ignore
Timber.w("Ignore error due to https://github.com/matrix-org/synapse/issues/5755") Timber.w("Ignore error due to https://github.com/matrix-org/synapse/issues/5755")
} else { } else {
throw throwable if (!params.ignoreServerRequestError) {
throw throwable
}
} }
} }
} }

View file

@ -60,6 +60,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.failure.GlobalError
import org.matrix.android.sdk.api.session.Session
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -262,18 +263,7 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
} }
} }
args.clearCredentials -> { args.clearCredentials -> {
lifecycleScope.launch { signout(session, onboardingStore, ignoreServerError = false)
try {
session.signOutService().signOut(!args.isUserLoggedOut)
} catch (failure: Throwable) {
displayError(failure)
return@launch
}
Timber.w("SIGN_OUT: success, start app")
activeSessionHolder.clearActiveSession()
doLocalCleanup(clearPreferences = true, onboardingStore)
startNextActivityAndFinish()
}
} }
args.clearCache -> { args.clearCache -> {
lifecycleScope.launch { lifecycleScope.launch {
@ -286,6 +276,26 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
} }
} }
private fun signout(
session: Session,
onboardingStore: VectorSessionStore,
ignoreServerError: Boolean,
) {
lifecycleScope.launch {
try {
session.signOutService().signOut(!args.isUserLoggedOut, ignoreServerError)
} catch (failure: Throwable) {
Timber.e(failure, "SIGN_OUT: error, propose to sign out anyway")
displaySignOutFailedDialog(session, onboardingStore)
return@launch
}
Timber.w("SIGN_OUT: success, start app")
activeSessionHolder.clearActiveSession()
doLocalCleanup(clearPreferences = true, onboardingStore)
startNextActivityAndFinish()
}
}
override fun handleInvalidToken(globalError: GlobalError.InvalidToken) { override fun handleInvalidToken(globalError: GlobalError.InvalidToken) {
// No op here // No op here
Timber.w("Ignoring invalid token global error") Timber.w("Ignoring invalid token global error")
@ -313,12 +323,20 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
} }
} }
private fun displayError(failure: Throwable) { private fun displaySignOutFailedDialog(
session: Session,
onboardingStore: VectorSessionStore,
) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) { if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
MaterialAlertDialogBuilder(this) MaterialAlertDialogBuilder(this)
.setTitle(R.string.dialog_title_error) .setTitle(R.string.dialog_title_error)
.setMessage(errorFormatter.toHumanReadable(failure)) .setMessage(R.string.sign_out_failed_dialog_message)
.setPositiveButton(R.string.global_retry) { _, _ -> doCleanUp() } .setPositiveButton(R.string.sign_out_anyway) { _, _ ->
signout(session, onboardingStore, ignoreServerError = true)
}
.setNeutralButton(R.string.global_retry) { _, _ ->
signout(session, onboardingStore, ignoreServerError = false)
}
.setNegativeButton(R.string.action_cancel) { _, _ -> startNextActivityAndFinish(ignoreClearCredentials = true) } .setNegativeButton(R.string.action_cancel) { _, _ -> startNextActivityAndFinish(ignoreClearCredentials = true) }
.setCancelable(false) .setCancelable(false)
.show() .show()