[fenix] For https://github.com/mozilla-mobile/fenix/issues/2395 - Properly takes you back to where you start authentication on completion
parent
7de8f59fde
commit
3a4015a02d
@ -0,0 +1,67 @@
|
||||
package org.mozilla.fenix.components.features
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.concept.engine.EngineSession
|
||||
import mozilla.components.concept.engine.request.RequestInterceptor
|
||||
import mozilla.components.service.fxa.manager.FxaAccountManager
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class FirefoxAccountsAuthFeature(
|
||||
private val accountManager: FxaAccountManager,
|
||||
private val redirectUrl: String,
|
||||
private val coroutineContext: CoroutineContext = Dispatchers.Main
|
||||
) {
|
||||
fun beginAuthentication(context: Context) {
|
||||
beginAuthenticationAsync(context) {
|
||||
accountManager.beginAuthenticationAsync().await()
|
||||
}
|
||||
}
|
||||
|
||||
fun beginPairingAuthentication(context: Context, pairingUrl: String) {
|
||||
beginAuthenticationAsync(context) {
|
||||
accountManager.beginAuthenticationAsync(pairingUrl).await()
|
||||
}
|
||||
}
|
||||
|
||||
private fun beginAuthenticationAsync(context: Context, beginAuthentication: suspend () -> String?) {
|
||||
CoroutineScope(coroutineContext).launch {
|
||||
// FIXME return a fallback URL provided by Config...
|
||||
// https://github.com/mozilla-mobile/android-components/issues/2496
|
||||
val authUrl = beginAuthentication() ?: "https://accounts.firefox.com/signin"
|
||||
|
||||
// TODO
|
||||
// We may fail to obtain an authentication URL, for example due to transient network errors.
|
||||
// If that happens, open up a fallback URL in order to present some kind of a "no network"
|
||||
// UI to the user.
|
||||
// It's possible that the underlying problem will go away by the time the tab actually
|
||||
// loads, resulting in a confusing experience.
|
||||
val intent = SupportUtils.createCustomTabIntent(context, authUrl)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
val interceptor = object : RequestInterceptor {
|
||||
override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? {
|
||||
if (uri.startsWith(redirectUrl)) {
|
||||
val parsedUri = Uri.parse(uri)
|
||||
val code = parsedUri.getQueryParameter("code")
|
||||
|
||||
if (code != null) {
|
||||
val state = parsedUri.getQueryParameter("state") as String
|
||||
|
||||
// Notify the state machine about our success.
|
||||
accountManager.finishAuthenticationAsync(code, state)
|
||||
|
||||
return RequestInterceptor.InterceptionResponse.Url(redirectUrl)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue