Skip to content

Commit

Permalink
Merge pull request #77 from authpass/authentication-validity-73
Browse files Browse the repository at this point in the history
Split authenticationValidityDurationSeconds between android and iOS
  • Loading branch information
hpoul authored May 21, 2024
2 parents 32da945 + 444e141 commit 0094e79
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 86 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 5.1.0-rc.1

* Split Split authenticationValidityDurationSeconds between android and iOS
* `darwinTouchIDAuthenticationForceReuseContextDuration`: Basically the equivalent to `androidAuthenticationValidityDuration`
* `darwinTouchIDAuthenticationAllowableReuseDuration`

## 5.0.1

* Add option for iOS/MacOS to allow non-biometric authentication (`darwinBiometricOnly`) #101
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import io.github.oshai.kotlinlogging.KotlinLogging
import java.io.File
import java.io.IOException
import javax.crypto.Cipher
import kotlin.time.Duration

private val logger = KotlinLogging.logger {}

data class InitOptions(
val authenticationValidityDurationSeconds: Int = -1,
val androidAuthenticationValidityDuration: Duration? = null,
val authenticationRequired: Boolean = true,
val androidBiometricOnly: Boolean = true
)
Expand Down Expand Up @@ -44,20 +45,22 @@ class BiometricStorageFile(
setIsStrongBoxBacked(useStrongBox)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (options.authenticationValidityDurationSeconds == -1) {
if (options.androidAuthenticationValidityDuration == null) {
setUserAuthenticationParameters(
0,
KeyProperties.AUTH_BIOMETRIC_STRONG
)
} else {
setUserAuthenticationParameters(
options.authenticationValidityDurationSeconds,
options.androidAuthenticationValidityDuration.inWholeSeconds.toInt(),
KeyProperties.AUTH_DEVICE_CREDENTIAL or KeyProperties.AUTH_BIOMETRIC_STRONG
)
}
} else {
@Suppress("DEPRECATION")
setUserAuthenticationValidityDurationSeconds(options.authenticationValidityDurationSeconds)
setUserAuthenticationValidityDurationSeconds(
options.androidAuthenticationValidityDuration?.inWholeSeconds?.toInt() ?: -1
)
}
}

Expand All @@ -74,8 +77,8 @@ class BiometricStorageFile(
}

private fun validateOptions() {
if (options.authenticationValidityDurationSeconds == -1 && !options.androidBiometricOnly) {
throw IllegalArgumentException("when authenticationValidityDurationSeconds is -1, androidBiometricOnly must be true")
if (options.androidAuthenticationValidityDuration == null && !options.androidBiometricOnly) {
throw IllegalArgumentException("when androidAuthenticationValidityDuration is null, androidBiometricOnly must be true")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import java.io.StringWriter
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import javax.crypto.Cipher
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

private val logger = KotlinLogging.logger {}

Expand Down Expand Up @@ -177,7 +179,7 @@ class BiometricStoragePlugin : FlutterPlugin, ActivityAware, MethodCallHandler {
CipherMode.Decrypt -> cipherForDecrypt()
}

val cipher = if (options.authenticationValidityDurationSeconds > -1) {
val cipher = if (options.androidAuthenticationValidityDuration != null) {
null
} else try {
cipherForMode()
Expand Down Expand Up @@ -223,7 +225,7 @@ class BiometricStoragePlugin : FlutterPlugin, ActivityAware, MethodCallHandler {

val options = call.argument<Map<String, Any>>("options")?.let {
InitOptions(
authenticationValidityDurationSeconds = it["authenticationValidityDurationSeconds"] as Int,
androidAuthenticationValidityDuration = (it["androidAuthenticationValidityDurationSeconds"] as Int?)?.seconds,
authenticationRequired = it["authenticationRequired"] as Boolean,
androidBiometricOnly = it["androidBiometricOnly"] as Boolean,
)
Expand Down Expand Up @@ -405,9 +407,9 @@ class BiometricStoragePlugin : FlutterPlugin, ActivityAware, MethodCallHandler {
promptBuilder.setAllowedAuthenticators(DEVICE_CREDENTIAL or BIOMETRIC_STRONG)
}

if (cipher == null || options.authenticationValidityDurationSeconds >= 0) {
// if authenticationValidityDurationSeconds is not -1 we can't use a CryptoObject
logger.debug { "Authenticating without cipher. ${options.authenticationValidityDurationSeconds}" }
if (cipher == null || options.androidAuthenticationValidityDuration != null) {
// if androidAuthenticationValidityDuration is not null we can't use a CryptoObject
logger.debug { "Authenticating without cipher. ${options.androidAuthenticationValidityDuration}" }
prompt.authenticate(promptBuilder.build())
} else {
prompt.authenticate(promptBuilder.build(), BiometricPrompt.CryptoObject(cipher))
Expand Down
19 changes: 19 additions & 0 deletions example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
include: package:flutter_lints/flutter.yaml

analyzer:
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: warning
# treat missing returns as a warning (not a hint)
missing_return: warning
# allow having TODOs in the code
todo: ignore
exclude:
- lib/generated_plugin_registrant.dart
- example/lib/generated_plugin_registrant.dart
language:
strict-casts: true
strict-raw-types: true

linter:
rules:
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011

COCOAPODS: 1.15.0
COCOAPODS: 1.15.2
2 changes: 1 addition & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
50 changes: 29 additions & 21 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void main() {
PrintAppender().attachToLogger(Logger.root);
logMessages.attachToLogger(Logger.root);
_logger.fine('Application launched. (v2)');
runApp(MyApp());
runApp(const MyApp());
}

class StringBufferWrapper with ChangeNotifier {
Expand Down Expand Up @@ -62,6 +62,8 @@ class MemoryAppender extends BaseLogAppender {
}

class MyApp extends StatefulWidget {
const MyApp({super.key});

@override
MyAppState createState() => MyAppState();
}
Expand Down Expand Up @@ -130,22 +132,26 @@ class MyAppState extends State<MyApp> {
authenticationRequired: false,
));
if (supportsAuthenticated) {
_customPrompt = await BiometricStorage().getStorage(
'${baseName}_customPrompt',
options: StorageFileInitOptions(
authenticationValidityDurationSeconds: 5),
promptInfo: const PromptInfo(
iosPromptInfo: IosPromptInfo(
saveTitle: 'Custom save title',
accessTitle: 'Custom access title.',
),
androidPromptInfo: AndroidPromptInfo(
title: 'Custom title',
subtitle: 'Custom subtitle',
description: 'Custom description',
negativeButton: 'Nope!',
),
));
_customPrompt = await BiometricStorage()
.getStorage('${baseName}_customPrompt',
options: StorageFileInitOptions(
androidAuthenticationValidityDuration:
const Duration(seconds: 5),
darwinTouchIDAuthenticationForceReuseContextDuration:
const Duration(seconds: 5),
),
promptInfo: const PromptInfo(
iosPromptInfo: IosPromptInfo(
saveTitle: 'Custom save title',
accessTitle: 'Custom access title.',
),
androidPromptInfo: AndroidPromptInfo(
title: 'Custom title',
subtitle: 'Custom subtitle',
description: 'Custom description',
negativeButton: 'Nope!',
),
));
}
setState(() {});
_logger.info('initiailzed $baseName');
Expand Down Expand Up @@ -194,13 +200,13 @@ class MyAppState extends State<MyApp> {
color: Colors.white,
constraints: const BoxConstraints.expand(),
child: SingleChildScrollView(
reverse: true,
child: Container(
padding: const EdgeInsets.all(16),
child: Text(
logMessages.log.toString(),
),
),
reverse: true,
),
),
),
Expand Down Expand Up @@ -230,9 +236,11 @@ class MyAppState extends State<MyApp> {
}

class StorageActions extends StatelessWidget {
const StorageActions(
{Key? key, required this.storageFile, required this.writeController})
: super(key: key);
const StorageActions({
super.key,
required this.storageFile,
required this.writeController,
});

final BiometricStorageFile storageFile;
final TextEditingController writeController;
Expand Down
Loading

0 comments on commit 0094e79

Please sign in to comment.