Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,12 @@ public final class LocalAuthPlugin: NSObject, FlutterPlugin, LocalAuthApi, @unch
return
}
result = errorCode == .passcodeNotSet ? .errorPasscodeNotSet : .errorNotEnrolled
case .userCancel:
result = .errorUserCancelled
case .userFallback:
result = .errorUserFallback
case .biometryNotAvailable:
result = .errorBiometricNotAvailable
case .biometryLockout:
DispatchQueue.main.async { [weak self] in
self?.showAlert(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v25.3.2), do not edit directly.
// Autogenerated from Pigeon (v25.5.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon

import Foundation
Expand Down Expand Up @@ -141,6 +141,12 @@ enum AuthResult: Int {
case errorNotEnrolled = 3
/// No passcode is set.
case errorPasscodeNotSet = 4
/// The user cancelled the authentication.
case errorUserCancelled = 5
/// The user tapped the "Enter Password" fallback.
case errorUserFallback = 6
/// The user biometrics is disabled.
case errorBiometricNotAvailable = 7
}

/// Pigeon equivalent of the subset of BiometricType used by iOS.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ class LocalAuthDarwin extends LocalAuthPlatform {
code: 'PasscodeNotSet',
message: resultDetails.errorMessage,
details: resultDetails.errorDetails);
case AuthResult.errorUserCancelled:
throw PlatformException(
code: 'UserCancelled',
message: resultDetails.errorMessage,
details: resultDetails.errorDetails);
case AuthResult.errorBiometricNotAvailable:
throw PlatformException(
code: 'BiometricNotAvailable',
message: resultDetails.errorMessage,
details: resultDetails.errorDetails);
case AuthResult.errorUserFallback:
throw PlatformException(
code: 'UserFallback',
message: resultDetails.errorMessage,
details: resultDetails.errorDetails);
}
}

Expand Down
98 changes: 44 additions & 54 deletions packages/local_auth/local_auth_darwin/lib/src/messages.g.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v25.3.2), do not edit directly.
// Autogenerated from Pigeon (v25.5.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers

Expand All @@ -17,38 +17,39 @@ PlatformException _createConnectionError(String channelName) {
message: 'Unable to establish connection on channel: "$channelName".',
);
}

bool _deepEquals(Object? a, Object? b) {
if (a is List && b is List) {
return a.length == b.length &&
a.indexed
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
}
if (a is Map && b is Map) {
return a.length == b.length &&
a.entries.every((MapEntry<Object?, Object?> entry) =>
(b as Map<Object?, Object?>).containsKey(entry.key) &&
_deepEquals(entry.value, b[entry.key]));
return a.length == b.length && a.entries.every((MapEntry<Object?, Object?> entry) =>
(b as Map<Object?, Object?>).containsKey(entry.key) &&
_deepEquals(entry.value, b[entry.key]));
}
return a == b;
}


/// Possible outcomes of an authentication attempt.
enum AuthResult {
/// The user authenticated successfully.
success,

/// The user failed to successfully authenticate.
failure,

/// The authentication system was not available.
errorNotAvailable,

/// No biometrics are enrolled.
errorNotEnrolled,

/// No passcode is set.
errorPasscodeNotSet,
/// The user cancelled the authentication.
errorUserCancelled,
/// The user tapped the "Enter Password" fallback.
errorUserFallback,
/// The user biometrics is disabled.
errorBiometricNotAvailable,
}

/// Pigeon equivalent of the subset of BiometricType used by iOS.
Expand Down Expand Up @@ -94,8 +95,7 @@ class AuthStrings {
}

Object encode() {
return _toList();
}
return _toList(); }

static AuthStrings decode(Object result) {
result as List<Object?>;
Expand Down Expand Up @@ -123,7 +123,8 @@ class AuthStrings {

@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => Object.hashAll(_toList());
int get hashCode => Object.hashAll(_toList())
;
}

class AuthOptions {
Expand All @@ -148,8 +149,7 @@ class AuthOptions {
}

Object encode() {
return _toList();
}
return _toList(); }

static AuthOptions decode(Object result) {
result as List<Object?>;
Expand All @@ -174,7 +174,8 @@ class AuthOptions {

@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => Object.hashAll(_toList());
int get hashCode => Object.hashAll(_toList())
;
}

class AuthResultDetails {
Expand Down Expand Up @@ -202,8 +203,7 @@ class AuthResultDetails {
}

Object encode() {
return _toList();
}
return _toList(); }

static AuthResultDetails decode(Object result) {
result as List<Object?>;
Expand All @@ -228,29 +228,31 @@ class AuthResultDetails {

@override
// ignore: avoid_equals_and_hash_code_on_mutable_classes
int get hashCode => Object.hashAll(_toList());
int get hashCode => Object.hashAll(_toList())
;
}


class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is int) {
buffer.putUint8(4);
buffer.putInt64(value);
} else if (value is AuthResult) {
} else if (value is AuthResult) {
buffer.putUint8(129);
writeValue(buffer, value.index);
} else if (value is AuthBiometric) {
} else if (value is AuthBiometric) {
buffer.putUint8(130);
writeValue(buffer, value.index);
} else if (value is AuthStrings) {
} else if (value is AuthStrings) {
buffer.putUint8(131);
writeValue(buffer, value.encode());
} else if (value is AuthOptions) {
} else if (value is AuthOptions) {
buffer.putUint8(132);
writeValue(buffer, value.encode());
} else if (value is AuthResultDetails) {
} else if (value is AuthResultDetails) {
buffer.putUint8(133);
writeValue(buffer, value.encode());
} else {
Expand All @@ -261,17 +263,17 @@ class _PigeonCodec extends StandardMessageCodec {
@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
case 129:
case 129:
final int? value = readValue(buffer) as int?;
return value == null ? null : AuthResult.values[value];
case 130:
case 130:
final int? value = readValue(buffer) as int?;
return value == null ? null : AuthBiometric.values[value];
case 131:
case 131:
return AuthStrings.decode(readValue(buffer)!);
case 132:
case 132:
return AuthOptions.decode(readValue(buffer)!);
case 133:
case 133:
return AuthResultDetails.decode(readValue(buffer)!);
default:
return super.readValueOfType(type, buffer);
Expand All @@ -283,11 +285,9 @@ class LocalAuthApi {
/// Constructor for [LocalAuthApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
LocalAuthApi(
{BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
LocalAuthApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
: pigeonVar_binaryMessenger = binaryMessenger,
pigeonVar_messageChannelSuffix =
messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
final BinaryMessenger? pigeonVar_binaryMessenger;

static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
Expand All @@ -296,10 +296,8 @@ class LocalAuthApi {

/// Returns true if this device supports authentication.
Future<bool> isDeviceSupported() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.isDeviceSupported$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
final String pigeonVar_channelName = 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.isDeviceSupported$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
Expand Down Expand Up @@ -328,10 +326,8 @@ class LocalAuthApi {
/// Returns true if this device can support biometric authentication, whether
/// any biometrics are enrolled or not.
Future<bool> deviceCanSupportBiometrics() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.deviceCanSupportBiometrics$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
final String pigeonVar_channelName = 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.deviceCanSupportBiometrics$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
Expand Down Expand Up @@ -360,10 +356,8 @@ class LocalAuthApi {
/// Returns the biometric types that are enrolled, and can thus be used
/// without additional setup.
Future<List<AuthBiometric>> getEnrolledBiometrics() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.getEnrolledBiometrics$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
final String pigeonVar_channelName = 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.getEnrolledBiometrics$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
Expand Down Expand Up @@ -391,18 +385,14 @@ class LocalAuthApi {

/// Attempts to authenticate the user with the provided [options], and using
/// [strings] for any UI.
Future<AuthResultDetails> authenticate(
AuthOptions options, AuthStrings strings) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.authenticate$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
Future<AuthResultDetails> authenticate(AuthOptions options, AuthStrings strings) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.local_auth_darwin.LocalAuthApi.authenticate$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture =
pigeonVar_channel.send(<Object?>[options, strings]);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[options, strings]);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
Expand Down
9 changes: 9 additions & 0 deletions packages/local_auth/local_auth_darwin/pigeons/messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ enum AuthResult {

/// No passcode is set.
errorPasscodeNotSet,

/// The user cancelled the authentication.
errorUserCancelled,

/// The user tapped the "Enter Password" fallback.
errorUserFallback,

/// The user biometrics is disabled.
errorBiometricNotAvailable,
}

class AuthOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,71 @@ void main() {
errorDetails)));
});

test('converts errorUserCancelled to PlatformException', () async {
const String errorMessage = 'The user cancelled authentication.';
const String errorDetails = 'com.apple.LocalAuthentication';
when(api.authenticate(any, any)).thenAnswer((_) async =>
AuthResultDetails(
result: AuthResult.errorUserCancelled,
errorMessage: errorMessage,
errorDetails: errorDetails));

expect(
() async => plugin.authenticate(
localizedReason: 'reason', authMessages: <AuthMessages>[]),
throwsA(isA<PlatformException>()
.having(
(PlatformException e) => e.code, 'code', 'UserCancelled')
.having(
(PlatformException e) => e.message, 'message', errorMessage)
.having((PlatformException e) => e.details, 'details',
errorDetails)));
});

test('converts errorUserFallback to PlatformException', () async {
const String errorMessage = 'The user chose to use the fallback.';
const String errorDetails = 'com.apple.LocalAuthentication';
when(api.authenticate(any, any)).thenAnswer((_) async =>
AuthResultDetails(
result: AuthResult.errorUserFallback,
errorMessage: errorMessage,
errorDetails: errorDetails));

expect(
() async => plugin.authenticate(
localizedReason: 'reason', authMessages: <AuthMessages>[]),
throwsA(isA<PlatformException>()
.having((PlatformException e) => e.code, 'code', 'UserFallback')
.having(
(PlatformException e) => e.message, 'message', errorMessage)
.having((PlatformException e) => e.details, 'details',
errorDetails)));
});

test('converts errorBiometricNotAvailable to PlatformException',
() async {
const String errorMessage =
'Biometrics are not available on this device.';
const String errorDetails = 'com.apple.LocalAuthentication';
when(api.authenticate(any, any)).thenAnswer((_) async =>
AuthResultDetails(
result: AuthResult.errorBiometricNotAvailable,
errorMessage: errorMessage,
errorDetails: errorDetails));

expect(
() async => plugin.authenticate(
localizedReason: 'reason', authMessages: <AuthMessages>[]),
throwsA(isA<PlatformException>()
// The code here should match what you defined in your Dart switch statement.
.having((PlatformException e) => e.code, 'code',
'BiometricNotAvailable')
.having(
(PlatformException e) => e.message, 'message', errorMessage)
.having((PlatformException e) => e.details, 'details',
errorDetails)));
});

test('converts errorPasscodeNotSet to legacy PlatformException',
() async {
const String errorMessage = 'a message';
Expand Down