Remove biometric auth

This commit is contained in:
Hillel Coren 2018-09-14 14:35:24 -07:00
parent a8ac3544e2
commit 1cdd5bb406
12 changed files with 10 additions and 186 deletions

View File

@ -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;

View File

@ -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(

View File

@ -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 {

View File

@ -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),
);
}

View File

@ -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);
}

View File

@ -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),
]);

View File

@ -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;

View File

@ -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(),

View File

@ -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),

View File

@ -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,
);
}
}

View File

@ -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'];

View File

@ -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