Loading feature/account/accountmanager/src/main/kotlin/app/k9mail/feature/account/accountmanager/AccountManagerConstants.kt +15 −0 Original line number Diff line number Diff line Loading @@ -26,9 +26,24 @@ object AccountManagerConstants { const val KEY_AUTH_STATE = "auth_state" const val AUTH_TOKEN_TYPE = "oauth2-access-token" const val OPEN_APP_PACKAGE_AFTER_AUTH = "open_app_package_after_auth" const val OPEN_APP_ACTIVITY_AFTER_AUTH = "open_app_activity_after_auth" const val TO_OPEN_AFTER_AUTH_ACTIVITY = "com.fsck.k9.activity.MessageList" const val USERNAME_HINT = "userNameHint" val ACCOUNT_TYPES = listOf(EELO_ACCOUNT_TYPE, GOOGLE_ACCOUNT_TYPE, YAHOO_ACCOUNT_TYPE) private const val ACTION_PREFIX = "foundation.e.accountmanager.account" const val ACCOUNT_CREATION_ACTION = "$ACTION_PREFIX.create" const val ACCOUNT_REMOVAL_ACTION = "android.accounts.action.ACCOUNT_REMOVED" val GOOGLE_DOMAIN_LIST = listOf( ".gmail.com", ".googlemail.com", ".google.com", ) val YAHOO_DOMAIN_LIST = listOf( ".yahoo.com", ) } feature/account/accountmanager/src/main/kotlin/app/k9mail/feature/account/accountmanager/AccountManagerHelper.kt +33 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ package app.k9mail.feature.account.accountmanager import android.accounts.Account import android.accounts.AccountManager import android.annotation.SuppressLint import android.app.Activity import android.content.ContentResolver import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.os.Bundle import app.k9mail.core.common.mail.Protocols import app.k9mail.feature.account.accountmanager.providersxml.DiscoveredServerSettings import app.k9mail.legacy.account.Account.DeletePolicy Loading Loading @@ -52,6 +54,19 @@ object AccountManagerHelper { } ?: accountColors.random() } fun openAccountManager(context: Context, email: String, accountType: String) { val accountManager = AccountManager.get(context) val options = Bundle() options.putString(AccountManagerConstants.OPEN_APP_PACKAGE_AFTER_AUTH, context.packageName) options.putString( AccountManagerConstants.OPEN_APP_ACTIVITY_AFTER_AUTH, AccountManagerConstants.TO_OPEN_AFTER_AUTH_ACTIVITY, ) options.putString(AccountManagerConstants.USERNAME_HINT, email) accountManager.addAccount(accountType, null, null, options, context as Activity?, null, null) } fun getServerSettings(discoveredServerSettings: DiscoveredServerSettings, password: String): ServerSettings? { if (discoveredServerSettings.authType == null || discoveredServerSettings.username == null) return null Loading Loading @@ -298,4 +313,22 @@ object AccountManagerHelper { return Syncable.ACCOUNT_NOT_FOUND } fun getOpenIdAccountTypeByHostName(hostname: String): String? { if (containedInDomain(AccountManagerConstants.GOOGLE_DOMAIN_LIST, hostname)) { return AccountManagerConstants.GOOGLE_ACCOUNT_TYPE } else if (containedInDomain(AccountManagerConstants.YAHOO_DOMAIN_LIST, hostname)) { return AccountManagerConstants.YAHOO_ACCOUNT_TYPE } return null } private fun containedInDomain(domainList: List<String>, hostname: String): Boolean { for (domain in domainList) { if (hostname.lowercase().endsWith(domain)) { return true } } return false } } feature/account/oauth/build.gradle.kts +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ dependencies { implementation(projects.mail.common) implementation(projects.feature.account.common) implementation(projects.feature.account.accountmanager) implementation(libs.appauth) implementation(libs.androidx.compose.material3) Loading feature/account/oauth/src/main/kotlin/app/k9mail/feature/account/oauth/ui/AccountOAuthContent.kt +5 −5 Original line number Diff line number Diff line Loading @@ -11,10 +11,11 @@ import androidx.compose.ui.res.stringResource import app.k9mail.core.ui.compose.designsystem.molecule.ErrorView import app.k9mail.core.ui.compose.designsystem.molecule.LoadingView import app.k9mail.core.ui.compose.theme2.MainTheme import app.k9mail.feature.account.accountmanager.AccountManagerConstants import app.k9mail.feature.account.accountmanager.AccountManagerHelper import app.k9mail.feature.account.oauth.R import app.k9mail.feature.account.oauth.ui.AccountOAuthContract.Event import app.k9mail.feature.account.oauth.ui.AccountOAuthContract.State import app.k9mail.feature.account.oauth.ui.view.GoogleSignInSupportText import app.k9mail.feature.account.oauth.ui.view.SignInView @Composable Loading Loading @@ -43,15 +44,14 @@ internal fun AccountOAuthContent( message = state.error.toResourceString(resources), onRetry = { onEvent(Event.OnRetryClicked) }, ) if (state.isGoogleSignIn) { GoogleSignInSupportText() } } } else { val isAccountManagerOpenIdSignIn = AccountManagerHelper.getOpenIdAccountTypeByHostName( state.hostname) != null SignInView( onSignInClick = { onEvent(Event.SignInClicked) }, isGoogleSignIn = state.isGoogleSignIn, isAccountManagerOpenIdSignIn = isAccountManagerOpenIdSignIn, isEnabled = isEnabled, ) } Loading feature/account/oauth/src/main/kotlin/app/k9mail/feature/account/oauth/ui/AccountOAuthContract.kt +5 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,11 @@ interface AccountOAuthContract { val state: AuthorizationState, ) : Effect object NavigateBack : Effect data class LaunchAccountManagerAuth( val accountType: String, val emailAddress: String, ) : Effect } sealed interface Error { Loading Loading
feature/account/accountmanager/src/main/kotlin/app/k9mail/feature/account/accountmanager/AccountManagerConstants.kt +15 −0 Original line number Diff line number Diff line Loading @@ -26,9 +26,24 @@ object AccountManagerConstants { const val KEY_AUTH_STATE = "auth_state" const val AUTH_TOKEN_TYPE = "oauth2-access-token" const val OPEN_APP_PACKAGE_AFTER_AUTH = "open_app_package_after_auth" const val OPEN_APP_ACTIVITY_AFTER_AUTH = "open_app_activity_after_auth" const val TO_OPEN_AFTER_AUTH_ACTIVITY = "com.fsck.k9.activity.MessageList" const val USERNAME_HINT = "userNameHint" val ACCOUNT_TYPES = listOf(EELO_ACCOUNT_TYPE, GOOGLE_ACCOUNT_TYPE, YAHOO_ACCOUNT_TYPE) private const val ACTION_PREFIX = "foundation.e.accountmanager.account" const val ACCOUNT_CREATION_ACTION = "$ACTION_PREFIX.create" const val ACCOUNT_REMOVAL_ACTION = "android.accounts.action.ACCOUNT_REMOVED" val GOOGLE_DOMAIN_LIST = listOf( ".gmail.com", ".googlemail.com", ".google.com", ) val YAHOO_DOMAIN_LIST = listOf( ".yahoo.com", ) }
feature/account/accountmanager/src/main/kotlin/app/k9mail/feature/account/accountmanager/AccountManagerHelper.kt +33 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ package app.k9mail.feature.account.accountmanager import android.accounts.Account import android.accounts.AccountManager import android.annotation.SuppressLint import android.app.Activity import android.content.ContentResolver import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.os.Bundle import app.k9mail.core.common.mail.Protocols import app.k9mail.feature.account.accountmanager.providersxml.DiscoveredServerSettings import app.k9mail.legacy.account.Account.DeletePolicy Loading Loading @@ -52,6 +54,19 @@ object AccountManagerHelper { } ?: accountColors.random() } fun openAccountManager(context: Context, email: String, accountType: String) { val accountManager = AccountManager.get(context) val options = Bundle() options.putString(AccountManagerConstants.OPEN_APP_PACKAGE_AFTER_AUTH, context.packageName) options.putString( AccountManagerConstants.OPEN_APP_ACTIVITY_AFTER_AUTH, AccountManagerConstants.TO_OPEN_AFTER_AUTH_ACTIVITY, ) options.putString(AccountManagerConstants.USERNAME_HINT, email) accountManager.addAccount(accountType, null, null, options, context as Activity?, null, null) } fun getServerSettings(discoveredServerSettings: DiscoveredServerSettings, password: String): ServerSettings? { if (discoveredServerSettings.authType == null || discoveredServerSettings.username == null) return null Loading Loading @@ -298,4 +313,22 @@ object AccountManagerHelper { return Syncable.ACCOUNT_NOT_FOUND } fun getOpenIdAccountTypeByHostName(hostname: String): String? { if (containedInDomain(AccountManagerConstants.GOOGLE_DOMAIN_LIST, hostname)) { return AccountManagerConstants.GOOGLE_ACCOUNT_TYPE } else if (containedInDomain(AccountManagerConstants.YAHOO_DOMAIN_LIST, hostname)) { return AccountManagerConstants.YAHOO_ACCOUNT_TYPE } return null } private fun containedInDomain(domainList: List<String>, hostname: String): Boolean { for (domain in domainList) { if (hostname.lowercase().endsWith(domain)) { return true } } return false } }
feature/account/oauth/build.gradle.kts +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ dependencies { implementation(projects.mail.common) implementation(projects.feature.account.common) implementation(projects.feature.account.accountmanager) implementation(libs.appauth) implementation(libs.androidx.compose.material3) Loading
feature/account/oauth/src/main/kotlin/app/k9mail/feature/account/oauth/ui/AccountOAuthContent.kt +5 −5 Original line number Diff line number Diff line Loading @@ -11,10 +11,11 @@ import androidx.compose.ui.res.stringResource import app.k9mail.core.ui.compose.designsystem.molecule.ErrorView import app.k9mail.core.ui.compose.designsystem.molecule.LoadingView import app.k9mail.core.ui.compose.theme2.MainTheme import app.k9mail.feature.account.accountmanager.AccountManagerConstants import app.k9mail.feature.account.accountmanager.AccountManagerHelper import app.k9mail.feature.account.oauth.R import app.k9mail.feature.account.oauth.ui.AccountOAuthContract.Event import app.k9mail.feature.account.oauth.ui.AccountOAuthContract.State import app.k9mail.feature.account.oauth.ui.view.GoogleSignInSupportText import app.k9mail.feature.account.oauth.ui.view.SignInView @Composable Loading Loading @@ -43,15 +44,14 @@ internal fun AccountOAuthContent( message = state.error.toResourceString(resources), onRetry = { onEvent(Event.OnRetryClicked) }, ) if (state.isGoogleSignIn) { GoogleSignInSupportText() } } } else { val isAccountManagerOpenIdSignIn = AccountManagerHelper.getOpenIdAccountTypeByHostName( state.hostname) != null SignInView( onSignInClick = { onEvent(Event.SignInClicked) }, isGoogleSignIn = state.isGoogleSignIn, isAccountManagerOpenIdSignIn = isAccountManagerOpenIdSignIn, isEnabled = isEnabled, ) } Loading
feature/account/oauth/src/main/kotlin/app/k9mail/feature/account/oauth/ui/AccountOAuthContract.kt +5 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,11 @@ interface AccountOAuthContract { val state: AuthorizationState, ) : Effect object NavigateBack : Effect data class LaunchAccountManagerAuth( val accountType: String, val emailAddress: String, ) : Effect } sealed interface Error { Loading