mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-26 10:33:15 +03:00
Add basic NFC support.
This commit is contained in:
parent
9136a4505d
commit
7d88c5c6a5
@ -3,10 +3,25 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
import '../../management/models.dart';
|
import '../../management/models.dart';
|
||||||
|
|
||||||
part 'models.freezed.dart';
|
part 'models.freezed.dart';
|
||||||
part 'models.g.dart';
|
//part 'models.g.dart';
|
||||||
|
|
||||||
enum SubPage { authenticator, yubikey }
|
enum SubPage { authenticator, yubikey }
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class YubiKeyData with _$YubiKeyData {
|
||||||
|
factory YubiKeyData(DeviceNode node, String name, DeviceInfo info) =
|
||||||
|
_YubiKeyData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class DeviceNode with _$DeviceNode {
|
||||||
|
factory DeviceNode.usbYubiKey(
|
||||||
|
List<String> path, String name, int pid, DeviceInfo info) =
|
||||||
|
UsbYubiKeyNode;
|
||||||
|
factory DeviceNode.nfcReader(List<String> path, String name) = NfcReaderNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
@freezed
|
@freezed
|
||||||
class DeviceNode with _$DeviceNode {
|
class DeviceNode with _$DeviceNode {
|
||||||
factory DeviceNode(
|
factory DeviceNode(
|
||||||
@ -16,10 +31,8 @@ class DeviceNode with _$DeviceNode {
|
|||||||
String name,
|
String name,
|
||||||
DeviceInfo info,
|
DeviceInfo info,
|
||||||
) = _DeviceNode;
|
) = _DeviceNode;
|
||||||
|
|
||||||
factory DeviceNode.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$DeviceNodeFromJson(json);
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class MenuAction with _$MenuAction {
|
class MenuAction with _$MenuAction {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||||
|
|
||||||
part of 'models.dart';
|
part of 'models.dart';
|
||||||
@ -13,27 +14,212 @@ T _$identity<T>(T value) => value;
|
|||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||||
|
|
||||||
DeviceNode _$DeviceNodeFromJson(Map<String, dynamic> json) {
|
/// @nodoc
|
||||||
return _DeviceNode.fromJson(json);
|
class _$YubiKeyDataTearOff {
|
||||||
|
const _$YubiKeyDataTearOff();
|
||||||
|
|
||||||
|
_YubiKeyData call(DeviceNode node, String name, DeviceInfo info) {
|
||||||
|
return _YubiKeyData(
|
||||||
|
node,
|
||||||
|
name,
|
||||||
|
info,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
const $YubiKeyData = _$YubiKeyDataTearOff();
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$YubiKeyData {
|
||||||
|
DeviceNode get node => throw _privateConstructorUsedError;
|
||||||
|
String get name => throw _privateConstructorUsedError;
|
||||||
|
DeviceInfo get info => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$YubiKeyDataCopyWith<YubiKeyData> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $YubiKeyDataCopyWith<$Res> {
|
||||||
|
factory $YubiKeyDataCopyWith(
|
||||||
|
YubiKeyData value, $Res Function(YubiKeyData) then) =
|
||||||
|
_$YubiKeyDataCopyWithImpl<$Res>;
|
||||||
|
$Res call({DeviceNode node, String name, DeviceInfo info});
|
||||||
|
|
||||||
|
$DeviceNodeCopyWith<$Res> get node;
|
||||||
|
$DeviceInfoCopyWith<$Res> get info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$YubiKeyDataCopyWithImpl<$Res> implements $YubiKeyDataCopyWith<$Res> {
|
||||||
|
_$YubiKeyDataCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
final YubiKeyData _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function(YubiKeyData) _then;
|
||||||
|
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? node = freezed,
|
||||||
|
Object? name = freezed,
|
||||||
|
Object? info = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
node: node == freezed
|
||||||
|
? _value.node
|
||||||
|
: node // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DeviceNode,
|
||||||
|
name: name == freezed
|
||||||
|
? _value.name
|
||||||
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
info: info == freezed
|
||||||
|
? _value.info
|
||||||
|
: info // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DeviceInfo,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$DeviceNodeCopyWith<$Res> get node {
|
||||||
|
return $DeviceNodeCopyWith<$Res>(_value.node, (value) {
|
||||||
|
return _then(_value.copyWith(node: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$DeviceInfoCopyWith<$Res> get info {
|
||||||
|
return $DeviceInfoCopyWith<$Res>(_value.info, (value) {
|
||||||
|
return _then(_value.copyWith(info: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$YubiKeyDataCopyWith<$Res>
|
||||||
|
implements $YubiKeyDataCopyWith<$Res> {
|
||||||
|
factory _$YubiKeyDataCopyWith(
|
||||||
|
_YubiKeyData value, $Res Function(_YubiKeyData) then) =
|
||||||
|
__$YubiKeyDataCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
$Res call({DeviceNode node, String name, DeviceInfo info});
|
||||||
|
|
||||||
|
@override
|
||||||
|
$DeviceNodeCopyWith<$Res> get node;
|
||||||
|
@override
|
||||||
|
$DeviceInfoCopyWith<$Res> get info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$YubiKeyDataCopyWithImpl<$Res> extends _$YubiKeyDataCopyWithImpl<$Res>
|
||||||
|
implements _$YubiKeyDataCopyWith<$Res> {
|
||||||
|
__$YubiKeyDataCopyWithImpl(
|
||||||
|
_YubiKeyData _value, $Res Function(_YubiKeyData) _then)
|
||||||
|
: super(_value, (v) => _then(v as _YubiKeyData));
|
||||||
|
|
||||||
|
@override
|
||||||
|
_YubiKeyData get _value => super._value as _YubiKeyData;
|
||||||
|
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? node = freezed,
|
||||||
|
Object? name = freezed,
|
||||||
|
Object? info = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_YubiKeyData(
|
||||||
|
node == freezed
|
||||||
|
? _value.node
|
||||||
|
: node // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DeviceNode,
|
||||||
|
name == freezed
|
||||||
|
? _value.name
|
||||||
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
info == freezed
|
||||||
|
? _value.info
|
||||||
|
: info // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DeviceInfo,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_YubiKeyData implements _YubiKeyData {
|
||||||
|
_$_YubiKeyData(this.node, this.name, this.info);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final DeviceNode node;
|
||||||
|
@override
|
||||||
|
final String name;
|
||||||
|
@override
|
||||||
|
final DeviceInfo info;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'YubiKeyData(node: $node, name: $name, info: $info)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _YubiKeyData &&
|
||||||
|
const DeepCollectionEquality().equals(other.node, node) &&
|
||||||
|
const DeepCollectionEquality().equals(other.name, name) &&
|
||||||
|
const DeepCollectionEquality().equals(other.info, info));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(node),
|
||||||
|
const DeepCollectionEquality().hash(name),
|
||||||
|
const DeepCollectionEquality().hash(info));
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
_$YubiKeyDataCopyWith<_YubiKeyData> get copyWith =>
|
||||||
|
__$YubiKeyDataCopyWithImpl<_YubiKeyData>(this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _YubiKeyData implements YubiKeyData {
|
||||||
|
factory _YubiKeyData(DeviceNode node, String name, DeviceInfo info) =
|
||||||
|
_$_YubiKeyData;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DeviceNode get node;
|
||||||
|
@override
|
||||||
|
String get name;
|
||||||
|
@override
|
||||||
|
DeviceInfo get info;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$YubiKeyDataCopyWith<_YubiKeyData> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$DeviceNodeTearOff {
|
class _$DeviceNodeTearOff {
|
||||||
const _$DeviceNodeTearOff();
|
const _$DeviceNodeTearOff();
|
||||||
|
|
||||||
_DeviceNode call(List<String> path, int pid, Transport transport, String name,
|
UsbYubiKeyNode usbYubiKey(
|
||||||
DeviceInfo info) {
|
List<String> path, String name, int pid, DeviceInfo info) {
|
||||||
return _DeviceNode(
|
return UsbYubiKeyNode(
|
||||||
path,
|
path,
|
||||||
pid,
|
|
||||||
transport,
|
|
||||||
name,
|
name,
|
||||||
|
pid,
|
||||||
info,
|
info,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceNode fromJson(Map<String, Object?> json) {
|
NfcReaderNode nfcReader(List<String> path, String name) {
|
||||||
return DeviceNode.fromJson(json);
|
return NfcReaderNode(
|
||||||
|
path,
|
||||||
|
name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,12 +229,51 @@ const $DeviceNode = _$DeviceNodeTearOff();
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$DeviceNode {
|
mixin _$DeviceNode {
|
||||||
List<String> get path => throw _privateConstructorUsedError;
|
List<String> get path => throw _privateConstructorUsedError;
|
||||||
int get pid => throw _privateConstructorUsedError;
|
|
||||||
Transport get transport => throw _privateConstructorUsedError;
|
|
||||||
String get name => throw _privateConstructorUsedError;
|
String get name => throw _privateConstructorUsedError;
|
||||||
DeviceInfo get info => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function(
|
||||||
|
List<String> path, String name, int pid, DeviceInfo info)
|
||||||
|
usbYubiKey,
|
||||||
|
required TResult Function(List<String> path, String name) nfcReader,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult Function(List<String> path, String name, int pid, DeviceInfo info)?
|
||||||
|
usbYubiKey,
|
||||||
|
TResult Function(List<String> path, String name)? nfcReader,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function(List<String> path, String name, int pid, DeviceInfo info)?
|
||||||
|
usbYubiKey,
|
||||||
|
TResult Function(List<String> path, String name)? nfcReader,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UsbYubiKeyNode value) usbYubiKey,
|
||||||
|
required TResult Function(NfcReaderNode value) nfcReader,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult Function(UsbYubiKeyNode value)? usbYubiKey,
|
||||||
|
TResult Function(NfcReaderNode value)? nfcReader,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UsbYubiKeyNode value)? usbYubiKey,
|
||||||
|
TResult Function(NfcReaderNode value)? nfcReader,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
$DeviceNodeCopyWith<DeviceNode> get copyWith =>
|
$DeviceNodeCopyWith<DeviceNode> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -59,14 +284,7 @@ abstract class $DeviceNodeCopyWith<$Res> {
|
|||||||
factory $DeviceNodeCopyWith(
|
factory $DeviceNodeCopyWith(
|
||||||
DeviceNode value, $Res Function(DeviceNode) then) =
|
DeviceNode value, $Res Function(DeviceNode) then) =
|
||||||
_$DeviceNodeCopyWithImpl<$Res>;
|
_$DeviceNodeCopyWithImpl<$Res>;
|
||||||
$Res call(
|
$Res call({List<String> path, String name});
|
||||||
{List<String> path,
|
|
||||||
int pid,
|
|
||||||
Transport transport,
|
|
||||||
String name,
|
|
||||||
DeviceInfo info});
|
|
||||||
|
|
||||||
$DeviceInfoCopyWith<$Res> get info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -80,29 +298,64 @@ class _$DeviceNodeCopyWithImpl<$Res> implements $DeviceNodeCopyWith<$Res> {
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? path = freezed,
|
Object? path = freezed,
|
||||||
Object? pid = freezed,
|
|
||||||
Object? transport = freezed,
|
|
||||||
Object? name = freezed,
|
Object? name = freezed,
|
||||||
Object? info = freezed,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
path: path == freezed
|
path: path == freezed
|
||||||
? _value.path
|
? _value.path
|
||||||
: path // ignore: cast_nullable_to_non_nullable
|
: path // ignore: cast_nullable_to_non_nullable
|
||||||
as List<String>,
|
as List<String>,
|
||||||
pid: pid == freezed
|
|
||||||
? _value.pid
|
|
||||||
: pid // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int,
|
|
||||||
transport: transport == freezed
|
|
||||||
? _value.transport
|
|
||||||
: transport // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Transport,
|
|
||||||
name: name == freezed
|
name: name == freezed
|
||||||
? _value.name
|
? _value.name
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
info: info == freezed
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $UsbYubiKeyNodeCopyWith<$Res>
|
||||||
|
implements $DeviceNodeCopyWith<$Res> {
|
||||||
|
factory $UsbYubiKeyNodeCopyWith(
|
||||||
|
UsbYubiKeyNode value, $Res Function(UsbYubiKeyNode) then) =
|
||||||
|
_$UsbYubiKeyNodeCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
$Res call({List<String> path, String name, int pid, DeviceInfo info});
|
||||||
|
|
||||||
|
$DeviceInfoCopyWith<$Res> get info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$UsbYubiKeyNodeCopyWithImpl<$Res> extends _$DeviceNodeCopyWithImpl<$Res>
|
||||||
|
implements $UsbYubiKeyNodeCopyWith<$Res> {
|
||||||
|
_$UsbYubiKeyNodeCopyWithImpl(
|
||||||
|
UsbYubiKeyNode _value, $Res Function(UsbYubiKeyNode) _then)
|
||||||
|
: super(_value, (v) => _then(v as UsbYubiKeyNode));
|
||||||
|
|
||||||
|
@override
|
||||||
|
UsbYubiKeyNode get _value => super._value as UsbYubiKeyNode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? path = freezed,
|
||||||
|
Object? name = freezed,
|
||||||
|
Object? pid = freezed,
|
||||||
|
Object? info = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(UsbYubiKeyNode(
|
||||||
|
path == freezed
|
||||||
|
? _value.path
|
||||||
|
: path // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<String>,
|
||||||
|
name == freezed
|
||||||
|
? _value.name
|
||||||
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
pid == freezed
|
||||||
|
? _value.pid
|
||||||
|
: pid // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
info == freezed
|
||||||
? _value.info
|
? _value.info
|
||||||
: info // ignore: cast_nullable_to_non_nullable
|
: info // ignore: cast_nullable_to_non_nullable
|
||||||
as DeviceInfo,
|
as DeviceInfo,
|
||||||
@ -118,137 +371,282 @@ class _$DeviceNodeCopyWithImpl<$Res> implements $DeviceNodeCopyWith<$Res> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$DeviceNodeCopyWith<$Res> implements $DeviceNodeCopyWith<$Res> {
|
|
||||||
factory _$DeviceNodeCopyWith(
|
|
||||||
_DeviceNode value, $Res Function(_DeviceNode) then) =
|
|
||||||
__$DeviceNodeCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
$Res call(
|
|
||||||
{List<String> path,
|
|
||||||
int pid,
|
|
||||||
Transport transport,
|
|
||||||
String name,
|
|
||||||
DeviceInfo info});
|
|
||||||
|
|
||||||
@override
|
class _$UsbYubiKeyNode implements UsbYubiKeyNode {
|
||||||
$DeviceInfoCopyWith<$Res> get info;
|
_$UsbYubiKeyNode(this.path, this.name, this.pid, this.info);
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$DeviceNodeCopyWithImpl<$Res> extends _$DeviceNodeCopyWithImpl<$Res>
|
|
||||||
implements _$DeviceNodeCopyWith<$Res> {
|
|
||||||
__$DeviceNodeCopyWithImpl(
|
|
||||||
_DeviceNode _value, $Res Function(_DeviceNode) _then)
|
|
||||||
: super(_value, (v) => _then(v as _DeviceNode));
|
|
||||||
|
|
||||||
@override
|
|
||||||
_DeviceNode get _value => super._value as _DeviceNode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? path = freezed,
|
|
||||||
Object? pid = freezed,
|
|
||||||
Object? transport = freezed,
|
|
||||||
Object? name = freezed,
|
|
||||||
Object? info = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(_DeviceNode(
|
|
||||||
path == freezed
|
|
||||||
? _value.path
|
|
||||||
: path // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<String>,
|
|
||||||
pid == freezed
|
|
||||||
? _value.pid
|
|
||||||
: pid // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int,
|
|
||||||
transport == freezed
|
|
||||||
? _value.transport
|
|
||||||
: transport // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Transport,
|
|
||||||
name == freezed
|
|
||||||
? _value.name
|
|
||||||
: name // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
info == freezed
|
|
||||||
? _value.info
|
|
||||||
: info // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DeviceInfo,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
@JsonSerializable()
|
|
||||||
class _$_DeviceNode implements _DeviceNode {
|
|
||||||
_$_DeviceNode(this.path, this.pid, this.transport, this.name, this.info);
|
|
||||||
|
|
||||||
factory _$_DeviceNode.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$$_DeviceNodeFromJson(json);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final List<String> path;
|
final List<String> path;
|
||||||
@override
|
@override
|
||||||
final int pid;
|
|
||||||
@override
|
|
||||||
final Transport transport;
|
|
||||||
@override
|
|
||||||
final String name;
|
final String name;
|
||||||
@override
|
@override
|
||||||
|
final int pid;
|
||||||
|
@override
|
||||||
final DeviceInfo info;
|
final DeviceInfo info;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'DeviceNode(path: $path, pid: $pid, transport: $transport, name: $name, info: $info)';
|
return 'DeviceNode.usbYubiKey(path: $path, name: $name, pid: $pid, info: $info)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _DeviceNode &&
|
other is UsbYubiKeyNode &&
|
||||||
const DeepCollectionEquality().equals(other.path, path) &&
|
const DeepCollectionEquality().equals(other.path, path) &&
|
||||||
(identical(other.pid, pid) || other.pid == pid) &&
|
const DeepCollectionEquality().equals(other.name, name) &&
|
||||||
(identical(other.transport, transport) ||
|
const DeepCollectionEquality().equals(other.pid, pid) &&
|
||||||
other.transport == transport) &&
|
const DeepCollectionEquality().equals(other.info, info));
|
||||||
(identical(other.name, name) || other.name == name) &&
|
|
||||||
(identical(other.info, info) || other.info == info));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,
|
int get hashCode => Object.hash(
|
||||||
const DeepCollectionEquality().hash(path), pid, transport, name, info);
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(path),
|
||||||
|
const DeepCollectionEquality().hash(name),
|
||||||
|
const DeepCollectionEquality().hash(pid),
|
||||||
|
const DeepCollectionEquality().hash(info));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
_$DeviceNodeCopyWith<_DeviceNode> get copyWith =>
|
$UsbYubiKeyNodeCopyWith<UsbYubiKeyNode> get copyWith =>
|
||||||
__$DeviceNodeCopyWithImpl<_DeviceNode>(this, _$identity);
|
_$UsbYubiKeyNodeCopyWithImpl<UsbYubiKeyNode>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
@optionalTypeArgs
|
||||||
return _$$_DeviceNodeToJson(this);
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function(
|
||||||
|
List<String> path, String name, int pid, DeviceInfo info)
|
||||||
|
usbYubiKey,
|
||||||
|
required TResult Function(List<String> path, String name) nfcReader,
|
||||||
|
}) {
|
||||||
|
return usbYubiKey(path, name, pid, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult Function(List<String> path, String name, int pid, DeviceInfo info)?
|
||||||
|
usbYubiKey,
|
||||||
|
TResult Function(List<String> path, String name)? nfcReader,
|
||||||
|
}) {
|
||||||
|
return usbYubiKey?.call(path, name, pid, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function(List<String> path, String name, int pid, DeviceInfo info)?
|
||||||
|
usbYubiKey,
|
||||||
|
TResult Function(List<String> path, String name)? nfcReader,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (usbYubiKey != null) {
|
||||||
|
return usbYubiKey(path, name, pid, info);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UsbYubiKeyNode value) usbYubiKey,
|
||||||
|
required TResult Function(NfcReaderNode value) nfcReader,
|
||||||
|
}) {
|
||||||
|
return usbYubiKey(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult Function(UsbYubiKeyNode value)? usbYubiKey,
|
||||||
|
TResult Function(NfcReaderNode value)? nfcReader,
|
||||||
|
}) {
|
||||||
|
return usbYubiKey?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UsbYubiKeyNode value)? usbYubiKey,
|
||||||
|
TResult Function(NfcReaderNode value)? nfcReader,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (usbYubiKey != null) {
|
||||||
|
return usbYubiKey(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _DeviceNode implements DeviceNode {
|
abstract class UsbYubiKeyNode implements DeviceNode {
|
||||||
factory _DeviceNode(List<String> path, int pid, Transport transport,
|
factory UsbYubiKeyNode(
|
||||||
String name, DeviceInfo info) = _$_DeviceNode;
|
List<String> path, String name, int pid, DeviceInfo info) =
|
||||||
|
_$UsbYubiKeyNode;
|
||||||
factory _DeviceNode.fromJson(Map<String, dynamic> json) =
|
|
||||||
_$_DeviceNode.fromJson;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> get path;
|
List<String> get path;
|
||||||
@override
|
@override
|
||||||
int get pid;
|
|
||||||
@override
|
|
||||||
Transport get transport;
|
|
||||||
@override
|
|
||||||
String get name;
|
String get name;
|
||||||
@override
|
int get pid;
|
||||||
DeviceInfo get info;
|
DeviceInfo get info;
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
_$DeviceNodeCopyWith<_DeviceNode> get copyWith =>
|
$UsbYubiKeyNodeCopyWith<UsbYubiKeyNode> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $NfcReaderNodeCopyWith<$Res>
|
||||||
|
implements $DeviceNodeCopyWith<$Res> {
|
||||||
|
factory $NfcReaderNodeCopyWith(
|
||||||
|
NfcReaderNode value, $Res Function(NfcReaderNode) then) =
|
||||||
|
_$NfcReaderNodeCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
$Res call({List<String> path, String name});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$NfcReaderNodeCopyWithImpl<$Res> extends _$DeviceNodeCopyWithImpl<$Res>
|
||||||
|
implements $NfcReaderNodeCopyWith<$Res> {
|
||||||
|
_$NfcReaderNodeCopyWithImpl(
|
||||||
|
NfcReaderNode _value, $Res Function(NfcReaderNode) _then)
|
||||||
|
: super(_value, (v) => _then(v as NfcReaderNode));
|
||||||
|
|
||||||
|
@override
|
||||||
|
NfcReaderNode get _value => super._value as NfcReaderNode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? path = freezed,
|
||||||
|
Object? name = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(NfcReaderNode(
|
||||||
|
path == freezed
|
||||||
|
? _value.path
|
||||||
|
: path // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<String>,
|
||||||
|
name == freezed
|
||||||
|
? _value.name
|
||||||
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$NfcReaderNode implements NfcReaderNode {
|
||||||
|
_$NfcReaderNode(this.path, this.name);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final List<String> path;
|
||||||
|
@override
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'DeviceNode.nfcReader(path: $path, name: $name)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is NfcReaderNode &&
|
||||||
|
const DeepCollectionEquality().equals(other.path, path) &&
|
||||||
|
const DeepCollectionEquality().equals(other.name, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(path),
|
||||||
|
const DeepCollectionEquality().hash(name));
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
$NfcReaderNodeCopyWith<NfcReaderNode> get copyWith =>
|
||||||
|
_$NfcReaderNodeCopyWithImpl<NfcReaderNode>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function(
|
||||||
|
List<String> path, String name, int pid, DeviceInfo info)
|
||||||
|
usbYubiKey,
|
||||||
|
required TResult Function(List<String> path, String name) nfcReader,
|
||||||
|
}) {
|
||||||
|
return nfcReader(path, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult Function(List<String> path, String name, int pid, DeviceInfo info)?
|
||||||
|
usbYubiKey,
|
||||||
|
TResult Function(List<String> path, String name)? nfcReader,
|
||||||
|
}) {
|
||||||
|
return nfcReader?.call(path, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function(List<String> path, String name, int pid, DeviceInfo info)?
|
||||||
|
usbYubiKey,
|
||||||
|
TResult Function(List<String> path, String name)? nfcReader,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (nfcReader != null) {
|
||||||
|
return nfcReader(path, name);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UsbYubiKeyNode value) usbYubiKey,
|
||||||
|
required TResult Function(NfcReaderNode value) nfcReader,
|
||||||
|
}) {
|
||||||
|
return nfcReader(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult Function(UsbYubiKeyNode value)? usbYubiKey,
|
||||||
|
TResult Function(NfcReaderNode value)? nfcReader,
|
||||||
|
}) {
|
||||||
|
return nfcReader?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UsbYubiKeyNode value)? usbYubiKey,
|
||||||
|
TResult Function(NfcReaderNode value)? nfcReader,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (nfcReader != null) {
|
||||||
|
return nfcReader(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NfcReaderNode implements DeviceNode {
|
||||||
|
factory NfcReaderNode(List<String> path, String name) = _$NfcReaderNode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get path;
|
||||||
|
@override
|
||||||
|
String get name;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$NfcReaderNodeCopyWith<NfcReaderNode> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,13 +781,17 @@ class _$_MenuAction implements _MenuAction {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _MenuAction &&
|
other is _MenuAction &&
|
||||||
(identical(other.text, text) || other.text == text) &&
|
const DeepCollectionEquality().equals(other.text, text) &&
|
||||||
(identical(other.icon, icon) || other.icon == icon) &&
|
const DeepCollectionEquality().equals(other.icon, icon) &&
|
||||||
(identical(other.action, action) || other.action == action));
|
(identical(other.action, action) || other.action == action));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, text, icon, action);
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(text),
|
||||||
|
const DeepCollectionEquality().hash(icon),
|
||||||
|
action);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -548,13 +950,17 @@ class _$_WindowState implements _WindowState {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _WindowState &&
|
other is _WindowState &&
|
||||||
(identical(other.focused, focused) || other.focused == focused) &&
|
const DeepCollectionEquality().equals(other.focused, focused) &&
|
||||||
(identical(other.visible, visible) || other.visible == visible) &&
|
const DeepCollectionEquality().equals(other.visible, visible) &&
|
||||||
(identical(other.active, active) || other.active == active));
|
const DeepCollectionEquality().equals(other.active, active));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, focused, visible, active);
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(focused),
|
||||||
|
const DeepCollectionEquality().hash(visible),
|
||||||
|
const DeepCollectionEquality().hash(active));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'models.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
_$_DeviceNode _$$_DeviceNodeFromJson(Map<String, dynamic> json) =>
|
|
||||||
_$_DeviceNode(
|
|
||||||
(json['path'] as List<dynamic>).map((e) => e as String).toList(),
|
|
||||||
json['pid'] as int,
|
|
||||||
$enumDecode(_$TransportEnumMap, json['transport']),
|
|
||||||
json['name'] as String,
|
|
||||||
DeviceInfo.fromJson(json['info'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$_DeviceNodeToJson(_$_DeviceNode instance) =>
|
|
||||||
<String, dynamic>{
|
|
||||||
'path': instance.path,
|
|
||||||
'pid': instance.pid,
|
|
||||||
'transport': _$TransportEnumMap[instance.transport],
|
|
||||||
'name': instance.name,
|
|
||||||
'info': instance.info,
|
|
||||||
};
|
|
||||||
|
|
||||||
const _$TransportEnumMap = {
|
|
||||||
Transport.usb: 'usb',
|
|
||||||
Transport.nfc: 'nfc',
|
|
||||||
};
|
|
@ -6,6 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
import 'package:yubico_authenticator/management/models.dart';
|
||||||
|
|
||||||
import '../core/models.dart';
|
import '../core/models.dart';
|
||||||
import '../core/state.dart';
|
import '../core/state.dart';
|
||||||
@ -118,24 +119,24 @@ class SearchNotifier extends StateNotifier<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final attachedDevicesProvider =
|
final _usbDevicesProvider =
|
||||||
StateNotifierProvider<AttachedDeviceNotifier, List<DeviceNode>>((ref) {
|
StateNotifierProvider<UsbDeviceNotifier, List<UsbYubiKeyNode>>((ref) {
|
||||||
final notifier = AttachedDeviceNotifier(ref.watch(rpcProvider));
|
final notifier = UsbDeviceNotifier(ref.watch(rpcProvider));
|
||||||
ref.listen<WindowState>(windowStateProvider, (_, windowState) {
|
ref.listen<WindowState>(windowStateProvider, (_, windowState) {
|
||||||
notifier._notifyWindowState(windowState);
|
notifier._notifyWindowState(windowState);
|
||||||
}, fireImmediately: true);
|
}, fireImmediately: true);
|
||||||
return notifier;
|
return notifier;
|
||||||
});
|
});
|
||||||
|
|
||||||
class AttachedDeviceNotifier extends StateNotifier<List<DeviceNode>> {
|
class UsbDeviceNotifier extends StateNotifier<List<UsbYubiKeyNode>> {
|
||||||
final RpcSession _rpc;
|
final RpcSession _rpc;
|
||||||
Timer? _pollTimer;
|
Timer? _pollTimer;
|
||||||
int _usbState = -1;
|
int _usbState = -1;
|
||||||
AttachedDeviceNotifier(this._rpc) : super([]);
|
UsbDeviceNotifier(this._rpc) : super([]);
|
||||||
|
|
||||||
void _notifyWindowState(WindowState windowState) {
|
void _notifyWindowState(WindowState windowState) {
|
||||||
if (windowState.active) {
|
if (windowState.active) {
|
||||||
_pollUsb();
|
_pollDevices();
|
||||||
} else {
|
} else {
|
||||||
_pollTimer?.cancel();
|
_pollTimer?.cancel();
|
||||||
// Release any held device
|
// Release any held device
|
||||||
@ -149,37 +150,110 @@ class AttachedDeviceNotifier extends StateNotifier<List<DeviceNode>> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pollUsb() async {
|
void _pollDevices() async {
|
||||||
_pollTimer?.cancel();
|
_pollTimer?.cancel();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var scan = await _rpc.command('scan', ['usb']);
|
var scan = await _rpc.command('scan', ['usb']);
|
||||||
|
|
||||||
if (_usbState != scan['state'] || state.length != scan['pids'].length) {
|
if (_usbState != scan['state'] || state.length != scan['pids'].length) {
|
||||||
var usbResult = await _rpc.command('get', ['usb']);
|
var usbResult = await _rpc.command('get', ['usb']);
|
||||||
log.info('USB state change', jsonEncode(usbResult));
|
log.info('USB state change', jsonEncode(usbResult));
|
||||||
|
_usbState = usbResult['data']['state'];
|
||||||
|
List<UsbYubiKeyNode> usbDevices = [];
|
||||||
|
|
||||||
List<DeviceNode> devices = [];
|
|
||||||
for (String id in (usbResult['children'] as Map).keys) {
|
for (String id in (usbResult['children'] as Map).keys) {
|
||||||
var path = ['usb', id];
|
var path = ['usb', id];
|
||||||
var deviceResult = await _rpc.command('get', path);
|
var deviceResult = await _rpc.command('get', path);
|
||||||
devices.add(
|
var deviceData = deviceResult['data'];
|
||||||
DeviceNode.fromJson({'path': path, ...deviceResult['data']}));
|
usbDevices.add(DeviceNode.usbYubiKey(
|
||||||
|
path,
|
||||||
|
deviceData['name'],
|
||||||
|
deviceData['pid'],
|
||||||
|
DeviceInfo.fromJson(deviceData['info']),
|
||||||
|
) as UsbYubiKeyNode);
|
||||||
}
|
}
|
||||||
_usbState = usbResult['data']['state'];
|
|
||||||
log.info('USB state updated');
|
log.info('USB state updated');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
state = devices;
|
state = usbDevices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} on RpcError catch (e) {
|
} on RpcError catch (e) {
|
||||||
log.severe('Error polling USB', jsonEncode(e));
|
log.severe('Error polling USB', jsonEncode(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
_pollTimer = Timer(const Duration(milliseconds: 500), _pollUsb);
|
_pollTimer = Timer(const Duration(milliseconds: 500), _pollDevices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _nfcDevicesProvider =
|
||||||
|
StateNotifierProvider<NfcDeviceNotifier, List<NfcReaderNode>>((ref) {
|
||||||
|
final notifier = NfcDeviceNotifier(ref.watch(rpcProvider));
|
||||||
|
ref.listen<WindowState>(windowStateProvider, (_, windowState) {
|
||||||
|
notifier._notifyWindowState(windowState);
|
||||||
|
}, fireImmediately: true);
|
||||||
|
return notifier;
|
||||||
|
});
|
||||||
|
|
||||||
|
class NfcDeviceNotifier extends StateNotifier<List<NfcReaderNode>> {
|
||||||
|
final RpcSession _rpc;
|
||||||
|
Timer? _pollTimer;
|
||||||
|
String _nfcState = '';
|
||||||
|
NfcDeviceNotifier(this._rpc) : super([]);
|
||||||
|
|
||||||
|
void _notifyWindowState(WindowState windowState) {
|
||||||
|
if (windowState.active) {
|
||||||
|
_pollReaders();
|
||||||
|
} else {
|
||||||
|
_pollTimer?.cancel();
|
||||||
|
// Release any held device
|
||||||
|
_rpc.command('get', ['nfc']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_pollTimer?.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _pollReaders() async {
|
||||||
|
_pollTimer?.cancel();
|
||||||
|
|
||||||
|
try {
|
||||||
|
var children = await _rpc.command('scan', ['nfc']);
|
||||||
|
var newState = children.keys.join(':');
|
||||||
|
|
||||||
|
if (mounted && newState != _nfcState) {
|
||||||
|
log.info('NFC state change', jsonEncode(children));
|
||||||
|
_nfcState = newState;
|
||||||
|
state = children.entries
|
||||||
|
.map((e) =>
|
||||||
|
DeviceNode.nfcReader(['nfc', e.key], e.value['name'] as String)
|
||||||
|
as NfcReaderNode)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
} on RpcError catch (e) {
|
||||||
|
log.severe('Error polling NFC', jsonEncode(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
_pollTimer = Timer(const Duration(milliseconds: 2500), _pollReaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final attachedDevicesProvider = Provider<List<DeviceNode>>((ref) {
|
||||||
|
final usbDevices = ref.watch(_usbDevicesProvider).toList();
|
||||||
|
final nfcDevices = ref.watch(_nfcDevicesProvider).toList();
|
||||||
|
usbDevices.sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
nfcDevices.sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
return [...usbDevices, ...nfcDevices];
|
||||||
|
});
|
||||||
|
|
||||||
final currentDeviceProvider =
|
final currentDeviceProvider =
|
||||||
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>((ref) {
|
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>((ref) {
|
||||||
final provider = CurrentDeviceNotifier(ref.watch(prefProvider));
|
final provider = CurrentDeviceNotifier(ref.watch(prefProvider));
|
||||||
@ -188,42 +262,110 @@ final currentDeviceProvider =
|
|||||||
});
|
});
|
||||||
|
|
||||||
class CurrentDeviceNotifier extends StateNotifier<DeviceNode?> {
|
class CurrentDeviceNotifier extends StateNotifier<DeviceNode?> {
|
||||||
static const String _lastDeviceSerial = 'APP_STATE_LAST_SERIAL';
|
static const String _lastDevice = 'APP_STATE_LAST_DEVICE';
|
||||||
final SharedPreferences _prefs;
|
final SharedPreferences _prefs;
|
||||||
CurrentDeviceNotifier(this._prefs) : super(null);
|
CurrentDeviceNotifier(this._prefs) : super(null);
|
||||||
|
|
||||||
_updateAttachedDevices(List<DeviceNode>? previous, List<DeviceNode> devices) {
|
_updateAttachedDevices(List<DeviceNode>? previous, List<DeviceNode> devices) {
|
||||||
if (devices.isEmpty) {
|
if (!devices.contains(state)) {
|
||||||
state = null;
|
final lastDevice = _prefs.getString(_lastDevice) ?? '';
|
||||||
} else if (!devices.contains(state)) {
|
try {
|
||||||
// Prefer last selected device
|
state = devices.firstWhere(
|
||||||
final serial = _prefs.getInt(_lastDeviceSerial) ?? -1;
|
(dev) => dev.when(
|
||||||
state = devices.firstWhere(
|
usbYubiKey: (path, name, pid, info) =>
|
||||||
(element) => element.info.serial == serial,
|
lastDevice == 'serial:${info.serial}',
|
||||||
orElse: () => devices.first,
|
nfcReader: (path, name) => lastDevice == 'name:$name',
|
||||||
);
|
),
|
||||||
|
orElse: () => devices.whereType<UsbYubiKeyNode>().first);
|
||||||
|
} on StateError {
|
||||||
|
state = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentDevice(DeviceNode device) {
|
setCurrentDevice(DeviceNode device) {
|
||||||
state = device;
|
state = device;
|
||||||
final serial = device.info.serial;
|
device.when(
|
||||||
if (serial != null) {
|
usbYubiKey: (path, name, pid, info) {
|
||||||
_prefs.setInt(_lastDeviceSerial, serial);
|
final serial = info.serial;
|
||||||
}
|
if (serial != null) {
|
||||||
|
_prefs.setString(_lastDevice, 'serial:$serial');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nfcReader: (path, name) {
|
||||||
|
_prefs.setString(_lastDevice, 'name:$name');
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final sortedDevicesProvider = Provider<List<DeviceNode>>((ref) {
|
final currentDeviceDataProvider =
|
||||||
final devices = ref.watch(attachedDevicesProvider).toList();
|
StateNotifierProvider<CurrentDeviceDataNotifier, YubiKeyData?>((ref) {
|
||||||
devices.sort((a, b) => a.name.compareTo(b.name));
|
final notifier = CurrentDeviceDataNotifier(
|
||||||
final device = ref.watch(currentDeviceProvider);
|
ref.watch(rpcProvider),
|
||||||
if (device != null) {
|
ref.watch(currentDeviceProvider),
|
||||||
return [device, ...devices.where((e) => e != device)];
|
);
|
||||||
|
if (notifier._deviceNode is NfcReaderNode) {
|
||||||
|
// If this is an NFC reader, listen on WindowState.
|
||||||
|
ref.listen<WindowState>(windowStateProvider, (_, windowState) {
|
||||||
|
notifier._notifyWindowState(windowState);
|
||||||
|
}, fireImmediately: true);
|
||||||
}
|
}
|
||||||
return devices;
|
return notifier;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
class CurrentDeviceDataNotifier extends StateNotifier<YubiKeyData?> {
|
||||||
|
final RpcSession _rpc;
|
||||||
|
final DeviceNode? _deviceNode;
|
||||||
|
Timer? _pollTimer;
|
||||||
|
|
||||||
|
CurrentDeviceDataNotifier(this._rpc, this._deviceNode) : super(null) {
|
||||||
|
final dev = _deviceNode;
|
||||||
|
if (dev is UsbYubiKeyNode) {
|
||||||
|
state = YubiKeyData(dev, dev.name, dev.info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyWindowState(WindowState windowState) {
|
||||||
|
if (windowState.active) {
|
||||||
|
_pollReader();
|
||||||
|
} else {
|
||||||
|
_pollTimer?.cancel();
|
||||||
|
// TODO: Should we clear the key here?
|
||||||
|
/*if (mounted) {
|
||||||
|
state = null;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_pollTimer?.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _pollReader() async {
|
||||||
|
_pollTimer?.cancel();
|
||||||
|
final node = _deviceNode!;
|
||||||
|
try {
|
||||||
|
var result = await _rpc.command('get', node.path);
|
||||||
|
if (mounted) {
|
||||||
|
if (result['data']['present']) {
|
||||||
|
state = YubiKeyData(node, result['data']['name'],
|
||||||
|
DeviceInfo.fromJson(result['data']['info']));
|
||||||
|
} else {
|
||||||
|
state = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} on RpcError catch (e) {
|
||||||
|
log.severe('Error polling NFC', jsonEncode(e));
|
||||||
|
}
|
||||||
|
if (mounted) {
|
||||||
|
_pollTimer = Timer(Duration(seconds: state == null ? 1 : 5), _pollReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final subPageProvider = StateNotifierProvider<SubPageNotifier, SubPage>(
|
final subPageProvider = StateNotifierProvider<SubPageNotifier, SubPage>(
|
||||||
(ref) => SubPageNotifier(SubPage.authenticator));
|
(ref) => SubPageNotifier(SubPage.authenticator));
|
||||||
|
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:yubico_authenticator/management/models.dart';
|
||||||
|
|
||||||
import '../models.dart';
|
import '../models.dart';
|
||||||
import 'device_images.dart';
|
import 'device_images.dart';
|
||||||
|
|
||||||
class DeviceAvatar extends StatelessWidget {
|
class DeviceAvatar extends StatelessWidget {
|
||||||
final DeviceNode device;
|
final DeviceNode node;
|
||||||
|
final String name;
|
||||||
|
final DeviceInfo? info;
|
||||||
final bool selected;
|
final bool selected;
|
||||||
|
|
||||||
const DeviceAvatar(this.device, {this.selected = false, Key? key})
|
const DeviceAvatar(this.node, this.name, this.info,
|
||||||
|
{this.selected = false, Key? key})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return CircleAvatar(
|
return CircleAvatar(
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
child: getProductImage(device),
|
child:
|
||||||
|
info != null ? getProductImage(info!, name) : const Icon(Icons.nfc),
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
),
|
),
|
||||||
radius: 22,
|
radius: 22,
|
||||||
|
@ -30,11 +30,11 @@ const _imagesForFormFactorNfc = {
|
|||||||
FormFactor.usbCKeychain: 'yk5cnfc',
|
FormFactor.usbCKeychain: 'yk5cnfc',
|
||||||
};
|
};
|
||||||
|
|
||||||
Image getProductImage(DeviceNode device) {
|
Image getProductImage(DeviceInfo info, String name) {
|
||||||
var image = _imagesForName[device.name];
|
var image = _imagesForName[name];
|
||||||
image ??= device.info.supportedCapabilities.containsKey(Transport.nfc)
|
image ??= info.supportedCapabilities.containsKey(Transport.nfc)
|
||||||
? _imagesForFormFactorNfc[device.info.formFactor]
|
? _imagesForFormFactorNfc[info.formFactor]
|
||||||
: _imagesForFormFactor[device.info.formFactor];
|
: _imagesForFormFactor[info.formFactor];
|
||||||
image ??= 'yk5series';
|
image ??= 'yk5series';
|
||||||
|
|
||||||
return Image.asset('assets/product-images/$image.png');
|
return Image.asset('assets/product-images/$image.png');
|
||||||
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import '../models.dart';
|
import '../models.dart';
|
||||||
|
|
||||||
class DeviceInfoScreen extends StatelessWidget {
|
class DeviceInfoScreen extends StatelessWidget {
|
||||||
final DeviceNode device;
|
final YubiKeyData device;
|
||||||
const DeviceInfoScreen(this.device, {Key? key}) : super(key: key);
|
const DeviceInfoScreen(this.device, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1,32 +1,56 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:yubico_authenticator/management/models.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
import '../models.dart';
|
import '../models.dart';
|
||||||
import '../state.dart';
|
import '../state.dart';
|
||||||
import 'device_avatar.dart';
|
import 'device_avatar.dart';
|
||||||
|
|
||||||
|
Function _listEquals = const ListEquality().equals;
|
||||||
|
|
||||||
class MainActionsDialog extends ConsumerWidget {
|
class MainActionsDialog extends ConsumerWidget {
|
||||||
const MainActionsDialog({Key? key}) : super(key: key);
|
const MainActionsDialog({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final devices = ref.watch(sortedDevicesProvider);
|
final devices = ref.watch(attachedDevicesProvider).toList();
|
||||||
final device = ref.watch(currentDeviceProvider);
|
final currentNode = ref.watch(currentDeviceProvider);
|
||||||
|
final data = ref.watch(currentDeviceDataProvider);
|
||||||
final actions = ref.watch(menuActionsProvider)(context);
|
final actions = ref.watch(menuActionsProvider)(context);
|
||||||
|
//final nfcReaders = ref.watch(nfcDevicesProvider);
|
||||||
|
|
||||||
|
//final allDevices = devices + nfcReaders;
|
||||||
|
if (currentNode != null) {
|
||||||
|
devices.removeWhere((e) => _listEquals(e.path, currentNode.path));
|
||||||
|
}
|
||||||
|
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
children: [
|
children: [
|
||||||
...devices.map((e) => Padding(
|
if (currentNode != null)
|
||||||
padding: const EdgeInsets.all(8.0),
|
CurrentDeviceRow(
|
||||||
child: DeviceRow(
|
currentNode,
|
||||||
e,
|
data?.name,
|
||||||
selected: e == device,
|
info: data?.info,
|
||||||
onPressed: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
ref.read(currentDeviceProvider.notifier).setCurrentDevice(e);
|
},
|
||||||
},
|
),
|
||||||
),
|
...devices.map(
|
||||||
)),
|
(e) => DeviceRow(
|
||||||
|
e,
|
||||||
|
e.name,
|
||||||
|
info: e.when(
|
||||||
|
usbYubiKey: (path, name, pid, info) => info,
|
||||||
|
nfcReader: (path, name) => null,
|
||||||
|
),
|
||||||
|
selected: false,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
ref.read(currentDeviceProvider.notifier).setCurrentDevice(e);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
if (actions.isNotEmpty) const Divider(),
|
if (actions.isNotEmpty) const Divider(),
|
||||||
...actions.map((a) => ListTile(
|
...actions.map((a) => ListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
@ -42,43 +66,74 @@ class MainActionsDialog extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeviceRow extends StatelessWidget {
|
class CurrentDeviceRow extends StatelessWidget {
|
||||||
final DeviceNode device;
|
final DeviceNode node;
|
||||||
final bool selected;
|
final String? name;
|
||||||
final Function() onPressed;
|
final DeviceInfo? info;
|
||||||
const DeviceRow(
|
final Function() onTap;
|
||||||
this.device, {
|
|
||||||
this.selected = false,
|
const CurrentDeviceRow(
|
||||||
required this.onPressed,
|
this.node,
|
||||||
|
this.name, {
|
||||||
|
required this.info,
|
||||||
|
required this.onTap,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TextButton(
|
final subtitle = node is NfcReaderNode
|
||||||
onPressed: onPressed,
|
? info != null
|
||||||
child: Row(
|
? '${node.name}\nS/N: ${info!.serial} F/W: ${info!.version}'
|
||||||
children: [
|
: node.name
|
||||||
DeviceAvatar(
|
: 'S/N: ${info!.serial} F/W: ${info!.version}';
|
||||||
device,
|
return ListTile(
|
||||||
selected: selected,
|
leading: DeviceAvatar(
|
||||||
),
|
node,
|
||||||
const SizedBox(width: 16.0),
|
name ?? '',
|
||||||
Column(
|
info,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
selected: true,
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
device.name,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'S/N: ${device.info.serial} F/W: ${device.info.version}',
|
|
||||||
style: Theme.of(context).textTheme.bodyText1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
title: Text(name ?? 'No YubiKey present'),
|
||||||
|
isThreeLine: subtitle.contains('\n'),
|
||||||
|
subtitle: Text(subtitle),
|
||||||
|
onTap: onTap,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeviceRow extends StatelessWidget {
|
||||||
|
final DeviceNode node;
|
||||||
|
final String name;
|
||||||
|
final DeviceInfo? info;
|
||||||
|
final bool selected;
|
||||||
|
final Function() onTap;
|
||||||
|
|
||||||
|
const DeviceRow(
|
||||||
|
this.node,
|
||||||
|
this.name, {
|
||||||
|
required this.info,
|
||||||
|
required this.onTap,
|
||||||
|
this.selected = false,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: DeviceAvatar(
|
||||||
|
node,
|
||||||
|
name,
|
||||||
|
info,
|
||||||
|
selected: selected,
|
||||||
|
),
|
||||||
|
title: Text(name),
|
||||||
|
subtitle: Text(
|
||||||
|
info == null
|
||||||
|
? (selected ? 'No YubiKey present' : 'Select to scan')
|
||||||
|
: 'S/N: ${info!.serial} F/W: ${info!.version}',
|
||||||
|
),
|
||||||
|
onTap: onTap,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import '../../oath/views/oath_screen.dart';
|
|||||||
class MainPage extends ConsumerWidget {
|
class MainPage extends ConsumerWidget {
|
||||||
const MainPage({Key? key}) : super(key: key);
|
const MainPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
Widget _buildSubPage(SubPage subPage, DeviceNode? device) {
|
Widget _buildSubPage(SubPage subPage, YubiKeyData? device) {
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
return const NoDeviceScreen();
|
return const NoDeviceScreen();
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ class MainPage extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final currentDevice = ref.watch(currentDeviceProvider);
|
final currentDevice = ref.watch(currentDeviceDataProvider);
|
||||||
final subPage = ref.watch(subPageProvider);
|
final subPage = ref.watch(subPageProvider);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -67,7 +67,12 @@ class MainPage extends ConsumerWidget {
|
|||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: DeviceAvatar(currentDevice, selected: true),
|
: DeviceAvatar(
|
||||||
|
currentDevice.node,
|
||||||
|
currentDevice.name,
|
||||||
|
currentDevice.info,
|
||||||
|
selected: true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||||
|
|
||||||
part of 'models.dart';
|
part of 'models.dart';
|
||||||
@ -134,13 +135,17 @@ class _$_Version extends _Version {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _Version &&
|
other is _Version &&
|
||||||
(identical(other.major, major) || other.major == major) &&
|
const DeepCollectionEquality().equals(other.major, major) &&
|
||||||
(identical(other.minor, minor) || other.minor == minor) &&
|
const DeepCollectionEquality().equals(other.minor, minor) &&
|
||||||
(identical(other.patch, patch) || other.patch == patch));
|
const DeepCollectionEquality().equals(other.patch, patch));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, major, minor, patch);
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(major),
|
||||||
|
const DeepCollectionEquality().hash(minor),
|
||||||
|
const DeepCollectionEquality().hash(patch));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -516,13 +521,15 @@ class _$Signal implements Signal {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is Signal &&
|
other is Signal &&
|
||||||
(identical(other.status, status) || other.status == status) &&
|
const DeepCollectionEquality().equals(other.status, status) &&
|
||||||
const DeepCollectionEquality().equals(other.body, body));
|
const DeepCollectionEquality().equals(other.body, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType, status, const DeepCollectionEquality().hash(body));
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(status),
|
||||||
|
const DeepCollectionEquality().hash(body));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -689,14 +696,17 @@ class _$RpcError implements RpcError {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is RpcError &&
|
other is RpcError &&
|
||||||
(identical(other.status, status) || other.status == status) &&
|
const DeepCollectionEquality().equals(other.status, status) &&
|
||||||
(identical(other.message, message) || other.message == message) &&
|
const DeepCollectionEquality().equals(other.message, message) &&
|
||||||
const DeepCollectionEquality().equals(other.body, body));
|
const DeepCollectionEquality().equals(other.body, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType, status, message, const DeepCollectionEquality().hash(body));
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(status),
|
||||||
|
const DeepCollectionEquality().hash(message),
|
||||||
|
const DeepCollectionEquality().hash(body));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -896,11 +906,12 @@ class _$_RpcState implements _RpcState {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _RpcState &&
|
other is _RpcState &&
|
||||||
(identical(other.version, version) || other.version == version));
|
const DeepCollectionEquality().equals(other.version, version));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, version);
|
int get hashCode =>
|
||||||
|
Object.hash(runtimeType, const DeepCollectionEquality().hash(version));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||||
|
|
||||||
part of 'models.dart';
|
part of 'models.dart';
|
||||||
@ -183,22 +184,21 @@ class _$_DeviceConfig implements _DeviceConfig {
|
|||||||
other is _DeviceConfig &&
|
other is _DeviceConfig &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.enabledCapabilities, enabledCapabilities) &&
|
.equals(other.enabledCapabilities, enabledCapabilities) &&
|
||||||
(identical(other.autoEjectTimeout, autoEjectTimeout) ||
|
const DeepCollectionEquality()
|
||||||
other.autoEjectTimeout == autoEjectTimeout) &&
|
.equals(other.autoEjectTimeout, autoEjectTimeout) &&
|
||||||
(identical(
|
const DeepCollectionEquality().equals(
|
||||||
other.challengeResponseTimeout, challengeResponseTimeout) ||
|
other.challengeResponseTimeout, challengeResponseTimeout) &&
|
||||||
other.challengeResponseTimeout == challengeResponseTimeout) &&
|
const DeepCollectionEquality()
|
||||||
(identical(other.deviceFlags, deviceFlags) ||
|
.equals(other.deviceFlags, deviceFlags));
|
||||||
other.deviceFlags == deviceFlags));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
const DeepCollectionEquality().hash(enabledCapabilities),
|
const DeepCollectionEquality().hash(enabledCapabilities),
|
||||||
autoEjectTimeout,
|
const DeepCollectionEquality().hash(autoEjectTimeout),
|
||||||
challengeResponseTimeout,
|
const DeepCollectionEquality().hash(challengeResponseTimeout),
|
||||||
deviceFlags);
|
const DeepCollectionEquality().hash(deviceFlags));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -495,30 +495,29 @@ class _$_DeviceInfo implements _DeviceInfo {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _DeviceInfo &&
|
other is _DeviceInfo &&
|
||||||
(identical(other.config, config) || other.config == config) &&
|
const DeepCollectionEquality().equals(other.config, config) &&
|
||||||
(identical(other.serial, serial) || other.serial == serial) &&
|
const DeepCollectionEquality().equals(other.serial, serial) &&
|
||||||
(identical(other.version, version) || other.version == version) &&
|
const DeepCollectionEquality().equals(other.version, version) &&
|
||||||
(identical(other.formFactor, formFactor) ||
|
const DeepCollectionEquality()
|
||||||
other.formFactor == formFactor) &&
|
.equals(other.formFactor, formFactor) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.supportedCapabilities, supportedCapabilities) &&
|
.equals(other.supportedCapabilities, supportedCapabilities) &&
|
||||||
(identical(other.isLocked, isLocked) ||
|
const DeepCollectionEquality().equals(other.isLocked, isLocked) &&
|
||||||
other.isLocked == isLocked) &&
|
const DeepCollectionEquality().equals(other.isFips, isFips) &&
|
||||||
(identical(other.isFips, isFips) || other.isFips == isFips) &&
|
const DeepCollectionEquality().equals(other.isSky, isSky));
|
||||||
(identical(other.isSky, isSky) || other.isSky == isSky));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
config,
|
const DeepCollectionEquality().hash(config),
|
||||||
serial,
|
const DeepCollectionEquality().hash(serial),
|
||||||
version,
|
const DeepCollectionEquality().hash(version),
|
||||||
formFactor,
|
const DeepCollectionEquality().hash(formFactor),
|
||||||
const DeepCollectionEquality().hash(supportedCapabilities),
|
const DeepCollectionEquality().hash(supportedCapabilities),
|
||||||
isLocked,
|
const DeepCollectionEquality().hash(isLocked),
|
||||||
isFips,
|
const DeepCollectionEquality().hash(isFips),
|
||||||
isSky);
|
const DeepCollectionEquality().hash(isSky));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||||
|
|
||||||
part of 'models.dart';
|
part of 'models.dart';
|
||||||
@ -230,21 +231,26 @@ class _$_OathCredential implements _OathCredential {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _OathCredential &&
|
other is _OathCredential &&
|
||||||
(identical(other.deviceId, deviceId) ||
|
const DeepCollectionEquality().equals(other.deviceId, deviceId) &&
|
||||||
other.deviceId == deviceId) &&
|
const DeepCollectionEquality().equals(other.id, id) &&
|
||||||
(identical(other.id, id) || other.id == id) &&
|
const DeepCollectionEquality().equals(other.issuer, issuer) &&
|
||||||
(identical(other.issuer, issuer) || other.issuer == issuer) &&
|
const DeepCollectionEquality().equals(other.name, name) &&
|
||||||
(identical(other.name, name) || other.name == name) &&
|
const DeepCollectionEquality().equals(other.oathType, oathType) &&
|
||||||
(identical(other.oathType, oathType) ||
|
const DeepCollectionEquality().equals(other.period, period) &&
|
||||||
other.oathType == oathType) &&
|
const DeepCollectionEquality()
|
||||||
(identical(other.period, period) || other.period == period) &&
|
.equals(other.touchRequired, touchRequired));
|
||||||
(identical(other.touchRequired, touchRequired) ||
|
|
||||||
other.touchRequired == touchRequired));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType, deviceId, id, issuer, name, oathType, period, touchRequired);
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(deviceId),
|
||||||
|
const DeepCollectionEquality().hash(id),
|
||||||
|
const DeepCollectionEquality().hash(issuer),
|
||||||
|
const DeepCollectionEquality().hash(name),
|
||||||
|
const DeepCollectionEquality().hash(oathType),
|
||||||
|
const DeepCollectionEquality().hash(period),
|
||||||
|
const DeepCollectionEquality().hash(touchRequired));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -429,14 +435,17 @@ class _$_OathCode implements _OathCode {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _OathCode &&
|
other is _OathCode &&
|
||||||
(identical(other.value, value) || other.value == value) &&
|
const DeepCollectionEquality().equals(other.value, value) &&
|
||||||
(identical(other.validFrom, validFrom) ||
|
const DeepCollectionEquality().equals(other.validFrom, validFrom) &&
|
||||||
other.validFrom == validFrom) &&
|
const DeepCollectionEquality().equals(other.validTo, validTo));
|
||||||
(identical(other.validTo, validTo) || other.validTo == validTo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, value, validFrom, validTo);
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(value),
|
||||||
|
const DeepCollectionEquality().hash(validFrom),
|
||||||
|
const DeepCollectionEquality().hash(validTo));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -605,13 +614,16 @@ class _$_OathPair implements _OathPair {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _OathPair &&
|
other is _OathPair &&
|
||||||
(identical(other.credential, credential) ||
|
const DeepCollectionEquality()
|
||||||
other.credential == credential) &&
|
.equals(other.credential, credential) &&
|
||||||
(identical(other.code, code) || other.code == code));
|
const DeepCollectionEquality().equals(other.code, code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, credential, code);
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(credential),
|
||||||
|
const DeepCollectionEquality().hash(code));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -772,14 +784,17 @@ class _$_OathState implements _OathState {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _OathState &&
|
other is _OathState &&
|
||||||
(identical(other.deviceId, deviceId) ||
|
const DeepCollectionEquality().equals(other.deviceId, deviceId) &&
|
||||||
other.deviceId == deviceId) &&
|
const DeepCollectionEquality().equals(other.hasKey, hasKey) &&
|
||||||
(identical(other.hasKey, hasKey) || other.hasKey == hasKey) &&
|
const DeepCollectionEquality().equals(other.locked, locked));
|
||||||
(identical(other.locked, locked) || other.locked == locked));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, deviceId, hasKey, locked);
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(deviceId),
|
||||||
|
const DeepCollectionEquality().hash(hasKey),
|
||||||
|
const DeepCollectionEquality().hash(locked));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -1037,19 +1052,19 @@ class _$_CredentialData extends _CredentialData {
|
|||||||
final String name;
|
final String name;
|
||||||
@override
|
@override
|
||||||
final String secret;
|
final String secret;
|
||||||
@JsonKey(defaultValue: OathType.totp)
|
@JsonKey()
|
||||||
@override
|
@override
|
||||||
final OathType oathType;
|
final OathType oathType;
|
||||||
@JsonKey(defaultValue: HashAlgorithm.sha1)
|
@JsonKey()
|
||||||
@override
|
@override
|
||||||
final HashAlgorithm hashAlgorithm;
|
final HashAlgorithm hashAlgorithm;
|
||||||
@JsonKey(defaultValue: 6)
|
@JsonKey()
|
||||||
@override
|
@override
|
||||||
final int digits;
|
final int digits;
|
||||||
@JsonKey(defaultValue: 30)
|
@JsonKey()
|
||||||
@override
|
@override
|
||||||
final int period;
|
final int period;
|
||||||
@JsonKey(defaultValue: 0)
|
@JsonKey()
|
||||||
@override
|
@override
|
||||||
final int counter;
|
final int counter;
|
||||||
|
|
||||||
@ -1063,21 +1078,28 @@ class _$_CredentialData extends _CredentialData {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _CredentialData &&
|
other is _CredentialData &&
|
||||||
(identical(other.issuer, issuer) || other.issuer == issuer) &&
|
const DeepCollectionEquality().equals(other.issuer, issuer) &&
|
||||||
(identical(other.name, name) || other.name == name) &&
|
const DeepCollectionEquality().equals(other.name, name) &&
|
||||||
(identical(other.secret, secret) || other.secret == secret) &&
|
const DeepCollectionEquality().equals(other.secret, secret) &&
|
||||||
(identical(other.oathType, oathType) ||
|
const DeepCollectionEquality().equals(other.oathType, oathType) &&
|
||||||
other.oathType == oathType) &&
|
const DeepCollectionEquality()
|
||||||
(identical(other.hashAlgorithm, hashAlgorithm) ||
|
.equals(other.hashAlgorithm, hashAlgorithm) &&
|
||||||
other.hashAlgorithm == hashAlgorithm) &&
|
const DeepCollectionEquality().equals(other.digits, digits) &&
|
||||||
(identical(other.digits, digits) || other.digits == digits) &&
|
const DeepCollectionEquality().equals(other.period, period) &&
|
||||||
(identical(other.period, period) || other.period == period) &&
|
const DeepCollectionEquality().equals(other.counter, counter));
|
||||||
(identical(other.counter, counter) || other.counter == counter));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, issuer, name, secret, oathType,
|
int get hashCode => Object.hash(
|
||||||
hashAlgorithm, digits, period, counter);
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(issuer),
|
||||||
|
const DeepCollectionEquality().hash(name),
|
||||||
|
const DeepCollectionEquality().hash(secret),
|
||||||
|
const DeepCollectionEquality().hash(oathType),
|
||||||
|
const DeepCollectionEquality().hash(hashAlgorithm),
|
||||||
|
const DeepCollectionEquality().hash(digits),
|
||||||
|
const DeepCollectionEquality().hash(period),
|
||||||
|
const DeepCollectionEquality().hash(counter));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
|
@ -5,7 +5,7 @@ import '../models.dart';
|
|||||||
import 'account_view.dart';
|
import 'account_view.dart';
|
||||||
|
|
||||||
class AccountList extends StatelessWidget {
|
class AccountList extends StatelessWidget {
|
||||||
final DeviceNode device;
|
final YubiKeyData device;
|
||||||
final List<OathPair> credentials;
|
final List<OathPair> credentials;
|
||||||
final List<String> favorites;
|
final List<String> favorites;
|
||||||
const AccountList(this.device, this.credentials, this.favorites, {Key? key})
|
const AccountList(this.device, this.credentials, this.favorites, {Key? key})
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
import '../../management/models.dart';
|
||||||
import '../../widgets/circle_timer.dart';
|
import '../../widgets/circle_timer.dart';
|
||||||
import '../../app/models.dart';
|
import '../../app/models.dart';
|
||||||
import '../models.dart';
|
import '../models.dart';
|
||||||
@ -35,7 +36,7 @@ class _ExpireNotifier extends StateNotifier<bool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AccountView extends ConsumerWidget {
|
class AccountView extends ConsumerWidget {
|
||||||
final DeviceNode device;
|
final YubiKeyData device;
|
||||||
final OathCredential credential;
|
final OathCredential credential;
|
||||||
final OathCode? code;
|
final OathCode? code;
|
||||||
const AccountView(this.device, this.credential, this.code, {Key? key})
|
const AccountView(this.device, this.credential, this.code, {Key? key})
|
||||||
@ -117,7 +118,7 @@ class AccountView extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await ref
|
await ref
|
||||||
.read(credentialListProvider(device.path).notifier)
|
.read(credentialListProvider(device.node.path).notifier)
|
||||||
.calculate(credential);
|
.calculate(credential);
|
||||||
} finally {
|
} finally {
|
||||||
close?.call();
|
close?.call();
|
||||||
|
@ -6,12 +6,12 @@ import '../state.dart';
|
|||||||
import 'account_list.dart';
|
import 'account_list.dart';
|
||||||
|
|
||||||
class OathScreen extends ConsumerWidget {
|
class OathScreen extends ConsumerWidget {
|
||||||
final DeviceNode device;
|
final YubiKeyData device;
|
||||||
const OathScreen(this.device, {Key? key}) : super(key: key);
|
const OathScreen(this.device, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final state = ref.watch(oathStateProvider(device.path));
|
final state = ref.watch(oathStateProvider(device.node.path));
|
||||||
|
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
return Column(
|
return Column(
|
||||||
@ -35,7 +35,7 @@ class OathScreen extends ConsumerWidget {
|
|||||||
decoration: const InputDecoration(labelText: 'Password'),
|
decoration: const InputDecoration(labelText: 'Password'),
|
||||||
onSubmitted: (value) async {
|
onSubmitted: (value) async {
|
||||||
final result = await ref
|
final result = await ref
|
||||||
.read(oathStateProvider(device.path).notifier)
|
.read(oathStateProvider(device.node.path).notifier)
|
||||||
.unlock(value);
|
.unlock(value);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@ -51,7 +51,7 @@ class OathScreen extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final accounts = ref.watch(credentialListProvider(device.path));
|
final accounts = ref.watch(credentialListProvider(device.node.path));
|
||||||
if (accounts == null) {
|
if (accounts == null) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
@ -323,7 +323,7 @@ packages:
|
|||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2"
|
version: "0.1.3"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -615,7 +615,7 @@ packages:
|
|||||||
name: window_manager
|
name: window_manager
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.4"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -41,7 +41,7 @@ dependencies:
|
|||||||
flutter_riverpod: ^1.0.0
|
flutter_riverpod: ^1.0.0
|
||||||
json_annotation: ^4.3.0
|
json_annotation: ^4.3.0
|
||||||
freezed_annotation: ^1.0.0
|
freezed_annotation: ^1.0.0
|
||||||
window_manager: ^0.1.3
|
window_manager: ^0.1.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit ab71cb6da0f19926400837d0b95fdde075830663
|
Subproject commit 765ccf63d9ccc972858d71730b9712514a9b0e0d
|
Loading…
Reference in New Issue
Block a user