mirror of
https://github.com/yogeshpaliyal/KeyPass.git
synced 2026-04-27 15:39:24 -05:00
Merge pull request #183 from yogeshpaliyal/securityFixes
Security fixes
This commit is contained in:
@@ -17,6 +17,8 @@ import com.yogeshpaliyal.keypass.ui.nav.DashboardActivity
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
private const val AUTHENTICATION_RESULT = 707
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AuthenticationActivity : AppCompatActivity() {
|
||||
|
||||
@@ -84,7 +86,9 @@ class AuthenticationActivity : AppCompatActivity() {
|
||||
biometricPrompt.authenticate(promptInfo)
|
||||
|
||||
binding.btnRetry.setOnClickListener {
|
||||
val canAuthentication = biometricManager.canAuthenticate(DEVICE_CREDENTIAL or BIOMETRIC_WEAK or BIOMETRIC_STRONG)
|
||||
val allowedAuths = DEVICE_CREDENTIAL or BIOMETRIC_WEAK or BIOMETRIC_STRONG
|
||||
val canAuthentication =
|
||||
biometricManager.canAuthenticate(allowedAuths)
|
||||
when (canAuthentication) {
|
||||
BiometricManager.BIOMETRIC_SUCCESS -> {
|
||||
Log.d("MY_APP_TAG", "App can authenticate using biometrics.")
|
||||
@@ -93,7 +97,10 @@ class AuthenticationActivity : AppCompatActivity() {
|
||||
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
|
||||
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
|
||||
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
|
||||
Log.e("MY_APP_TAG", "$canAuthentication Biometric features are currently unavailable.")
|
||||
Log.e(
|
||||
"MY_APP_TAG",
|
||||
"$canAuthentication Biometric features are currently unavailable."
|
||||
)
|
||||
// Prompts the user to create credentials that your app accepts.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
|
||||
@@ -102,7 +109,7 @@ class AuthenticationActivity : AppCompatActivity() {
|
||||
BIOMETRIC_STRONG or DEVICE_CREDENTIAL
|
||||
)
|
||||
}
|
||||
startActivityForResult(enrollIntent, 707)
|
||||
startActivityForResult(enrollIntent, AUTHENTICATION_RESULT)
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this,
|
||||
|
||||
@@ -40,23 +40,23 @@ class MySettingsFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
|
||||
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
||||
when (preference.key) {
|
||||
return when (preference.key) {
|
||||
"feedback" -> {
|
||||
context?.email(
|
||||
getString(R.string.feedback_to_keypass),
|
||||
"yogeshpaliyal.foss@gmail.com"
|
||||
)
|
||||
return true
|
||||
true
|
||||
}
|
||||
|
||||
"backup" -> {
|
||||
BackupActivity.start(context)
|
||||
return true
|
||||
true
|
||||
}
|
||||
|
||||
getString(R.string.settings_restore_backup) -> {
|
||||
selectRestoreFile()
|
||||
return true
|
||||
true
|
||||
}
|
||||
|
||||
"share" -> {
|
||||
@@ -68,10 +68,10 @@ class MySettingsFragment : PreferenceFragmentCompat() {
|
||||
)
|
||||
sendIntent.type = "text/plain"
|
||||
startActivity(Intent.createChooser(sendIntent, getString(R.string.share_keypass)))
|
||||
return true
|
||||
true
|
||||
}
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
|
||||
private fun selectRestoreFile() {
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
package com.yogeshpaliyal.common.utils
|
||||
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.FloatRange
|
||||
import com.google.android.material.animation.ArgbEvaluatorCompat
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@@ -85,32 +83,6 @@ fun lerp(
|
||||
return lerp(startValue, endValue, (fraction - startFraction) / (endFraction - startFraction))
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolate between two colors when the fraction is in a given range.
|
||||
*/
|
||||
@ColorInt
|
||||
fun lerpArgb(
|
||||
@ColorInt startColor: Int,
|
||||
@ColorInt endColor: Int,
|
||||
@FloatRange(
|
||||
from = 0.0,
|
||||
fromInclusive = true,
|
||||
to = 1.0,
|
||||
toInclusive = false
|
||||
) startFraction: Float,
|
||||
@FloatRange(from = 0.0, fromInclusive = false, to = 1.0, toInclusive = true) endFraction: Float,
|
||||
@FloatRange(from = 0.0, fromInclusive = true, to = 1.0, toInclusive = true) fraction: Float
|
||||
): Int {
|
||||
if (fraction < startFraction) return startColor
|
||||
if (fraction > endFraction) return endColor
|
||||
|
||||
return ArgbEvaluatorCompat.getInstance().evaluate(
|
||||
(fraction - startFraction) / (endFraction - startFraction),
|
||||
startColor,
|
||||
endColor
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce the receiving Float between inputMin and inputMax and linearly interpolate to the
|
||||
* outputMin to outputMax scale. This function is able to handle ranges which span negative and
|
||||
@@ -124,12 +96,16 @@ fun Float.normalize(
|
||||
outputMin: Float,
|
||||
outputMax: Float
|
||||
): Float {
|
||||
if (this < inputMin) {
|
||||
return outputMin
|
||||
val result: Float? = if (this < inputMin) {
|
||||
outputMin
|
||||
} else if (this > inputMax) {
|
||||
return outputMax
|
||||
outputMax
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
return outputMin * (1 - (this - inputMin) / (inputMax - inputMin)) +
|
||||
outputMax * ((this - inputMin) / (inputMax - inputMin))
|
||||
return result ?: (
|
||||
outputMin * (1 - (this - inputMin) / (inputMax - inputMin)) +
|
||||
outputMax * ((this - inputMin) / (inputMax - inputMin))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -31,10 +31,19 @@ fun getRandomString(sizeOfRandomString: Int): String {
|
||||
}
|
||||
|
||||
suspend fun Context?.canUserAccessBackupDirectory(): Boolean {
|
||||
this ?: return false
|
||||
val backupDirectoryUri = getUri(getBackupDirectory()) ?: return false
|
||||
val backupDirectory = DocumentFile.fromTreeUri(this, backupDirectoryUri)
|
||||
return backupDirectory != null && backupDirectory.exists() && backupDirectory.canRead() && backupDirectory.canWrite()
|
||||
if (this != null) {
|
||||
val backupDirectoryUri = getUri(getBackupDirectory())
|
||||
if (backupDirectoryUri != null) {
|
||||
val backupDirectory = DocumentFile.fromTreeUri(this, backupDirectoryUri)
|
||||
val listOfConditions = arrayListOf<Boolean?>()
|
||||
listOfConditions.add(backupDirectory != null)
|
||||
listOfConditions.add(backupDirectory?.exists())
|
||||
listOfConditions.add(backupDirectory?.canRead())
|
||||
listOfConditions.add(backupDirectory?.canWrite())
|
||||
return listOfConditions.all { it == true }
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.yogeshpaliyal.common.utils
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -65,7 +66,7 @@ fun Context.share(chooserTitle: String, text: String): Boolean {
|
||||
intent.type = "text/plain"
|
||||
startActivity(Intent.createChooser(intent, chooserTitle))
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ val Context.dataStore by preferencesDataStore(
|
||||
name = "settings"
|
||||
)
|
||||
|
||||
private const val BACKUP_KEY_LENGTH = 16
|
||||
|
||||
/**
|
||||
* Pair
|
||||
* 1st => true if key is created now & false if key is created previously
|
||||
@@ -29,7 +31,7 @@ suspend fun Context.getOrCreateBackupKey(reset: Boolean = false): Pair<Boolean,
|
||||
return if (sp.contains(BACKUP_KEY) && reset.not()) {
|
||||
Pair(false, (sp[BACKUP_KEY]) ?: "")
|
||||
} else {
|
||||
val randomKey = getRandomString(16)
|
||||
val randomKey = getRandomString(BACKUP_KEY_LENGTH)
|
||||
dataStore.edit {
|
||||
it[BACKUP_KEY] = randomKey
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user