Merge pull request #183 from yogeshpaliyal/securityFixes

Security fixes
This commit is contained in:
Yogesh Choudhary Paliyal
2022-07-03 00:20:26 +05:30
committed by GitHub
6 changed files with 43 additions and 48 deletions
@@ -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
}