Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b90d6634 authored by Mohammed Althaf T's avatar Mohammed Althaf T 😊
Browse files

Browser: Allow Re-OAuth from notification

parent 12b5fd51
Loading
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -35,10 +35,11 @@ import at.bitfire.davdroid.ui.account.AccountSettingsActivity
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import foundation.e.accountmanager.AccountTypes
import foundation.e.accountmanager.ui.setup.ReOAuthActivity
import foundation.e.accountmanager.utils.AccountHelper
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runInterruptible
import java.io.IOException
import java.io.InterruptedIOException
import java.util.logging.Level
import java.util.logging.Logger
import kotlin.coroutines.cancellation.CancellationException
@@ -191,10 +192,17 @@ class RefreshCollectionsWorker @AssistedInject constructor(
        } catch (e: UnauthorizedException) {
            logger.log(Level.SEVERE, "Not authorized (anymore)", e)
            // notify that we need to re-authenticate in the account settings
            val settingsIntent = Intent(applicationContext, AccountSettingsActivity::class.java)
                .putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account)
            val isOidcAccount = AccountHelper.isOidcAccount(applicationContext, account)
            val (settingsIntent, notificationMessage) = if (isOidcAccount) {
                Intent(applicationContext, ReOAuthActivity::class.java) to
                        applicationContext.getString(R.string.sync_error_authentication_oauth)
            } else {
                Intent(applicationContext, AccountSettingsActivity::class.java) to
                        applicationContext.getString(R.string.sync_error_authentication_failed)
            }
            settingsIntent.putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account)
            notifyRefreshError(
                applicationContext.getString(R.string.sync_error_authentication_failed),
                notificationMessage,
                settingsIntent
            )
            return Result.failure()
+6 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.sync.account.InvalidAccountException
import at.bitfire.synctools.storage.LocalStorageException
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.accountmanager.utils.AccountHelper
import foundation.e.accountmanager.utils.SystemUtils
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.coroutineScope
@@ -755,7 +756,11 @@ abstract class SyncManager<ResourceType: LocalResource<*>, out CollectionType: L
                if (isNetworkAvailable) {
                    syncResult.numAuthExceptions++
                }
                message = context.getString(R.string.sync_error_authentication_failed)
                message = if (AccountHelper.isOidcAccount(context, account)) {
                    context.getString(R.string.sync_error_authentication_oauth)
                } else {
                    context.getString(R.string.sync_error_authentication_failed)
                }

                // persistent session cookie is present. Probably the session is outDated. no need to show the notification
                if (accountSettings.containsPersistentCookie() && accountSettings.noAuthExceptionDetected()) {
+7 −1
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.accountmanager.ui.setup.ReOAuthActivity
import foundation.e.accountmanager.utils.AccountHelper
import okhttp3.HttpUrl
import org.dmfs.tasks.contract.TaskContract
import java.io.IOException
@@ -124,7 +126,11 @@ class SyncNotificationManager @AssistedInject constructor(
        val contentIntent: Intent
        var viewItemAction: NotificationCompat.Action? = null
        if (e is UnauthorizedException) {
            contentIntent = Intent(context, AccountSettingsActivity::class.java)
            contentIntent = if (AccountHelper.isOidcAccount(context, account)) {
                Intent(context, ReOAuthActivity::class.java)
            } else {
                Intent(context, AccountSettingsActivity::class.java)
            }
            contentIntent.putExtra(
                AccountSettingsActivity.EXTRA_ACCOUNT,
                account
+95 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 e Foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 *
 */
package foundation.e.accountmanager.ui.setup

import android.accounts.Account
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.glance.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.account.AccountSettingsActivity
import at.bitfire.davdroid.ui.account.AccountSettingsModel
import dagger.hilt.android.AndroidEntryPoint
import foundation.e.accountmanager.utils.AccountHelper

@AndroidEntryPoint
class ReOAuthActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Retrieve the Account from the Intent
        val account: Account? = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableExtra(AccountSettingsActivity.EXTRA_ACCOUNT, Account::class.java)
        } else {
            @Suppress("DEPRECATION")
            intent.getParcelableExtra(AccountSettingsActivity.EXTRA_ACCOUNT)
        }

        setContent {
            AppTheme {
                if (account != null) {
                    OAuthHandlerScreen(
                        account = account,
                        onFinished = { finish() }
                    )
                } else {
                    finish()
                }
            }
        }
    }
}

@Composable
fun OAuthHandlerScreen(
    account: Account,
    onFinished: () -> Unit,
) {
    val context = LocalContext.current
    val model = hiltViewModel { factory: AccountSettingsModel.Factory ->
        factory.create(account)
    }

    val authRequestContract = rememberLauncherForActivityResult(model.authorizationContract()) { authResponse ->
        if (authResponse != null) {
            model.authenticate(authResponse)

            // Sync after authenticated
            AccountHelper.scheduleSyncWithDelay(context)
        } else {
            model.authCodeFailed()
        }
        onFinished()
    }

    // Auto-launch immediately, no UI shown
    LaunchedEffect(Unit) {
        val request = model.newAuthorizationRequest()
        if (request != null) {
            authRequestContract.launch(request)
        } else {
            onFinished()
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -34,4 +34,6 @@
    <string name="privacy_policy_title_nav">"Privacy Policy"</string>
    <string name="navigation_drawer_open_webcalmanager">Web Calendar Manager</string>
    <string name="legacy_murena_login">Legacy Murena.io</string>

    <string name="sync_error_authentication_oauth">Authentication issue. Tap to sign in again</string>
</resources>
Loading