Merge #7eb29178: feat(security): require biometric authentication to to…

feat(security): require biometric authentication to toggle the biometrics setting

nostr:nevent1qqs8av530rq448g5r8a7rajhn9r5g2zsvc34hr92jryv65g5deakvkcpz3mhxue69uhhyetvv9ujumn8d96zuer9wck9amw6

PR-Author: greenart7c3
nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5

PR description:

Toggling the 'Enable biometrics' slider in the Security screen now triggers
the biometric/keyguard prompt before the switch changes state. This verifies
the biometric sensors work before activation and prevents deactivating the
setting without authorization.

Closes greenart7c3/Amber#519
This commit is contained in:
greenart7c3
2026-08-26 13:05:40 -03:00
@@ -1,5 +1,10 @@
package com.greenart7c3.nostrsigner.ui
import android.app.Activity
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -32,6 +37,7 @@ import com.greenart7c3.nostrsigner.Amber
import com.greenart7c3.nostrsigner.AmberLog
import com.greenart7c3.nostrsigner.LocalPreferences
import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.service.Biometrics.authenticate
import com.greenart7c3.nostrsigner.ui.components.AmberButton
import com.greenart7c3.nostrsigner.ui.components.TitleExplainer
import com.greenart7c3.nostrsigner.ui.navigation.Route
@@ -61,6 +67,33 @@ fun SecurityScreen(
}
val scope = rememberCoroutineScope()
val context = LocalContext.current
val biometricsKeyguardLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
enableBiometrics = !enableBiometrics
}
}
fun toggleBiometrics() {
authenticate(
title = context.getString(R.string.authenticate),
context = context,
keyguardLauncher = biometricsKeyguardLauncher,
onApproved = {
enableBiometrics = !enableBiometrics
},
onError = { _, message ->
Amber.instance.applicationIOScope.launch(Dispatchers.Main) {
Toast.makeText(
context,
message,
Toast.LENGTH_SHORT,
).show()
}
},
)
}
fun toggleRequireUnlockedDevice(enabled: Boolean) {
requireUnlockedDevice = enabled
requireUnlockedDeviceUpdating = true
@@ -97,7 +130,7 @@ fun SecurityScreen(
modifier = Modifier
.padding(horizontal = 8.dp)
.clickable {
enableBiometrics = !enableBiometrics
toggleBiometrics()
},
) {
Text(
@@ -107,7 +140,7 @@ fun SecurityScreen(
Switch(
checked = enableBiometrics,
onCheckedChange = {
enableBiometrics = !enableBiometrics
toggleBiometrics()
},
)
}