mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-19 20:29:02 +00:00
remove apple auth for now
This commit is contained in:
parent
ec44f0ac31
commit
5f99154690
7 changed files with 0 additions and 306 deletions
|
|
@ -121,8 +121,6 @@ dependencies {
|
|||
implementation "androidx.compose.ui:ui-tooling:$compose_version"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
|
||||
|
||||
implementation 'com.willowtreeapps:signinwithapplebutton:0.3'
|
||||
|
||||
implementation project(':common')
|
||||
implementation project(':shared')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
package com.habitrpg.android.habitica.helpers
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebResourceResponse
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.habitrpg.android.habitica.BuildConfig
|
||||
|
||||
class SignInWebViewClient(
|
||||
private val attempt: SignInWithAppleService.AuthenticationAttempt,
|
||||
private val callback: (SignInWithAppleResult) -> Unit
|
||||
) : WebViewClient() {
|
||||
|
||||
// for API levels < 24
|
||||
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
|
||||
return isUrlOverridden(view, Uri.parse(url))
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
|
||||
return isUrlOverridden(view, request?.url)
|
||||
}
|
||||
|
||||
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
|
||||
request?.requestHeaders?.let { it["Authorization"] = "Basic " + BuildConfig.STAGING_KEY }
|
||||
return super.shouldInterceptRequest(view, request)
|
||||
}
|
||||
|
||||
private fun isUrlOverridden(view: WebView?, url: Uri?): Boolean {
|
||||
return when {
|
||||
url == null -> {
|
||||
false
|
||||
}
|
||||
url.toString().contains("appleid.apple.com") -> {
|
||||
view?.loadUrl(url.toString())
|
||||
true
|
||||
}
|
||||
(url.toString().contains(attempt.redirectUri) || url.toString().contains("userID")) -> {
|
||||
Log.d("Apple Sign in", "Web view was forwarded to redirect URI")
|
||||
|
||||
val userID = url.getQueryParameter("userID")
|
||||
val apiKey = url.getQueryParameter("key")
|
||||
|
||||
if (userID == null || apiKey == null) {
|
||||
callback(SignInWithAppleResult.Failure(IllegalArgumentException("data not returned")))
|
||||
} else {
|
||||
callback(SignInWithAppleResult.Success(userID, apiKey, url.getQueryParameter("newUser") == "true"))
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SignInWithAppleResult {
|
||||
data class Success(val userID: String, val apiKey: String, val newUser: Boolean) : SignInWithAppleResult()
|
||||
data class Failure(val error: Throwable) : SignInWithAppleResult()
|
||||
object Cancel : SignInWithAppleResult()
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
package com.habitrpg.android.habitica.helpers
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.WebView
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
||||
class SignInWebViewDialogFragment : DialogFragment() {
|
||||
|
||||
companion object {
|
||||
private const val AUTHENTICATION_ATTEMPT_KEY = "authenticationAttempt"
|
||||
private const val WEB_VIEW_KEY = "webView"
|
||||
|
||||
fun newInstance(authenticationAttempt: SignInWithAppleService.AuthenticationAttempt): SignInWebViewDialogFragment {
|
||||
val fragment = SignInWebViewDialogFragment()
|
||||
fragment.arguments = Bundle().apply {
|
||||
putParcelable(AUTHENTICATION_ATTEMPT_KEY, authenticationAttempt)
|
||||
}
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var authenticationAttempt: SignInWithAppleService.AuthenticationAttempt
|
||||
private var callback: ((SignInWithAppleResult) -> Unit)? = null
|
||||
|
||||
private val webViewIfCreated: WebView?
|
||||
get() = view as? WebView
|
||||
|
||||
fun configure(callback: (SignInWithAppleResult) -> Unit) {
|
||||
this.callback = callback
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
authenticationAttempt = arguments?.getParcelable(AUTHENTICATION_ATTEMPT_KEY)!!
|
||||
setStyle(STYLE_NORMAL, R.style.sign_in_with_apple_button_DialogTheme)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
||||
val webView = context?.let {
|
||||
WebView(it).apply {
|
||||
settings.apply {
|
||||
javaScriptEnabled = true
|
||||
javaScriptCanOpenWindowsAutomatically = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
webView?.webViewClient = SignInWebViewClient(authenticationAttempt, ::onCallback)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
savedInstanceState.getBundle(WEB_VIEW_KEY)?.run {
|
||||
webView?.restoreState(this)
|
||||
}
|
||||
} else {
|
||||
webView?.loadUrl(authenticationAttempt.authenticationUri)
|
||||
}
|
||||
|
||||
return webView
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putBundle(
|
||||
WEB_VIEW_KEY,
|
||||
Bundle().apply {
|
||||
webViewIfCreated?.saveState(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
onCallback(SignInWithAppleResult.Cancel)
|
||||
}
|
||||
|
||||
// SignInWithAppleCallback
|
||||
|
||||
private fun onCallback(result: SignInWithAppleResult) {
|
||||
dialog?.dismiss()
|
||||
val callback = callback
|
||||
if (callback == null) {
|
||||
Log.e("Apple Sign in", "Callback is not configured")
|
||||
return
|
||||
}
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
package com.habitrpg.android.habitica.helpers
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
||||
import java.util.UUID
|
||||
|
||||
class SignInWithAppleService(
|
||||
private val fragmentManager: FragmentManager,
|
||||
private val fragmentTag: String,
|
||||
private val configuration: SignInWithAppleConfiguration,
|
||||
private val callback: (SignInWithAppleResult) -> Unit
|
||||
) {
|
||||
|
||||
init {
|
||||
val fragmentIfShown =
|
||||
fragmentManager.findFragmentByTag(fragmentTag) as? SignInWebViewDialogFragment
|
||||
fragmentIfShown?.configure(callback)
|
||||
}
|
||||
|
||||
data class AuthenticationAttempt(
|
||||
val authenticationUri: String,
|
||||
val redirectUri: String,
|
||||
val state: String
|
||||
) : Parcelable {
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readString() ?: "invalid",
|
||||
parcel.readString() ?: "invalid",
|
||||
parcel.readString() ?: "invalid"
|
||||
)
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
parcel.writeString(authenticationUri)
|
||||
parcel.writeString(redirectUri)
|
||||
parcel.writeString(state)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<AuthenticationAttempt> {
|
||||
|
||||
override fun createFromParcel(parcel: Parcel) = AuthenticationAttempt(parcel)
|
||||
|
||||
override fun newArray(size: Int): Array<AuthenticationAttempt?> = arrayOfNulls(size)
|
||||
|
||||
/*
|
||||
The authentication page URI we're creating is based off the URI constructed by Apple's JavaScript SDK,
|
||||
which is why certain fields (like the version, v) are included in the URI construction.
|
||||
|
||||
We have to build this URI ourselves because Apple's behavior in JavaScript is to POST the response,
|
||||
while we need a GET so we can retrieve the authentication code and verify the state
|
||||
merely by intercepting the URL.
|
||||
|
||||
See the Sign In With Apple Javascript SDK for comparison:
|
||||
https://developer.apple.com/documentation/signinwithapplejs/configuring_your_webpage_for_sign_in_with_apple
|
||||
*/
|
||||
fun create(
|
||||
configuration: SignInWithAppleConfiguration,
|
||||
state: String = UUID.randomUUID().toString()
|
||||
): AuthenticationAttempt {
|
||||
val authenticationUri = Uri
|
||||
.parse("https://appleid.apple.com/auth/authorize")
|
||||
.buildUpon().apply {
|
||||
appendQueryParameter("response_type", "code")
|
||||
appendQueryParameter("v", "1.1.6")
|
||||
appendQueryParameter("client_id", configuration.clientId)
|
||||
appendQueryParameter("redirect_uri", configuration.redirectUri)
|
||||
appendQueryParameter("scope", configuration.scope)
|
||||
appendQueryParameter("state", state)
|
||||
appendQueryParameter("response_mode", "form_post")
|
||||
}
|
||||
.build()
|
||||
.toString()
|
||||
|
||||
return AuthenticationAttempt(authenticationUri, configuration.redirectUri, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun show() {
|
||||
val fragment = SignInWebViewDialogFragment.newInstance(AuthenticationAttempt.create(configuration))
|
||||
fragment.configure(callback)
|
||||
fragment.show(fragmentManager, fragmentTag)
|
||||
}
|
||||
}
|
||||
|
|
@ -170,11 +170,6 @@ class LoginActivity : BaseActivity() {
|
|||
binding.backButton.setOnClickListener { backButtonClicked() }
|
||||
binding.forgotPassword.setOnClickListener { onForgotPasswordClicked() }
|
||||
binding.googleLoginButton.setOnClickListener { viewModel.handleGoogleLogin(this, pickAccountResult) }
|
||||
binding.appleLoginButton.setOnClickListener {
|
||||
viewModel.connectApple(supportFragmentManager) {
|
||||
handleAuthResponse(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadTheme(sharedPreferences: SharedPreferences, forced: Boolean) {
|
||||
|
|
|
|||
|
|
@ -177,15 +177,6 @@ class AccountPreferenceFragment :
|
|||
}
|
||||
}
|
||||
}
|
||||
"apple_auth" -> {
|
||||
if (user?.authentication?.hasAppleAuth == true) {
|
||||
disconnect("apple", "Apple")
|
||||
} else {
|
||||
viewModel.connectApple(parentFragmentManager) {
|
||||
viewModel.handleAuthResponse(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
"facebook_auth" -> {
|
||||
if (user?.authentication?.hasFacebookAuth == true) {
|
||||
disconnect("facebook", "Facebook")
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import android.content.SharedPreferences
|
|||
import android.os.Build
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.core.content.edit
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.google.android.gms.auth.GoogleAuthException
|
||||
import com.google.android.gms.auth.GoogleAuthUtil
|
||||
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException
|
||||
|
|
@ -17,20 +16,16 @@ import com.google.android.gms.common.ConnectionResult
|
|||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import com.google.android.gms.common.GooglePlayServicesUtil
|
||||
import com.google.android.gms.common.Scopes
|
||||
import com.habitrpg.android.habitica.BuildConfig
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
||||
import com.habitrpg.android.habitica.helpers.SignInWithAppleResult
|
||||
import com.habitrpg.android.habitica.helpers.SignInWithAppleService
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.common.habitica.helpers.AnalyticsManager
|
||||
import com.habitrpg.common.habitica.helpers.KeyHelper
|
||||
import com.habitrpg.common.habitica.helpers.launchCatching
|
||||
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import javax.inject.Inject
|
||||
|
|
@ -45,30 +40,6 @@ class AuthenticationViewModel @Inject constructor(
|
|||
) {
|
||||
var googleEmail : String? = null
|
||||
|
||||
fun connectApple(fragmentManager : FragmentManager, onSuccess : (UserAuthResponse) -> Unit) {
|
||||
val configuration = SignInWithAppleConfiguration(
|
||||
clientId = BuildConfig.APPLE_AUTH_CLIENT_ID,
|
||||
redirectUri = "${hostConfig.address}/api/v4/user/auth/apple",
|
||||
scope = "name email"
|
||||
)
|
||||
val fragmentTag = "SignInWithAppleButton-SignInWebViewDialogFragment"
|
||||
|
||||
SignInWithAppleService(fragmentManager, fragmentTag, configuration) { result ->
|
||||
when (result) {
|
||||
is SignInWithAppleResult.Success -> {
|
||||
val response = UserAuthResponse()
|
||||
response.id = result.userID
|
||||
response.apiToken = result.apiKey
|
||||
response.newUser = result.newUser
|
||||
onSuccess(response)
|
||||
}
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
|
||||
fun handleGoogleLogin(
|
||||
activity : Activity,
|
||||
pickAccountResult : ActivityResultLauncher<Intent>
|
||||
|
|
|
|||
Loading…
Reference in a new issue