mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
feat(ui): authenticate first when enabling security settings (#991)
This commit is contained in:
parent
35e38a53ad
commit
22937424fa
7 changed files with 91 additions and 51 deletions
|
@ -154,7 +154,7 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
// Testing
|
// Testing
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
testImplementation("org.json:json:20231013")
|
testImplementation("org.json:json:20240303")
|
||||||
androidTestImplementation("androidx.test:core")
|
androidTestImplementation("androidx.test:core")
|
||||||
implementation("androidx.test.ext:junit-ktx:1.1.5")
|
implementation("androidx.test.ext:junit-ktx:1.1.5")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
|
|
|
@ -135,7 +135,10 @@ import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
|
||||||
import com.lagradost.cloudstream3.utils.BackupUtils.backup
|
import com.lagradost.cloudstream3.utils.BackupUtils.backup
|
||||||
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
|
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.biometricPrompt
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isAuthEnabled
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.promptInfo
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
|
@ -1231,18 +1234,17 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener,
|
||||||
changeStatusBarState(isLayout(EMULATOR))
|
changeStatusBarState(isLayout(EMULATOR))
|
||||||
|
|
||||||
/** Biometric stuff for users without accounts **/
|
/** Biometric stuff for users without accounts **/
|
||||||
val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_key), false)
|
|
||||||
val noAccounts = settingsManager.getBoolean(
|
val noAccounts = settingsManager.getBoolean(
|
||||||
getString(R.string.skip_startup_account_select_key),
|
getString(R.string.skip_startup_account_select_key),
|
||||||
false
|
false
|
||||||
) || accounts.count() <= 1
|
) || accounts.count() <= 1
|
||||||
|
|
||||||
if (isLayout(PHONE) && authEnabled && noAccounts) {
|
if (isLayout(PHONE) && isAuthEnabled(this) && noAccounts) {
|
||||||
if (deviceHasPasswordPinLock(this)) {
|
if (deviceHasPasswordPinLock(this)) {
|
||||||
startBiometricAuthentication(this, R.string.biometric_authentication_title, false)
|
startBiometricAuthentication(this, R.string.biometric_authentication_title, false)
|
||||||
|
|
||||||
BiometricAuthenticator.promptInfo?.let { promt ->
|
promptInfo?.let { prompt ->
|
||||||
BiometricAuthenticator.biometricPrompt?.authenticate(promt)
|
biometricPrompt?.authenticate(prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide background while authenticating, Sorry moms & dads 🙏
|
// hide background while authenticating, Sorry moms & dads 🙏
|
||||||
|
@ -1825,6 +1827,10 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener,
|
||||||
binding?.navHostFragment?.isInvisible = false
|
binding?.navHostFragment?.isInvisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationError() {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
private var backPressedCallback: OnBackPressedCallback? = null
|
private var backPressedCallback: OnBackPressedCallback? = null
|
||||||
|
|
||||||
private fun attachBackPressedCallback() {
|
private fun attachBackPressedCallback() {
|
||||||
|
|
|
@ -23,7 +23,10 @@ import com.lagradost.cloudstream3.ui.settings.Globals.PHONE
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.TV
|
import com.lagradost.cloudstream3.ui.settings.Globals.TV
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
|
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.biometricPrompt
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isAuthEnabled
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.promptInfo
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.accounts
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.accounts
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.selectedKeyIndex
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.selectedKeyIndex
|
||||||
|
@ -48,7 +51,6 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
|
||||||
)
|
)
|
||||||
|
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_key), false)
|
|
||||||
val skipStartup = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false
|
val skipStartup = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false
|
||||||
) || accounts.count() <= 1
|
) || accounts.count() <= 1
|
||||||
|
|
||||||
|
@ -56,7 +58,7 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
|
||||||
|
|
||||||
fun askBiometricAuth() {
|
fun askBiometricAuth() {
|
||||||
|
|
||||||
if (isLayout(PHONE) && authEnabled) {
|
if (isLayout(PHONE) && isAuthEnabled(this)) {
|
||||||
if (deviceHasPasswordPinLock(this)) {
|
if (deviceHasPasswordPinLock(this)) {
|
||||||
startBiometricAuthentication(
|
startBiometricAuthentication(
|
||||||
this,
|
this,
|
||||||
|
@ -64,8 +66,8 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
BiometricAuthenticator.promptInfo?.let { promt ->
|
promptInfo?.let { prompt ->
|
||||||
BiometricAuthenticator.biometricPrompt?.authenticate(promt)
|
biometricPrompt?.authenticate(prompt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,4 +191,8 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
|
||||||
override fun onAuthenticationSuccess() {
|
override fun onAuthenticationSuccess() {
|
||||||
Log.i(BiometricAuthenticator.TAG,"Authentication successful in AccountSelectActivity")
|
Log.i(BiometricAuthenticator.TAG,"Authentication successful in AccountSelectActivity")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationError() {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -12,6 +12,7 @@ import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
|
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
|
||||||
import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
|
import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
|
||||||
|
@ -30,6 +31,7 @@ import com.lagradost.cloudstream3.syncproviders.AuthAPI
|
||||||
import com.lagradost.cloudstream3.syncproviders.InAppAuthAPI
|
import com.lagradost.cloudstream3.syncproviders.InAppAuthAPI
|
||||||
import com.lagradost.cloudstream3.syncproviders.OAuth2API
|
import com.lagradost.cloudstream3.syncproviders.OAuth2API
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR
|
import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.Globals.PHONE
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.TV
|
import com.lagradost.cloudstream3.ui.settings.Globals.TV
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
|
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref
|
||||||
|
@ -38,13 +40,20 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setTool
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||||
import com.lagradost.cloudstream3.utils.BackupUtils
|
import com.lagradost.cloudstream3.utils.BackupUtils
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.authCallback
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.biometricPrompt
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isAuthEnabled
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.promptInfo
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogText
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogText
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||||
|
|
||||||
class SettingsAccount : PreferenceFragmentCompat() {
|
class SettingsAccount : PreferenceFragmentCompat(), BiometricAuthenticator.BiometricAuthCallback {
|
||||||
companion object {
|
companion object {
|
||||||
/** Used by nginx plugin too */
|
/** Used by nginx plugin too */
|
||||||
fun showLoginInfo(
|
fun showLoginInfo(
|
||||||
|
@ -252,6 +261,31 @@ class SettingsAccount : PreferenceFragmentCompat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateAuthPreference(enabled: Boolean) {
|
||||||
|
val biometricKey = getString(R.string.biometric_key)
|
||||||
|
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context ?: return).edit()
|
||||||
|
.putBoolean(biometricKey, enabled).apply()
|
||||||
|
findPreference<SwitchPreferenceCompat>(biometricKey)?.isChecked = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationError() {
|
||||||
|
updateAuthPreference(!isAuthEnabled(context ?: return))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationSuccess() {
|
||||||
|
if (isAuthEnabled(context?: return)) {
|
||||||
|
updateAuthPreference(true)
|
||||||
|
BackupUtils.backup(activity)
|
||||||
|
activity?.showBottomDialogText(
|
||||||
|
getString(R.string.biometric_setting),
|
||||||
|
getString(R.string.biometric_warning).html()
|
||||||
|
) { onDialogDismissedEvent }
|
||||||
|
} else {
|
||||||
|
updateAuthPreference(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
setUpToolbar(R.string.category_account)
|
setUpToolbar(R.string.category_account)
|
||||||
|
@ -263,22 +297,25 @@ class SettingsAccount : PreferenceFragmentCompat() {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
setPreferencesFromResource(R.xml.settings_account, rootKey)
|
setPreferencesFromResource(R.xml.settings_account, rootKey)
|
||||||
|
|
||||||
getPref(R.string.biometric_key)?.setOnPreferenceClickListener {
|
// hide preference on tvs and emulators
|
||||||
val authEnabled = PreferenceManager.getDefaultSharedPreferences(
|
getPref(R.string.biometric_key)?.isEnabled = isLayout(PHONE)
|
||||||
context ?: return@setOnPreferenceClickListener false
|
|
||||||
)
|
|
||||||
.getBoolean(getString(R.string.biometric_key), false)
|
|
||||||
|
|
||||||
if (authEnabled) {
|
getPref(R.string.biometric_key)?.setOnPreferenceClickListener {
|
||||||
BackupUtils.backup(activity)
|
val ctx = context ?: return@setOnPreferenceClickListener false
|
||||||
val title = activity?.getString(R.string.biometric_setting)
|
|
||||||
val warning = activity?.getString(R.string.biometric_warning)
|
if (deviceHasPasswordPinLock(ctx)) {
|
||||||
activity?.showBottomDialogText(
|
startBiometricAuthentication(
|
||||||
title as String,
|
activity?: return@setOnPreferenceClickListener false,
|
||||||
warning.html()
|
R.string.biometric_authentication_title,
|
||||||
) { onDialogDismissedEvent }
|
false
|
||||||
|
)
|
||||||
|
promptInfo?.let {
|
||||||
|
authCallback = this
|
||||||
|
biometricPrompt?.authenticate(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
val syncApis =
|
val syncApis =
|
||||||
|
|
|
@ -12,20 +12,20 @@ import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
|
||||||
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.content.ContextCompat.getString
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
|
|
||||||
object BiometricAuthenticator {
|
object BiometricAuthenticator {
|
||||||
|
|
||||||
|
const val TAG = "cs3Auth"
|
||||||
private const val MAX_FAILED_ATTEMPTS = 3
|
private const val MAX_FAILED_ATTEMPTS = 3
|
||||||
private var failedAttempts = 0
|
private var failedAttempts = 0
|
||||||
const val TAG = "cs3Auth"
|
|
||||||
|
|
||||||
private var biometricManager: BiometricManager? = null
|
private var biometricManager: BiometricManager? = null
|
||||||
var biometricPrompt: BiometricPrompt? = null
|
var biometricPrompt: BiometricPrompt? = null
|
||||||
var promptInfo: BiometricPrompt.PromptInfo? = null
|
var promptInfo: BiometricPrompt.PromptInfo? = null
|
||||||
|
|
||||||
var authCallback: BiometricAuthCallback? = null // listen to authentication success
|
var authCallback: BiometricAuthCallback? = null // listen to authentication success
|
||||||
|
|
||||||
private fun initializeBiometrics(activity: Activity) {
|
private fun initializeBiometrics(activity: Activity) {
|
||||||
|
@ -37,20 +37,12 @@ object BiometricAuthenticator {
|
||||||
activity as FragmentActivity,
|
activity as FragmentActivity,
|
||||||
executor,
|
executor,
|
||||||
object : BiometricPrompt.AuthenticationCallback() {
|
object : BiometricPrompt.AuthenticationCallback() {
|
||||||
|
|
||||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||||
super.onAuthenticationError(errorCode, errString)
|
super.onAuthenticationError(errorCode, errString)
|
||||||
showToast("$errString")
|
showToast("$errString")
|
||||||
Log.e(TAG, "$errorCode")
|
Log.e(TAG, "$errorCode")
|
||||||
failedAttempts++
|
authCallback?.onAuthenticationError()
|
||||||
|
//activity.finish()
|
||||||
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
|
|
||||||
failedAttempts = 0
|
|
||||||
activity.finish()
|
|
||||||
} else {
|
|
||||||
failedAttempts = 0
|
|
||||||
activity.finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||||
|
@ -89,7 +81,6 @@ object BiometricAuthenticator {
|
||||||
.setDescription(description)
|
.setDescription(description)
|
||||||
.setAllowedAuthenticators(authFlag)
|
.setAllowedAuthenticators(authFlag)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// for apis < 30
|
// for apis < 30
|
||||||
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||||
|
@ -98,7 +89,6 @@ object BiometricAuthenticator {
|
||||||
.setDeviceCredentialAllowed(true)
|
.setDeviceCredentialAllowed(true)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// fallback for A12+ when both fingerprint & Face unlock is absent but PIN is set
|
// fallback for A12+ when both fingerprint & Face unlock is absent but PIN is set
|
||||||
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||||
|
@ -114,7 +104,6 @@ object BiometricAuthenticator {
|
||||||
var result = false
|
var result = false
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
|
||||||
when (biometricManager?.canAuthenticate(
|
when (biometricManager?.canAuthenticate(
|
||||||
DEVICE_CREDENTIAL or BIOMETRIC_STRONG or BIOMETRIC_WEAK
|
DEVICE_CREDENTIAL or BIOMETRIC_STRONG or BIOMETRIC_WEAK
|
||||||
)) {
|
)) {
|
||||||
|
@ -126,7 +115,6 @@ object BiometricAuthenticator {
|
||||||
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> result = true
|
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> result = true
|
||||||
BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> result = false
|
BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> result = false
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
when (biometricManager?.canAuthenticate()) {
|
when (biometricManager?.canAuthenticate()) {
|
||||||
|
@ -153,12 +141,11 @@ object BiometricAuthenticator {
|
||||||
// function to start authentication in any fragment or activity
|
// function to start authentication in any fragment or activity
|
||||||
fun startBiometricAuthentication(activity: Activity, title: Int, setDeviceCred: Boolean) {
|
fun startBiometricAuthentication(activity: Activity, title: Int, setDeviceCred: Boolean) {
|
||||||
initializeBiometrics(activity)
|
initializeBiometrics(activity)
|
||||||
|
authCallback = activity as? BiometricAuthCallback
|
||||||
if (isBiometricHardWareAvailable()) {
|
if (isBiometricHardWareAvailable()) {
|
||||||
authCallback = activity as? BiometricAuthCallback
|
authCallback = activity as? BiometricAuthCallback
|
||||||
authenticationDialog(activity, title, setDeviceCred)
|
authenticationDialog(activity, title, setDeviceCred)
|
||||||
promptInfo?.let { biometricPrompt?.authenticate(it) }
|
promptInfo?.let { biometricPrompt?.authenticate(it) }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (deviceHasPasswordPinLock(activity)) {
|
if (deviceHasPasswordPinLock(activity)) {
|
||||||
authCallback = activity as? BiometricAuthCallback
|
authCallback = activity as? BiometricAuthCallback
|
||||||
|
@ -171,7 +158,15 @@ object BiometricAuthenticator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isAuthEnabled(ctx: Context):Boolean {
|
||||||
|
return ctx.let {
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(ctx)
|
||||||
|
.getBoolean(getString(ctx, R.string.biometric_key), false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface BiometricAuthCallback {
|
interface BiometricAuthCallback {
|
||||||
fun onAuthenticationSuccess()
|
fun onAuthenticationSuccess()
|
||||||
|
fun onAuthenticationError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@
|
||||||
<string name="search">Search</string>
|
<string name="search">Search</string>
|
||||||
<string name="library">Library</string>
|
<string name="library">Library</string>
|
||||||
<string name="category_account">Accounts and Security</string>
|
<string name="category_account">Accounts and Security</string>
|
||||||
<string name="category_updates">Updates and backup</string>
|
<string name="category_updates">Updates and Backup</string>
|
||||||
<string name="settings_info">Info</string>
|
<string name="settings_info">Info</string>
|
||||||
<string name="advanced_search">Advanced Search</string>
|
<string name="advanced_search">Advanced Search</string>
|
||||||
<string name="advanced_search_des">Gives you the search results separated by provider</string>
|
<string name="advanced_search_des">Gives you the search results separated by provider</string>
|
||||||
|
@ -611,7 +611,7 @@
|
||||||
<string name="tracks">Tracks</string>
|
<string name="tracks">Tracks</string>
|
||||||
<string name="audio_tracks">Audio tracks</string>
|
<string name="audio_tracks">Audio tracks</string>
|
||||||
<string name="video_tracks">Video tracks</string>
|
<string name="video_tracks">Video tracks</string>
|
||||||
<string name="apply_on_restart">Apply on Restart</string>
|
<string name="apply_on_restart">Restart the app to see changes.</string>
|
||||||
<string name="restart">Restart</string>
|
<string name="restart">Restart</string>
|
||||||
<string name="stop">Stop</string>
|
<string name="stop">Stop</string>
|
||||||
<string name="safe_mode_title">Safe mode on</string>
|
<string name="safe_mode_title">Safe mode on</string>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
@ -6,12 +5,9 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.android.tools.build:gradle:8.2.1")
|
classpath("com.android.tools.build:gradle:8.2.2")
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22")
|
||||||
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.10")
|
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.10")
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
|
||||||
// in the individual module build.gradle.kts files
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +19,7 @@ allprojects {
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.google.devtools.ksp") version "1.9.22-1.0.16" apply false
|
id("com.google.devtools.ksp") version "1.9.22-1.0.17" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<Delete>("clean") {
|
tasks.register<Delete>("clean") {
|
||||||
|
|
Loading…
Reference in a new issue