auth: lets keep an eye on microG bundle uninstall

This commit is contained in:
Rahul Patel
2026-05-11 22:21:23 +05:30
parent 2ff098317e
commit 53aff0e24f
6 changed files with 64 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
/*
* SPDX-FileCopyrightText: 2026 Aurora OSS
* SPDX-FileCopyrightText: 2025 The Calyx Institute
* SPDX-License-Identifier: GPL-3.0-or-later
*/
@@ -8,7 +9,10 @@ package com.aurora.store.compose.navigation
import android.content.Intent
import androidx.activity.compose.LocalActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
import androidx.navigation.NavDeepLinkBuilder
import androidx.navigation3.runtime.NavKey
@@ -16,6 +20,10 @@ import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
import androidx.navigation3.ui.NavDisplay
import com.aurora.Constants.PACKAGE_NAME_GMS
import com.aurora.extensions.toast
import com.aurora.store.AuroraApp
import com.aurora.store.ComposeActivity
import com.aurora.store.MainActivity
import com.aurora.store.R
import com.aurora.store.compose.ui.about.AboutScreen
@@ -33,6 +41,11 @@ import com.aurora.store.compose.ui.onboarding.OnboardingScreen
import com.aurora.store.compose.ui.preferences.installation.InstallerScreen
import com.aurora.store.compose.ui.search.SearchScreen
import com.aurora.store.compose.ui.spoof.SpoofScreen
import com.aurora.store.data.event.InstallerEvent
import com.aurora.store.data.model.AccountType
import com.aurora.store.data.providers.AccountProvider
import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences
/**
* Navigation display for compose screens
@@ -58,6 +71,36 @@ fun NavDisplay(startDestination: NavKey) {
if (backstack.size == 1) activity?.finish() else backstack.removeLastOrNull()
}
val context = LocalContext.current
fun isMicroGAuthInvalidated(): Boolean =
Preferences.getBoolean(context, Preferences.PREFERENCE_AUTH_VIA_MICROG, false) &&
AccountProvider.getAccountType(context) == AccountType.GOOGLE &&
!PackageUtil.hasSupportedMicroGVariant(context)
fun handleMicroGRemoved() {
context.toast(R.string.microg_removed_auth_warning)
AccountProvider.logout(context)
val intent = Intent(context, ComposeActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
}
// Check every time the screen resumes in case microG was removed while Aurora was in background.
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
if (isMicroGAuthInvalidated()) handleMicroGRemoved()
}
// Also react immediately if the GMS package is uninstalled while Aurora is in the foreground.
LaunchedEffect(Unit) {
AuroraApp.events.installerEvent.collect { event ->
if (event is InstallerEvent.Uninstalled && event.packageName == PACKAGE_NAME_GMS) {
if (isMicroGAuthInvalidated()) handleMicroGRemoved()
}
}
}
NavDisplay(
backStack = backstack,
entryDecorators = listOf(

View File

@@ -80,5 +80,6 @@ object AccountProvider {
Preferences.remove(context, Constants.ACCOUNT_EMAIL_PLAIN)
Preferences.remove(context, Constants.ACCOUNT_AAS_PLAIN)
Preferences.remove(context, Constants.ACCOUNT_AUTH_PLAIN)
Preferences.remove(context, Preferences.PREFERENCE_AUTH_VIA_MICROG)
}
}

View File

@@ -48,6 +48,7 @@ object Preferences {
const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO"
const val PREFERENCE_MICROG_AUTH = "PREFERENCE_MICROG_AUTH"
const val PREFERENCE_AUTH_VIA_MICROG = "PREFERENCE_AUTH_VIA_MICROG"
const val PREFERENCE_DISPENSER_URLS = "PREFERENCE_DISPENSER_URLS"
const val PREFERENCE_VENDING_VERSION = "PREFERENCE_VENDING_VERSION"

View File

@@ -35,6 +35,7 @@ import com.aurora.store.data.model.AuthState
import com.aurora.store.data.providers.AccountProvider
import com.aurora.store.data.providers.AuthProvider
import com.aurora.store.util.AC2DMTask
import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -171,13 +172,26 @@ class AuthViewModel @Inject constructor(
_authState.value = AuthState.Verifying
if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) {
authProvider.saveAuthData(authData)
val tokenType =
if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS
AccountProvider.login(
context,
authData.email,
authData.aasToken.ifBlank { authData.authToken },
if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS,
authData.aasToken.ifBlank {
authData.authToken
},
tokenType,
accountType
)
// Record whether this Google session relies on microG's AccountManager so we
// can warn the user if microG is later uninstalled.
Preferences.putBoolean(
context,
Preferences.PREFERENCE_AUTH_VIA_MICROG,
accountType == AccountType.GOOGLE &&
tokenType == AuthHelper.Token.AUTH &&
PackageUtil.hasSupportedMicroGVariant(context)
)
_authState.value = AuthState.SignedIn
} else {
authProvider.removeAuthData(context)

View File

@@ -16,6 +16,7 @@ import com.aurora.extensions.TAG
import com.aurora.extensions.requiresGMS
import com.aurora.gplayapi.data.models.App
import com.aurora.gplayapi.data.models.Review
import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
import com.aurora.gplayapi.data.models.details.TestingProgramStatus
import com.aurora.gplayapi.helpers.AppDetailsHelper
import com.aurora.gplayapi.helpers.ReviewsHelper
@@ -41,6 +42,7 @@ import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_EXTENDED
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -54,8 +56,6 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import org.json.JSONObject
import javax.inject.Inject
import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
@HiltViewModel
class AppDetailsViewModel @Inject constructor(