Skip to content

Commit 2cf81b1

Browse files
author
UserGreen
committed
feat(auth): prompt relogin when restored session has no CSRF token
A session restored from a persisted access token on cold start never passes through login or refresh, so no CSRF token is ever set and every mutating request fails with a 403. On launch for a signed-in session, try to re-establish CSRF via a refresh; if that is not possible, tell the user the session is broken and to log in again.
1 parent 0db1508 commit 2cf81b1

16 files changed

Lines changed: 43 additions & 0 deletions

File tree

app/src/main/kotlin/org/astermail/android/auth/AuthRepository.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,15 @@ class AuthRepository @Inject constructor(
487487
return true
488488
}
489489

490+
suspend fun ensure_csrf_ready(): Boolean {
491+
if (!_is_signed_in.value) return true
492+
if (api_client.get_csrf() != null) return true
493+
return when (try_refresh_session()) {
494+
RefreshOutcome.Success -> api_client.get_csrf() != null
495+
RefreshOutcome.AuthFailed, RefreshOutcome.Transient -> false
496+
}
497+
}
498+
490499
fun has_stored_session(account_id: String): Boolean = session_snapshot_store.has(account_id)
491500

492501
suspend fun change_password(current_password: String, new_password: String): Result<Unit> = runCatching {

app/src/main/kotlin/org/astermail/android/auth/auth_gate_view_model.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,20 @@ package org.astermail.android.auth
2424
import androidx.lifecycle.ViewModel
2525
import androidx.lifecycle.viewModelScope
2626
import android.content.Context
27+
import android.widget.Toast
2728
import dagger.hilt.android.lifecycle.HiltViewModel
2829
import dagger.hilt.android.qualifiers.ApplicationContext
2930
import javax.inject.Inject
3031
import kotlinx.coroutines.CancellationException
32+
import kotlinx.coroutines.Dispatchers
3133
import kotlinx.coroutines.flow.MutableStateFlow
3234
import kotlinx.coroutines.flow.StateFlow
3335
import kotlinx.coroutines.flow.asStateFlow
3436
import kotlinx.coroutines.launch
37+
import kotlinx.coroutines.withContext
3538
import kotlinx.coroutines.withTimeoutOrNull
39+
import org.astermail.android.BuildConfig
40+
import org.astermail.android.R
3641
import org.astermail.android.api.auth.AuthApi
3742
import org.astermail.android.security.LockdownStore
3843

@@ -54,6 +59,21 @@ class AuthGateViewModel @Inject constructor(
5459
}
5560
_is_ready.value = true
5661
if (auth_repository.is_signed_in.value) {
62+
viewModelScope.launch {
63+
val csrf_ok = auth_repository.ensure_csrf_ready()
64+
if (!csrf_ok) {
65+
if (BuildConfig.DEBUG) {
66+
android.util.Log.w("AuthGate", "CSRF token fetch failed on launch")
67+
}
68+
withContext(Dispatchers.Main) {
69+
Toast.makeText(
70+
context,
71+
context.getString(R.string.csrf_unavailable),
72+
Toast.LENGTH_LONG,
73+
).show()
74+
}
75+
}
76+
}
5777
viewModelScope.launch {
5878
try {
5979
val info = withTimeoutOrNull(8_000L) { auth_api.me() }

app/src/main/res/values-ar/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,4 +1281,5 @@
12811281
<string name="pending_deletion_error">تعذّرت استعادة حسابك. يرجى المحاولة مرة أخرى.</string>
12821282
<string name="pending_deletion_restored">مرحبًا بعودتك. تمت استعادة حسابك.</string>
12831283
<string name="image_blocked_placeholder">[تم حظر الصورة]</string>
1284+
<string name="csrf_unavailable">هذه الجلسة معطوبة! يرجى تسجيل الدخول مرة أخرى.</string>
12841285
</resources>

app/src/main/res/values-de/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,4 +1274,5 @@
12741274
<string name="pending_deletion_error">Ihr Konto konnte nicht wiederhergestellt werden. Bitte versuchen Sie es erneut.</string>
12751275
<string name="pending_deletion_restored">Willkommen zurück. Ihr Konto wurde wiederhergestellt.</string>
12761276
<string name="image_blocked_placeholder">[Bild blockiert]</string>
1277+
<string name="csrf_unavailable">Diese Sitzung ist fehlerhaft! Bitte melden Sie sich erneut an.</string>
12771278
</resources>

app/src/main/res/values-es/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,4 +1274,5 @@
12741274
<string name="pending_deletion_error">No se pudo restaurar tu cuenta. Inténtalo de nuevo.</string>
12751275
<string name="pending_deletion_restored">Bienvenido de nuevo. Tu cuenta ha sido restaurada.</string>
12761276
<string name="image_blocked_placeholder">[Imagen bloqueada]</string>
1277+
<string name="csrf_unavailable">¡Esta sesión está dañada! Vuelve a iniciar sesión.</string>
12771278
</resources>

app/src/main/res/values-fr/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,4 +1889,5 @@
18891889
<string name="pending_deletion_error">Impossible de restaurer votre compte. Veuillez réessayer.</string>
18901890
<string name="pending_deletion_restored">Bon retour. Votre compte a été restauré.</string>
18911891
<string name="image_blocked_placeholder">[Image bloquée]</string>
1892+
<string name="csrf_unavailable">Cette session est corrompue ! Veuillez vous reconnecter.</string>
18921893
</resources>

app/src/main/res/values-it/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,4 +1273,5 @@
12731273
<string name="pending_deletion_error">Impossibile ripristinare il tuo account. Riprova.</string>
12741274
<string name="pending_deletion_restored">Bentornato. Il tuo account è stato ripristinato.</string>
12751275
<string name="image_blocked_placeholder">[Immagine bloccata]</string>
1276+
<string name="csrf_unavailable">Questa sessione è danneggiata! Effettua nuovamente l\'accesso.</string>
12761277
</resources>

app/src/main/res/values-ja/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,4 +1271,5 @@
12711271
<string name="pending_deletion_error">アカウントを復元できませんでした。もう一度お試しください。</string>
12721272
<string name="pending_deletion_restored">おかえりなさい。アカウントが復元されました。</string>
12731273
<string name="image_blocked_placeholder">[画像はブロックされました]</string>
1274+
<string name="csrf_unavailable">このセッションは壊れています!もう一度ログインしてください。</string>
12741275
</resources>

app/src/main/res/values-ko/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,4 +1271,5 @@
12711271
<string name="pending_deletion_error">계정을 복원할 수 없습니다. 다시 시도해 주세요.</string>
12721272
<string name="pending_deletion_restored">다시 오신 것을 환영합니다. 계정이 복원되었습니다.</string>
12731273
<string name="image_blocked_placeholder">[이미지 차단됨]</string>
1274+
<string name="csrf_unavailable">이 세션이 손상되었습니다! 다시 로그인해 주세요.</string>
12741275
</resources>

app/src/main/res/values-nl/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,4 +1273,5 @@
12731273
<string name="pending_deletion_error">Kan je account niet herstellen. Probeer het opnieuw.</string>
12741274
<string name="pending_deletion_restored">Welkom terug. Je account is hersteld.</string>
12751275
<string name="image_blocked_placeholder">[Afbeelding geblokkeerd]</string>
1276+
<string name="csrf_unavailable">Deze sessie is beschadigd! Log opnieuw in.</string>
12761277
</resources>

0 commit comments

Comments
 (0)