diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
index fdeb3e45..6308117b 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
@@ -19,6 +19,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
+import android.widget.Toast.LENGTH_LONG
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.IdRes
@@ -1208,26 +1209,21 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricAu
changeStatusBarState(isEmulatorSettings())
/** Biometric stuff for users without accounts **/
- val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_enabled_key), false)
+ val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_key), false)
val noAccounts = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false) || accounts.count() <= 1
if (isTruePhone() && authEnabled && noAccounts) {
if (deviceHasPasswordPinLock(this)) {
- startBiometricAuthentication(this,
- R.string.biometric_authentication_title,
- false
- )
+ startBiometricAuthentication(this, R.string.biometric_authentication_title, false)
BiometricAuthenticator.promptInfo?.let {
- BiometricAuthenticator.biometricPrompt?.authenticate(
- it
- )
+ BiometricAuthenticator.biometricPrompt?.authenticate(it)
}
// hide background while authenticating, Sorry moms & dads 🙏
binding?.navHostFragment?.isInvisible = true
} else {
- showToast(R.string.phone_not_secured, Toast.LENGTH_LONG)
+ showToast(R.string.phone_not_secured, LENGTH_LONG)
}
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt
index 2bb4746b..c6e1e1fe 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt
@@ -47,7 +47,7 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
)
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
- val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_enabled_key), false)
+ val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_key), false)
val skipStartup = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false
) || accounts.count() <= 1
@@ -57,11 +57,8 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
if (isTruePhone() && authEnabled) {
if (deviceHasPasswordPinLock(this)) {
- startBiometricAuthentication(
- this,
- R.string.biometric_authentication_title,
- false
- )
+ startBiometricAuthentication(this, R.string.biometric_authentication_title, false)
+
BiometricAuthenticator.promptInfo?.let {
BiometricAuthenticator.biometricPrompt?.authenticate(it)
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt
index aa5a3182..d04757da 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt
@@ -13,6 +13,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceFragmentCompat
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
+import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.AccountManagmentBinding
@@ -32,7 +33,10 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSet
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setPaddingBottom
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setToolBarScrollFlags
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
+import com.lagradost.cloudstream3.utils.AppUtils.html
+import com.lagradost.cloudstream3.utils.BackupUtils
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
+import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogText
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.setImage
@@ -256,6 +260,19 @@ class SettingsAccount : PreferenceFragmentCompat() {
hideKeyboard()
setPreferencesFromResource(R.xml.settings_account, rootKey)
+ getPref(R.string.biometric_key)?.setOnPreferenceClickListener {
+
+ BackupUtils.backup(activity)
+ val title = activity?.getString(R.string.biometric_setting)
+ val warning = activity?.getString(R.string.biometric_warning)
+ activity?.showBottomDialogText(
+ title as String,
+ warning.html()
+ ) { onDialogDismissedEvent }
+
+ true
+ }
+
val syncApis =
listOf(
R.string.mal_key to malApi,
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/BackupUtils.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/BackupUtils.kt
index e50131fe..db001ef5 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/BackupUtils.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/BackupUtils.kt
@@ -66,6 +66,7 @@ object BackupUtils {
OPEN_SUBTITLES_USER_KEY,
"nginx_user", // Nginx user key
+ "biometric_key" // can lock down users if backup is shared on a incompatible device
)
/** false if blacklisted key */
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt
index 96e73cd3..de9b9963 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt
@@ -5,7 +5,6 @@ import android.app.KeyguardManager
import android.content.Context
import android.os.Build
import android.util.Log
-import android.widget.Toast.LENGTH_SHORT
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
@@ -41,9 +40,10 @@ object BiometricAuthenticator {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
- showToast("$errString", LENGTH_SHORT)
+ showToast("$errString")
Log.e(TAG, "$errorCode")
failedAttempts++
+
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
failedAttempts = 0
activity.finish()
@@ -70,6 +70,7 @@ object BiometricAuthenticator {
})
}
+ @Suppress("DEPRECATION")
// authentication dialog prompt builder
private fun authenticationDialog(
activity: Activity,
@@ -77,6 +78,7 @@ object BiometricAuthenticator {
setDeviceCred: Boolean,
) {
val description = activity.getString(R.string.biometric_prompt_description)
+
if (setDeviceCred) {
// For API level > 30, Newer API setAllowedAuthenticators is used
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -87,17 +89,18 @@ object BiometricAuthenticator {
.setDescription(description)
.setAllowedAuthenticators(authFlag)
.build()
+
} else {
- @Suppress("DEPRECATION")
+ // for apis < 30
promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString(title))
.setDescription(description)
.setDeviceCredentialAllowed(true)
.build()
}
+
} else {
// fallback for A12+ when both fingerprint & Face unlock is absent but PIN is set
- @Suppress("DEPRECATION")
promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString(title))
.setDescription(description)
@@ -107,9 +110,11 @@ object BiometricAuthenticator {
}
private fun isBiometricHardWareAvailable(): Boolean {
+ // authentication occurs only when this is true and device is truly capable
var result = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+
when (biometricManager?.canAuthenticate(
DEVICE_CREDENTIAL or BIOMETRIC_STRONG or BIOMETRIC_WEAK
)) {
@@ -121,6 +126,7 @@ object BiometricAuthenticator {
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> result = true
BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> result = false
}
+
} else {
@Suppress("DEPRECATION")
when (biometricManager?.canAuthenticate()) {
@@ -137,7 +143,7 @@ object BiometricAuthenticator {
return result
}
- // checks if device is secured or not
+ // checks if device is secured i.e has at least some type of lock
fun deviceHasPasswordPinLock(context: Context?): Boolean {
val keyMgr =
context?.getSystemService(AppCompatActivity.KEYGUARD_SERVICE) as? KeyguardManager
@@ -160,7 +166,7 @@ object BiometricAuthenticator {
promptInfo?.let { biometricPrompt?.authenticate(it) }
} else {
- showToast(R.string.biometric_unsupported, LENGTH_SHORT)
+ showToast(R.string.biometric_unsupported)
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 79b3c813..244095ba 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -747,11 +747,13 @@
Unlock CloudStream
- Fingerprint sensor authentication
- biometric_key
+ Fingerprint/Face unlock authentication
+ biometric_key
Password/PIN Authentication
Biometric authentication is not supported on this device
Please disable fingerprint authentication if device has no lock.
This window will close after few failed attempts. You\'ll have to restart the App.
-
+ Your CloudStream data has been backed up now, although probability of this rare case is very low but all
+ devices behave differently, in case you get locked down from accessing the app in worst case scenario,
+ Clear the app data wholly and restore the backup. Any inconvenience if arrived is deeply regretted.
diff --git a/app/src/main/res/xml/settings_account.xml b/app/src/main/res/xml/settings_account.xml
index d0316f96..39e21162 100644
--- a/app/src/main/res/xml/settings_account.xml
+++ b/app/src/main/res/xml/settings_account.xml
@@ -24,7 +24,7 @@
android:title="@string/skip_startup_account_select_pref" />