A revoked device wipes itself
Mirror of the iOS change: a 410 from the poll cancels polling, destroys the vault (Android's sign-out is already a full wipe), and lands on the sign-in screen with a sentence that says what happened and what signing in again means. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
b6557d6409
commit
3ab8e6c641
@@ -1614,9 +1614,20 @@ class MessengerViewModel(app: Application) : AndroidViewModel(app) {
|
||||
if (current != null) {
|
||||
// A story arriving must appear without the user pulling
|
||||
// to refresh; it is filed by `receive()` and read back here.
|
||||
val threads = withContext(Dispatchers.IO) {
|
||||
runCatching { current.receive() }.getOrDefault(emptySet())
|
||||
val received = withContext(Dispatchers.IO) {
|
||||
runCatching { current.receive() }
|
||||
}
|
||||
// 🔴 410 from the poll: this device's registration is gone
|
||||
// — revoked from another phone, or expired by the sweep.
|
||||
// Wipe and sign out with an honest sentence, rather than
|
||||
// hammering a mailbox that no longer exists while sitting
|
||||
// on ciphertext the account's owner asked to be gone.
|
||||
val failure = received.exceptionOrNull()
|
||||
if (failure is RelayException.Http && failure.status == 410) {
|
||||
signOutRevoked()
|
||||
return@launch
|
||||
}
|
||||
val threads = received.getOrDefault(emptySet())
|
||||
// 🔴 **Retry the outbox on every tick.** A message to
|
||||
// somebody with no registered device waits here rather than
|
||||
// being lost or dumped on the sender to remember — see
|
||||
@@ -1705,6 +1716,22 @@ class MessengerViewModel(app: Application) : AndroidViewModel(app) {
|
||||
const val CALL_SETUP_POLL_MS = 1_000L
|
||||
}
|
||||
|
||||
/// The relay said this device was removed. Same teardown as a sign-out —
|
||||
/// which on Android is already a full vault destroy — plus the sentence
|
||||
/// that says what happened and what signing in again means.
|
||||
private fun signOutRevoked() = viewModelScope.launch {
|
||||
polling?.cancel()
|
||||
polling = null
|
||||
session = null
|
||||
withContext(Dispatchers.IO) { runCatching { KeystoreVault.destroy(getApplication()) } }
|
||||
identity = null
|
||||
vault = KeystoreVault.open(getApplication())
|
||||
_phase.value = Phase.SignedOut(
|
||||
error = "This device was removed from the account, so its local "
|
||||
+ "messages were cleared. Signing in again registers it as a "
|
||||
+ "new device.")
|
||||
}
|
||||
|
||||
fun signOut() = viewModelScope.launch {
|
||||
polling?.cancel()
|
||||
polling = null
|
||||
|
||||
Reference in New Issue
Block a user