@@ -48,6 +48,7 @@ import androidx.core.widget.doAfterTextChanged
4848import eu.opencloud.android.BuildConfig
4949import eu.opencloud.android.MainApp.Companion.accountType
5050import eu.opencloud.android.R
51+ import eu.opencloud.android.data.authentication.KEY_OIDC_ISSUER
5152import eu.opencloud.android.data.authentication.KEY_PREFERRED_USERNAME
5253import eu.opencloud.android.data.authentication.KEY_USER_ID
5354import eu.opencloud.android.databinding.AccountSetupBinding
@@ -59,7 +60,6 @@ import eu.opencloud.android.domain.exceptions.OpencloudVersionNotSupportedExcept
5960import eu.opencloud.android.domain.exceptions.SSLErrorCode
6061import eu.opencloud.android.domain.exceptions.SSLErrorException
6162import eu.opencloud.android.domain.exceptions.ServerNotReachableException
62- import eu.opencloud.android.domain.exceptions.StateMismatchException
6363import eu.opencloud.android.domain.exceptions.UnauthorizedException
6464import eu.opencloud.android.domain.server.model.ServerInfo
6565import eu.opencloud.android.extensions.checkPasscodeEnforced
@@ -312,7 +312,13 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
312312 authenticationViewModel.accountDiscovery.observe(this ) {
313313 if (it.peekContent() is UIResult .Success ) {
314314 notifyDocumentsProviderRoots(applicationContext)
315- launchFileDisplayActivity()
315+ if (authenticationViewModel.launchedFromDeepLink ||
316+ (isTaskRoot && accountAuthenticatorResponse == null )
317+ ) {
318+ launchFileDisplayActivity()
319+ } else {
320+ finish()
321+ }
316322 } else {
317323 binding.authStatusText.run {
318324 text = context.getString(R .string.login_account_preparing)
@@ -559,10 +565,17 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
559565 resultBundle = intent.extras
560566 setResult(Activity .RESULT_OK , intent)
561567
568+ val account = Account (accountName, contextProvider.getString(R .string.account_type))
569+ val am = AccountManager .get(this )
570+
562571 // Store preferred_username from id_token for login_hint on re-login
563- preferredUsername?.let { prefUsername ->
564- val account = Account (accountName, contextProvider.getString(R .string.account_type))
565- AccountManager .get(this ).setUserData(account, KEY_PREFERRED_USERNAME , prefUsername)
572+ preferredUsername?.let { am.setUserData(account, KEY_PREFERRED_USERNAME , it) }
573+
574+ // Store OIDC issuer from webfinger so AccountAuthenticator can do OIDC discovery
575+ // against the correct IDP (not the cloud server which may proxy stale config)
576+ val serverInfo = authenticationViewModel.serverInfo.value?.peekContent()?.getStoredData()
577+ if (serverInfo is ServerInfo .OIDCServer ) {
578+ am.setUserData(account, KEY_OIDC_ISSUER , serverInfo.oidcServerConfiguration.issuer)
566579 }
567580
568581 authenticationViewModel.discoverAccount(accountName = accountName, discoveryNeeded = loginAction == ACTION_CREATE )
@@ -686,6 +699,10 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
686699 super .onNewIntent(intent)
687700 intent?.let {
688701 Timber .d(" onNewIntent received with data: ${it.data} " )
702+ if (! ::binding.isInitialized) {
703+ Timber .w(" onNewIntent received before binding initialized, ignoring OAuth response" )
704+ return
705+ }
689706 setIntent(it)
690707 handleGetAuthorizationCodeResponse(it)
691708 }
@@ -696,8 +713,9 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
696713 val state = intent.data?.getQueryParameter(" state" )
697714
698715 if (state != authenticationViewModel.oidcState) {
699- Timber .e(" OAuth request to get authorization code failed. State mismatching, maybe somebody is trying a CSRF attack." )
700- updateOAuthStatusIconAndText(StateMismatchException ())
716+ Timber .e(" OAuth: state mismatch (expected=${authenticationViewModel.oidcState} , got=$state ). Finishing." )
717+ showMessageInSnackbar(message = getString(R .string.auth_oauth_error))
718+ finish()
701719 } else {
702720 if (authorizationCode != null ) {
703721 Timber .d(" Authorization code received [$authorizationCode ]. Let's exchange it for access token" )
@@ -996,6 +1014,10 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
9961014 }
9971015
9981016 private fun updateOAuthStatusIconAndText (authorizationException : Throwable ? ) {
1017+ if (! ::binding.isInitialized) {
1018+ Timber .w(" updateOAuthStatusIconAndText called before binding initialized, ignoring" )
1019+ return
1020+ }
9991021 binding.serverStatusText.run {
10001022 setCompoundDrawablesWithIntrinsicBounds(R .drawable.common_error, 0 , 0 , 0 )
10011023 text =
0 commit comments