From 5e56c407f7a08bd2e9ca4fd1e94b0868e7a3b424 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 4 Oct 2020 13:35:48 +0300 Subject: [PATCH] Track login errors --- lib/data/models/account_model.dart | 4 ++-- lib/data/models/client_model.dart | 2 ++ lib/data/models/company_model.dart | 8 ++++++-- lib/main.dart | 9 +++++++++ lib/redux/app/app_actions.dart | 2 +- lib/redux/app/app_middleware.dart | 4 +++- lib/redux/app/app_reducer.dart | 15 +++++++++------ lib/redux/app/app_state.dart | 3 ++- lib/redux/auth/auth_middleware.dart | 5 +++++ lib/redux/company/company_reducer.dart | 2 +- lib/redux/company/company_state.dart | 4 ++-- lib/ui/client/view/client_view_details.dart | 2 +- lib/utils/web.dart | 3 +++ lib/utils/web_stub.dart | 2 ++ pubspec.lock | 2 +- web/index.html | 3 ++- 16 files changed, 51 insertions(+), 19 deletions(-) diff --git a/lib/data/models/account_model.dart b/lib/data/models/account_model.dart index a90b57747..ee566967f 100644 --- a/lib/data/models/account_model.dart +++ b/lib/data/models/account_model.dart @@ -6,7 +6,7 @@ part 'account_model.g.dart'; abstract class AccountEntity implements Built { - factory AccountEntity({String id, AppState state}) { + factory AccountEntity(bool reportErrors, {String id, AppState state}) { return _$AccountEntity._( id: '', defaultUrl: '', @@ -14,7 +14,7 @@ abstract class AccountEntity planExpires: '', latestVersion: '', currentVersion: '', - reportErrors: false, + reportErrors: reportErrors, ); } diff --git a/lib/data/models/client_model.dart b/lib/data/models/client_model.dart index bf88da2b3..637457776 100644 --- a/lib/data/models/client_model.dart +++ b/lib/data/models/client_model.dart @@ -760,6 +760,8 @@ abstract class ContactEntity extends Object String get link; + String get silentLink => '$link?silent=true'; + String get fullName { return (firstName + ' ' + lastName).trim(); } diff --git a/lib/data/models/company_model.dart b/lib/data/models/company_model.dart index d85d7e90b..3db752342 100644 --- a/lib/data/models/company_model.dart +++ b/lib/data/models/company_model.dart @@ -409,6 +409,7 @@ abstract class CompanyEntity extends Object ); bool isModuleEnabled(EntityType entityType) { + /* // TODO remove this if ([ EntityType.project, @@ -418,6 +419,7 @@ abstract class CompanyEntity extends Object ].contains(entityType)) { return false; } + */ if ((entityType == EntityType.invoice || entityType == EntityType.payment) && @@ -572,7 +574,7 @@ abstract class GatewayEntity extends Object abstract class UserCompanyEntity implements Built { - factory UserCompanyEntity() { + factory UserCompanyEntity(bool reportErrors) { return _$UserCompanyEntity._( isAdmin: false, isOwner: false, @@ -580,7 +582,7 @@ abstract class UserCompanyEntity company: CompanyEntity(), user: UserEntity(), token: TokenEntity(), - account: AccountEntity(), + account: AccountEntity(reportErrors), notifications: BuiltMap>().rebuild((b) => b ..[kNotificationChannelEmail] = BuiltList([kNotificationsAll])), @@ -632,6 +634,7 @@ abstract class UserCompanyEntity return true; } + /* // TODO remove this once task/expenses are supported if (!Config.DEMO_MODE && [ @@ -642,6 +645,7 @@ abstract class UserCompanyEntity ].contains(entityType)) { return false; } + */ if (isAdmin ?? false) { return true; diff --git a/lib/main.dart b/lib/main.dart index a6a24f98d..6dd42073d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -146,9 +146,18 @@ Future _initialState(bool isTesting) async { } */ + bool reportErrors = false; + if (kIsWeb) { + reportErrors = WebUtils.getHtmlValue('report-errors') == '1'; + if (reportErrors) { + print('Error reporting is enabled'); + } + } + return AppState( prefState: prefState, currentRoute: currentRoute, url: Config.DEMO_MODE ? '' : url, + reportErrors: reportErrors, ); } diff --git a/lib/redux/app/app_actions.dart b/lib/redux/app/app_actions.dart index 1f6b1cd06..713843f08 100644 --- a/lib/redux/app/app_actions.dart +++ b/lib/redux/app/app_actions.dart @@ -562,7 +562,7 @@ void createEntityByType( force: force, user: UserEntity( state: state, - userCompany: UserCompanyEntity(), + userCompany: UserCompanyEntity(false), ), )); break; diff --git a/lib/redux/app/app_middleware.dart b/lib/redux/app/app_middleware.dart index 40363a6a2..3d1349c58 100644 --- a/lib/redux/app/app_middleware.dart +++ b/lib/redux/app/app_middleware.dart @@ -207,7 +207,9 @@ Middleware _createLoadState( companyStates.add(await companyRepositories[i].loadCompanyState(i)); } - final AppState appState = AppState(prefState: store.state.prefState) + final AppState appState = AppState( + prefState: store.state.prefState, + reportErrors: store.state.account.reportErrors) .rebuild((b) => b ..authState.replace(authState) ..uiState.replace(uiState) diff --git a/lib/redux/app/app_reducer.dart b/lib/redux/app/app_reducer.dart index 08111742e..328dc72ea 100644 --- a/lib/redux/app/app_reducer.dart +++ b/lib/redux/app/app_reducer.dart @@ -33,11 +33,14 @@ import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart'; // We create the State reducer by combining many smaller reducers into one! AppState appReducer(AppState state, dynamic action) { if (action is UserLogout) { - return AppState(prefState: state.prefState).rebuild((b) => b - ..authState.replace(state.authState.rebuild((b) => b - ..isAuthenticated = false - ..lastEnteredPasswordAt = 0)) - ..isTesting = state.isTesting); + return AppState( + prefState: state.prefState, + reportErrors: state.account.reportErrors) + .rebuild((b) => b + ..authState.replace(state.authState.rebuild((b) => b + ..isAuthenticated = false + ..lastEnteredPasswordAt = 0)) + ..isTesting = state.isTesting); } else if (action is LoadStateSuccess) { return action.state.rebuild((b) => b ..isLoading = false @@ -46,7 +49,7 @@ AppState appReducer(AppState state, dynamic action) { return state.rebuild((b) => b ..userCompanyStates.replace(BuiltList( List.generate(kMaxNumberOfCompanies, (i) => i + 1) - .map((index) => UserCompanyState()) + .map((index) => UserCompanyState(state.account.reportErrors)) .toList()))); } diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index b216023c5..a31a3cce6 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -77,6 +77,7 @@ part 'app_state.g.dart'; abstract class AppState implements Built { factory AppState({ @required PrefState prefState, + @required bool reportErrors, String currentRoute, String url, }) { @@ -89,7 +90,7 @@ abstract class AppState implements Built { staticState: StaticState(), userCompanyStates: BuiltList( List.generate(kMaxNumberOfCompanies, (i) => i + 1) - .map((index) => UserCompanyState()) + .map((index) => UserCompanyState(reportErrors)) .toList()), uiState: UIState(currentRoute: currentRoute), prefState: prefState ?? PrefState(), diff --git a/lib/redux/auth/auth_middleware.dart b/lib/redux/auth/auth_middleware.dart index 0ec2b242d..b879a2075 100644 --- a/lib/redux/auth/auth_middleware.dart +++ b/lib/redux/auth/auth_middleware.dart @@ -88,6 +88,7 @@ Middleware _createLoginRequest(AuthRepository repository) { action.completer.completeError(message); } store.dispatch(UserLoginFailure(message)); + throw error; }); next(action); @@ -115,6 +116,7 @@ Middleware _createSignUpRequest(AuthRepository repository) { action.completer.completeError(message); } store.dispatch(UserLoginFailure(message)); + throw error; }); next(action); @@ -148,6 +150,7 @@ Middleware _createOAuthLoginRequest(AuthRepository repository) { action.completer.completeError(message); } store.dispatch(UserLoginFailure(message)); + throw error; }); next(action); @@ -176,6 +179,7 @@ Middleware _createOAuthSignUpRequest(AuthRepository repository) { action.completer.completeError(message); } store.dispatch(UserLoginFailure(message)); + throw error; }); next(action); @@ -229,6 +233,7 @@ Middleware _createRefreshRequest(AuthRepository repository) { action.completer.completeError(message); } store.dispatch(RefreshDataFailure(message)); + throw error; }); next(action); diff --git a/lib/redux/company/company_reducer.dart b/lib/redux/company/company_reducer.dart index 00f1c4460..b4c835c20 100644 --- a/lib/redux/company/company_reducer.dart +++ b/lib/redux/company/company_reducer.dart @@ -32,7 +32,7 @@ import 'package:invoiceninja_flutter/redux/group/group_reducer.dart'; UserCompanyState companyReducer(UserCompanyState state, dynamic action) { if (action is DeleteCompanySuccess) { - return UserCompanyState(); + return UserCompanyState(false); } return state.rebuild((b) => b diff --git a/lib/redux/company/company_state.dart b/lib/redux/company/company_state.dart index aeeae972e..645c1f9f2 100644 --- a/lib/redux/company/company_state.dart +++ b/lib/redux/company/company_state.dart @@ -31,10 +31,10 @@ part 'company_state.g.dart'; abstract class UserCompanyState implements Built { - factory UserCompanyState() { + factory UserCompanyState(bool reportErrors) { return _$UserCompanyState._( lastUpdated: 0, - userCompany: UserCompanyEntity(), + userCompany: UserCompanyEntity(reportErrors), documentState: DocumentState(), productState: ProductState(), clientState: ClientState(), diff --git a/lib/ui/client/view/client_view_details.dart b/lib/ui/client/view/client_view_details.dart index ba015c9bd..162957a3c 100644 --- a/lib/ui/client/view/client_view_details.dart +++ b/lib/ui/client/view/client_view_details.dart @@ -58,7 +58,7 @@ class _ClientViewDetailsState extends State { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)), onPressed: () { - launch('${contact.link}&client_hash=${client.clientHash}', + launch('${contact.silentLink}&client_hash=${client.clientHash}', forceWebView: false, forceSafariVC: false); }, )), diff --git a/lib/utils/web.dart b/lib/utils/web.dart index f5e9926af..20c0946ca 100644 --- a/lib/utils/web.dart +++ b/lib/utils/web.dart @@ -11,6 +11,9 @@ class WebUtils { static String get browserUrl => formatApiUrl(window.location.href.split('#')[0]); + static String getHtmlValue(String field) => + window.document.documentElement.dataset[field]; + static Future filePicker() { final completer = new Completer(); final InputElement input = document.createElement('input'); diff --git a/lib/utils/web_stub.dart b/lib/utils/web_stub.dart index 0c2de93ce..1c0526cab 100644 --- a/lib/utils/web_stub.dart +++ b/lib/utils/web_stub.dart @@ -6,6 +6,8 @@ import 'package:redux/redux.dart'; class WebUtils { static String get browserUrl => null; + static String getHtmlValue(String field) => null; + static Future filePicker() => null; static void downloadTextFile(String filename, String data) {} diff --git a/pubspec.lock b/pubspec.lock index 474eac9aa..bc1b0d321 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -381,7 +381,7 @@ packages: name: flutter_launcher_icons url: "https://pub.dartlang.org" source: hosted - version: "0.8.0" + version: "0.8.1" flutter_localizations: dependency: "direct main" description: flutter diff --git a/web/index.html b/web/index.html index 2c25c7456..2ed622506 100644 --- a/web/index.html +++ b/web/index.html @@ -1,7 +1,8 @@ - + + Invoice Ninja