Remove biometric auth
This commit is contained in:
parent
a8ac3544e2
commit
1cdd5bb406
|
|
@ -9,7 +9,6 @@ const String kSharedPrefSecret = 'secret';
|
|||
const String kSharedPrefEnableDarkMode = 'enable_dark_mode';
|
||||
const String kSharedPrefEmailPayment = 'email_payment';
|
||||
const String kSharedPrefAppVersion = 'app_version';
|
||||
const String kSharedPrefRequireAuthentication = 'require_authentication';
|
||||
|
||||
const int kMinMajorAppVersion = 4;
|
||||
const int kMinMinorAppVersion = 5;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:invoiceninja_flutter/redux/company/company_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
|
||||
|
|
@ -38,7 +35,6 @@ import 'package:invoiceninja_flutter/redux/product/product_middleware.dart';
|
|||
import 'package:invoiceninja_flutter/redux/invoice/invoice_middleware.dart';
|
||||
import 'package:invoiceninja_flutter/ui/invoice/invoice_screen.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
//import 'package:quick_actions/quick_actions.dart';
|
||||
|
||||
// STARTER: import - do not remove comment
|
||||
|
|
@ -57,13 +53,10 @@ import 'package:invoiceninja_flutter/redux/quote/quote_middleware.dart';
|
|||
void main() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final enableDarkMode = prefs.getBool(kSharedPrefEnableDarkMode) ?? false;
|
||||
final requireAuthentication =
|
||||
prefs.getBool(kSharedPrefRequireAuthentication) ?? false;
|
||||
|
||||
final store = Store<AppState>(appReducer,
|
||||
initialState: AppState(
|
||||
enableDarkMode: enableDarkMode,
|
||||
requireAuthentication: requireAuthentication),
|
||||
enableDarkMode: enableDarkMode),
|
||||
middleware: []
|
||||
..addAll(createStoreAuthMiddleware())
|
||||
..addAll(createStoreDashboardMiddleware())
|
||||
|
|
@ -91,26 +84,6 @@ class InvoiceNinjaApp extends StatefulWidget {
|
|||
}
|
||||
|
||||
class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
||||
bool _authenticated = false;
|
||||
|
||||
Future<Null> _authenticate() async {
|
||||
bool authenticated = false;
|
||||
try {
|
||||
authenticated = await LocalAuthentication().authenticateWithBiometrics(
|
||||
localizedReason: 'Please authenticate to access the app',
|
||||
useErrorDialogs: true,
|
||||
stickyAuth: false);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_authenticated = authenticated;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -130,16 +103,6 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
|||
*/
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
final state = widget.store.state;
|
||||
if (state.uiState.requireAuthentication && !_authenticated) {
|
||||
_authenticate();
|
||||
}
|
||||
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StoreProvider<AppState>(
|
||||
|
|
@ -147,7 +110,6 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
|||
child: AppBuilder(builder: (context) {
|
||||
final state = widget.store.state;
|
||||
Intl.defaultLocale = localeSelector(state);
|
||||
final localization = AppLocalization(Locale(Intl.defaultLocale));
|
||||
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
|
|
@ -155,40 +117,7 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
|||
const AppLocalizationsDelegate(),
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
],
|
||||
home: state.uiState.requireAuthentication && !_authenticated
|
||||
? Material(
|
||||
color: Colors.grey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
FontAwesomeIcons.lock,
|
||||
size: 24.0,
|
||||
color: Colors.grey[400],
|
||||
),
|
||||
SizedBox(
|
||||
width: 12.0,
|
||||
),
|
||||
Text(
|
||||
localization.locked,
|
||||
style: TextStyle(
|
||||
fontSize: 32.0,
|
||||
color: Colors.grey[400],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
RaisedButton(
|
||||
onPressed: () => _authenticate(),
|
||||
child: Text(localization.authenticate),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: InitScreen(),
|
||||
home: InitScreen(),
|
||||
locale: Locale(localeSelector(state)),
|
||||
theme: state.uiState.enableDarkMode
|
||||
? ThemeData(
|
||||
|
|
|
|||
|
|
@ -28,12 +28,8 @@ class LoadStaticSuccess {
|
|||
class UserSettingsChanged implements PersistUI {
|
||||
final bool enableDarkMode;
|
||||
final bool emailPayment;
|
||||
final bool requireAuthentication;
|
||||
|
||||
UserSettingsChanged(
|
||||
{this.enableDarkMode,
|
||||
this.emailPayment,
|
||||
this.requireAuthentication});
|
||||
UserSettingsChanged({this.enableDarkMode, this.emailPayment});
|
||||
}
|
||||
|
||||
class LoadDataSuccess {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ part 'app_state.g.dart';
|
|||
|
||||
abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||
factory AppState(
|
||||
{String appVersion, bool enableDarkMode, bool requireAuthentication}) {
|
||||
{String appVersion, bool enableDarkMode}) {
|
||||
return _$AppState._(
|
||||
isLoading: false,
|
||||
isSaving: false,
|
||||
|
|
@ -33,8 +33,7 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
|||
companyState4: CompanyState(),
|
||||
companyState5: CompanyState(),
|
||||
uiState: UIState(CompanyEntity(),
|
||||
enableDarkMode: enableDarkMode,
|
||||
requireAuthentication: requireAuthentication),
|
||||
enableDarkMode: enableDarkMode),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,13 +43,10 @@ void _loadAuthLocal(Store<AppState> store, dynamic action) async {
|
|||
|
||||
final bool enableDarkMode = prefs.getBool(kSharedPrefEnableDarkMode) ?? false;
|
||||
final bool emailPayment = prefs.getBool(kSharedPrefEmailPayment) ?? false;
|
||||
final bool requireAuthentication =
|
||||
prefs.getBool(kSharedPrefRequireAuthentication) ?? false;
|
||||
|
||||
store.dispatch(UserSettingsChanged(
|
||||
enableDarkMode: enableDarkMode,
|
||||
emailPayment: emailPayment,
|
||||
requireAuthentication: requireAuthentication));
|
||||
emailPayment: emailPayment));
|
||||
|
||||
Navigator.of(action.context).pushReplacementNamed(LoginScreen.route);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ UIState uiReducer(UIState state, dynamic action) {
|
|||
selectedCompanyIndexReducer(state.selectedCompanyIndex, action)
|
||||
..currentRoute = currentRouteReducer(state.currentRoute, action)
|
||||
..enableDarkMode = darkModeReducer(state.enableDarkMode, action)
|
||||
..requireAuthentication = requireAuthenticationReducer(
|
||||
state.requireAuthentication, action)
|
||||
..emailPayment = emailPaymentReducer(state.emailPayment, action)
|
||||
..productUIState.replace(productUIReducer(state.productUIState, action))
|
||||
..clientUIState.replace(clientUIReducer(state.clientUIState, action))
|
||||
|
|
@ -54,15 +52,6 @@ bool updateDarkModeReducer(bool enableDarkMode, UserSettingsChanged action) {
|
|||
return action.enableDarkMode ?? enableDarkMode;
|
||||
}
|
||||
|
||||
Reducer<bool> requireAuthenticationReducer = combineReducers([
|
||||
TypedReducer<bool, UserSettingsChanged>(updateRequireAuthenticationReducer),
|
||||
]);
|
||||
|
||||
bool updateRequireAuthenticationReducer(
|
||||
bool requireAuthentication, UserSettingsChanged action) {
|
||||
return action.requireAuthentication ?? requireAuthentication;
|
||||
}
|
||||
|
||||
Reducer<String> currentRouteReducer = combineReducers([
|
||||
TypedReducer<String, UpdateCurrentRoute>(updateCurrentRouteReducer),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -15,12 +15,11 @@ part 'ui_state.g.dart';
|
|||
|
||||
abstract class UIState implements Built<UIState, UIStateBuilder> {
|
||||
factory UIState(CompanyEntity company,
|
||||
{bool enableDarkMode, bool requireAuthentication}) {
|
||||
{bool enableDarkMode}) {
|
||||
return _$UIState._(
|
||||
selectedCompanyIndex: 0,
|
||||
currentRoute: LoginScreen.route,
|
||||
enableDarkMode: enableDarkMode ?? false,
|
||||
requireAuthentication: requireAuthentication ?? false,
|
||||
emailPayment: false,
|
||||
productUIState: ProductUIState(),
|
||||
clientUIState: ClientUIState(),
|
||||
|
|
@ -40,8 +39,6 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
|
|||
|
||||
bool get enableDarkMode;
|
||||
|
||||
bool get requireAuthentication;
|
||||
|
||||
bool get emailPayment;
|
||||
|
||||
ProductUIState get productUIState;
|
||||
|
|
|
|||
|
|
@ -40,9 +40,6 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
|
|||
'enableDarkMode',
|
||||
serializers.serialize(object.enableDarkMode,
|
||||
specifiedType: const FullType(bool)),
|
||||
'requireAuthentication',
|
||||
serializers.serialize(object.requireAuthentication,
|
||||
specifiedType: const FullType(bool)),
|
||||
'emailPayment',
|
||||
serializers.serialize(object.emailPayment,
|
||||
specifiedType: const FullType(bool)),
|
||||
|
|
@ -95,10 +92,6 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
|
|||
result.enableDarkMode = serializers.deserialize(value,
|
||||
specifiedType: const FullType(bool)) as bool;
|
||||
break;
|
||||
case 'requireAuthentication':
|
||||
result.requireAuthentication = serializers.deserialize(value,
|
||||
specifiedType: const FullType(bool)) as bool;
|
||||
break;
|
||||
case 'emailPayment':
|
||||
result.emailPayment = serializers.deserialize(value,
|
||||
specifiedType: const FullType(bool)) as bool;
|
||||
|
|
@ -142,8 +135,6 @@ class _$UIState extends UIState {
|
|||
@override
|
||||
final bool enableDarkMode;
|
||||
@override
|
||||
final bool requireAuthentication;
|
||||
@override
|
||||
final bool emailPayment;
|
||||
@override
|
||||
final ProductUIState productUIState;
|
||||
|
|
@ -165,7 +156,6 @@ class _$UIState extends UIState {
|
|||
{this.selectedCompanyIndex,
|
||||
this.currentRoute,
|
||||
this.enableDarkMode,
|
||||
this.requireAuthentication,
|
||||
this.emailPayment,
|
||||
this.productUIState,
|
||||
this.clientUIState,
|
||||
|
|
@ -183,9 +173,6 @@ class _$UIState extends UIState {
|
|||
if (enableDarkMode == null) {
|
||||
throw new BuiltValueNullFieldError('UIState', 'enableDarkMode');
|
||||
}
|
||||
if (requireAuthentication == null) {
|
||||
throw new BuiltValueNullFieldError('UIState', 'requireAuthentication');
|
||||
}
|
||||
if (emailPayment == null) {
|
||||
throw new BuiltValueNullFieldError('UIState', 'emailPayment');
|
||||
}
|
||||
|
|
@ -220,7 +207,6 @@ class _$UIState extends UIState {
|
|||
selectedCompanyIndex == other.selectedCompanyIndex &&
|
||||
currentRoute == other.currentRoute &&
|
||||
enableDarkMode == other.enableDarkMode &&
|
||||
requireAuthentication == other.requireAuthentication &&
|
||||
emailPayment == other.emailPayment &&
|
||||
productUIState == other.productUIState &&
|
||||
clientUIState == other.clientUIState &&
|
||||
|
|
@ -240,13 +226,9 @@ class _$UIState extends UIState {
|
|||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(
|
||||
$jc(0,
|
||||
selectedCompanyIndex.hashCode),
|
||||
currentRoute.hashCode),
|
||||
enableDarkMode.hashCode),
|
||||
requireAuthentication.hashCode),
|
||||
$jc($jc(0, selectedCompanyIndex.hashCode),
|
||||
currentRoute.hashCode),
|
||||
enableDarkMode.hashCode),
|
||||
emailPayment.hashCode),
|
||||
productUIState.hashCode),
|
||||
clientUIState.hashCode),
|
||||
|
|
@ -262,7 +244,6 @@ class _$UIState extends UIState {
|
|||
..add('selectedCompanyIndex', selectedCompanyIndex)
|
||||
..add('currentRoute', currentRoute)
|
||||
..add('enableDarkMode', enableDarkMode)
|
||||
..add('requireAuthentication', requireAuthentication)
|
||||
..add('emailPayment', emailPayment)
|
||||
..add('productUIState', productUIState)
|
||||
..add('clientUIState', clientUIState)
|
||||
|
|
@ -291,11 +272,6 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
set enableDarkMode(bool enableDarkMode) =>
|
||||
_$this._enableDarkMode = enableDarkMode;
|
||||
|
||||
bool _requireAuthentication;
|
||||
bool get requireAuthentication => _$this._requireAuthentication;
|
||||
set requireAuthentication(bool requireAuthentication) =>
|
||||
_$this._requireAuthentication = requireAuthentication;
|
||||
|
||||
bool _emailPayment;
|
||||
bool get emailPayment => _$this._emailPayment;
|
||||
set emailPayment(bool emailPayment) => _$this._emailPayment = emailPayment;
|
||||
|
|
@ -341,7 +317,6 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
_selectedCompanyIndex = _$v.selectedCompanyIndex;
|
||||
_currentRoute = _$v.currentRoute;
|
||||
_enableDarkMode = _$v.enableDarkMode;
|
||||
_requireAuthentication = _$v.requireAuthentication;
|
||||
_emailPayment = _$v.emailPayment;
|
||||
_productUIState = _$v.productUIState?.toBuilder();
|
||||
_clientUIState = _$v.clientUIState?.toBuilder();
|
||||
|
|
@ -376,7 +351,6 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
|
|||
selectedCompanyIndex: selectedCompanyIndex,
|
||||
currentRoute: currentRoute,
|
||||
enableDarkMode: enableDarkMode,
|
||||
requireAuthentication: requireAuthentication,
|
||||
emailPayment: emailPayment,
|
||||
productUIState: productUIState.build(),
|
||||
clientUIState: clientUIState.build(),
|
||||
|
|
|
|||
|
|
@ -23,16 +23,6 @@ class SettingsList extends StatelessWidget {
|
|||
secondary: Icon(FontAwesomeIcons.moon),
|
||||
activeColor: Theme.of(context).accentColor,
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalization.of(context).biometricAuthentication),
|
||||
value: viewModel.requireAuthentication,
|
||||
onChanged: (value) =>
|
||||
viewModel.onRequireAuthenticationChanged(context, value),
|
||||
secondary: Icon(viewModel.requireAuthentication
|
||||
? FontAwesomeIcons.lock
|
||||
: FontAwesomeIcons.unlockAlt),
|
||||
activeColor: Theme.of(context).accentColor,
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(FontAwesomeIcons.syncAlt),
|
||||
title: Text(AppLocalization.of(context).refreshData),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
|
|||
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:invoiceninja_flutter/ui/auth/login_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/settings/settings_list.dart';
|
||||
|
|
@ -35,18 +34,13 @@ class SettingsListVM {
|
|||
final Function(BuildContext context) onLogoutTap;
|
||||
final Function(BuildContext context) onRefreshTap;
|
||||
final Function(BuildContext context, bool value) onDarkModeChanged;
|
||||
final Function(BuildContext context, bool value)
|
||||
onRequireAuthenticationChanged;
|
||||
final bool enableDarkMode;
|
||||
final bool requireAuthentication;
|
||||
|
||||
SettingsListVM({
|
||||
@required this.onLogoutTap,
|
||||
@required this.onRefreshTap,
|
||||
@required this.onDarkModeChanged,
|
||||
@required this.onRequireAuthenticationChanged,
|
||||
@required this.enableDarkMode,
|
||||
@required this.requireAuthentication,
|
||||
});
|
||||
|
||||
static SettingsListVM fromStore(Store<AppState> store) {
|
||||
|
|
@ -102,26 +96,7 @@ class SettingsListVM {
|
|||
store.dispatch(UserSettingsChanged(enableDarkMode: value));
|
||||
AppBuilder.of(context).rebuild();
|
||||
},
|
||||
onRequireAuthenticationChanged: (BuildContext context, bool value) async {
|
||||
bool authenticated = false;
|
||||
try {
|
||||
authenticated = await LocalAuthentication()
|
||||
.authenticateWithBiometrics(
|
||||
localizedReason:
|
||||
AppLocalization.of(context).authenticateToChangeSetting,
|
||||
useErrorDialogs: true,
|
||||
stickyAuth: false);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
if (authenticated) {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
prefs.setBool(kSharedPrefRequireAuthentication, value);
|
||||
store.dispatch(UserSettingsChanged(requireAuthentication: value));
|
||||
} else {}
|
||||
},
|
||||
enableDarkMode: store.state.uiState.enableDarkMode,
|
||||
requireAuthentication: store.state.uiState.requireAuthentication,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,6 @@ class AppLocalization {
|
|||
|
||||
static final Map<String, Map<String, String>> _localizedValues = {
|
||||
'en': {
|
||||
'authenticate_to_change_setting':
|
||||
'Please authenticate to change this setting',
|
||||
'locked': 'Locked',
|
||||
'authenticate': 'Authenticate',
|
||||
'please_authenticate': 'Please authenticate',
|
||||
'biometric_authentication': 'Biometric Authentication',
|
||||
'clone_to_invoice': 'Clone to Invoice',
|
||||
'clone_to_quote': 'Clone to Quote',
|
||||
'view_invoice': 'View Invoice',
|
||||
|
|
@ -8328,20 +8322,6 @@ class AppLocalization {
|
|||
},
|
||||
};
|
||||
|
||||
String get authenticateToChangeSetting =>
|
||||
_localizedValues[locale.languageCode]['authenticate_to_change_setting'];
|
||||
|
||||
String get locked => _localizedValues[locale.languageCode]['locked'];
|
||||
|
||||
String get authenticate =>
|
||||
_localizedValues[locale.languageCode]['authenticate'];
|
||||
|
||||
String get pleaseAuthenticate =>
|
||||
_localizedValues[locale.languageCode]['please_authenticate'];
|
||||
|
||||
String get biometricAuthentication =>
|
||||
_localizedValues[locale.languageCode]['biometric_authentication'];
|
||||
|
||||
String get cloneToInvoice =>
|
||||
_localizedValues[locale.languageCode]['clone_to_invoice'];
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ dependencies:
|
|||
cached_network_image: ^0.4.2
|
||||
share: ^0.5.3
|
||||
quick_actions: ^0.2.1
|
||||
local_auth : ^0.2.1
|
||||
intl: ^0.15.7
|
||||
flutter_slidable: ^0.4.6
|
||||
#flutter_html_view: ^0.5.8
|
||||
|
|
|
|||
Loading…
Reference in New Issue