Track login errors
This commit is contained in:
parent
6dcaf9796c
commit
5e56c407f7
|
|
@ -6,7 +6,7 @@ part 'account_model.g.dart';
|
||||||
|
|
||||||
abstract class AccountEntity
|
abstract class AccountEntity
|
||||||
implements Built<AccountEntity, AccountEntityBuilder> {
|
implements Built<AccountEntity, AccountEntityBuilder> {
|
||||||
factory AccountEntity({String id, AppState state}) {
|
factory AccountEntity(bool reportErrors, {String id, AppState state}) {
|
||||||
return _$AccountEntity._(
|
return _$AccountEntity._(
|
||||||
id: '',
|
id: '',
|
||||||
defaultUrl: '',
|
defaultUrl: '',
|
||||||
|
|
@ -14,7 +14,7 @@ abstract class AccountEntity
|
||||||
planExpires: '',
|
planExpires: '',
|
||||||
latestVersion: '',
|
latestVersion: '',
|
||||||
currentVersion: '',
|
currentVersion: '',
|
||||||
reportErrors: false,
|
reportErrors: reportErrors,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -760,6 +760,8 @@ abstract class ContactEntity extends Object
|
||||||
|
|
||||||
String get link;
|
String get link;
|
||||||
|
|
||||||
|
String get silentLink => '$link?silent=true';
|
||||||
|
|
||||||
String get fullName {
|
String get fullName {
|
||||||
return (firstName + ' ' + lastName).trim();
|
return (firstName + ' ' + lastName).trim();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,7 @@ abstract class CompanyEntity extends Object
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isModuleEnabled(EntityType entityType) {
|
bool isModuleEnabled(EntityType entityType) {
|
||||||
|
/*
|
||||||
// TODO remove this
|
// TODO remove this
|
||||||
if ([
|
if ([
|
||||||
EntityType.project,
|
EntityType.project,
|
||||||
|
|
@ -418,6 +419,7 @@ abstract class CompanyEntity extends Object
|
||||||
].contains(entityType)) {
|
].contains(entityType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if ((entityType == EntityType.invoice ||
|
if ((entityType == EntityType.invoice ||
|
||||||
entityType == EntityType.payment) &&
|
entityType == EntityType.payment) &&
|
||||||
|
|
@ -572,7 +574,7 @@ abstract class GatewayEntity extends Object
|
||||||
|
|
||||||
abstract class UserCompanyEntity
|
abstract class UserCompanyEntity
|
||||||
implements Built<UserCompanyEntity, UserCompanyEntityBuilder> {
|
implements Built<UserCompanyEntity, UserCompanyEntityBuilder> {
|
||||||
factory UserCompanyEntity() {
|
factory UserCompanyEntity(bool reportErrors) {
|
||||||
return _$UserCompanyEntity._(
|
return _$UserCompanyEntity._(
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
isOwner: false,
|
isOwner: false,
|
||||||
|
|
@ -580,7 +582,7 @@ abstract class UserCompanyEntity
|
||||||
company: CompanyEntity(),
|
company: CompanyEntity(),
|
||||||
user: UserEntity(),
|
user: UserEntity(),
|
||||||
token: TokenEntity(),
|
token: TokenEntity(),
|
||||||
account: AccountEntity(),
|
account: AccountEntity(reportErrors),
|
||||||
notifications: BuiltMap<String, BuiltList<String>>().rebuild((b) => b
|
notifications: BuiltMap<String, BuiltList<String>>().rebuild((b) => b
|
||||||
..[kNotificationChannelEmail] =
|
..[kNotificationChannelEmail] =
|
||||||
BuiltList<String>(<String>[kNotificationsAll])),
|
BuiltList<String>(<String>[kNotificationsAll])),
|
||||||
|
|
@ -632,6 +634,7 @@ abstract class UserCompanyEntity
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// TODO remove this once task/expenses are supported
|
// TODO remove this once task/expenses are supported
|
||||||
if (!Config.DEMO_MODE &&
|
if (!Config.DEMO_MODE &&
|
||||||
[
|
[
|
||||||
|
|
@ -642,6 +645,7 @@ abstract class UserCompanyEntity
|
||||||
].contains(entityType)) {
|
].contains(entityType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (isAdmin ?? false) {
|
if (isAdmin ?? false) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -146,9 +146,18 @@ Future<AppState> _initialState(bool isTesting) async {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool reportErrors = false;
|
||||||
|
if (kIsWeb) {
|
||||||
|
reportErrors = WebUtils.getHtmlValue('report-errors') == '1';
|
||||||
|
if (reportErrors) {
|
||||||
|
print('Error reporting is enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AppState(
|
return AppState(
|
||||||
prefState: prefState,
|
prefState: prefState,
|
||||||
currentRoute: currentRoute,
|
currentRoute: currentRoute,
|
||||||
url: Config.DEMO_MODE ? '' : url,
|
url: Config.DEMO_MODE ? '' : url,
|
||||||
|
reportErrors: reportErrors,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -562,7 +562,7 @@ void createEntityByType(
|
||||||
force: force,
|
force: force,
|
||||||
user: UserEntity(
|
user: UserEntity(
|
||||||
state: state,
|
state: state,
|
||||||
userCompany: UserCompanyEntity(),
|
userCompany: UserCompanyEntity(false),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,9 @@ Middleware<AppState> _createLoadState(
|
||||||
companyStates.add(await companyRepositories[i].loadCompanyState(i));
|
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
|
.rebuild((b) => b
|
||||||
..authState.replace(authState)
|
..authState.replace(authState)
|
||||||
..uiState.replace(uiState)
|
..uiState.replace(uiState)
|
||||||
|
|
|
||||||
|
|
@ -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!
|
// We create the State reducer by combining many smaller reducers into one!
|
||||||
AppState appReducer(AppState state, dynamic action) {
|
AppState appReducer(AppState state, dynamic action) {
|
||||||
if (action is UserLogout) {
|
if (action is UserLogout) {
|
||||||
return AppState(prefState: state.prefState).rebuild((b) => b
|
return AppState(
|
||||||
..authState.replace(state.authState.rebuild((b) => b
|
prefState: state.prefState,
|
||||||
..isAuthenticated = false
|
reportErrors: state.account.reportErrors)
|
||||||
..lastEnteredPasswordAt = 0))
|
.rebuild((b) => b
|
||||||
..isTesting = state.isTesting);
|
..authState.replace(state.authState.rebuild((b) => b
|
||||||
|
..isAuthenticated = false
|
||||||
|
..lastEnteredPasswordAt = 0))
|
||||||
|
..isTesting = state.isTesting);
|
||||||
} else if (action is LoadStateSuccess) {
|
} else if (action is LoadStateSuccess) {
|
||||||
return action.state.rebuild((b) => b
|
return action.state.rebuild((b) => b
|
||||||
..isLoading = false
|
..isLoading = false
|
||||||
|
|
@ -46,7 +49,7 @@ AppState appReducer(AppState state, dynamic action) {
|
||||||
return state.rebuild((b) => b
|
return state.rebuild((b) => b
|
||||||
..userCompanyStates.replace(BuiltList<UserCompanyState>(
|
..userCompanyStates.replace(BuiltList<UserCompanyState>(
|
||||||
List<int>.generate(kMaxNumberOfCompanies, (i) => i + 1)
|
List<int>.generate(kMaxNumberOfCompanies, (i) => i + 1)
|
||||||
.map((index) => UserCompanyState())
|
.map((index) => UserCompanyState(state.account.reportErrors))
|
||||||
.toList())));
|
.toList())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ part 'app_state.g.dart';
|
||||||
abstract class AppState implements Built<AppState, AppStateBuilder> {
|
abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||||
factory AppState({
|
factory AppState({
|
||||||
@required PrefState prefState,
|
@required PrefState prefState,
|
||||||
|
@required bool reportErrors,
|
||||||
String currentRoute,
|
String currentRoute,
|
||||||
String url,
|
String url,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -89,7 +90,7 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
|
||||||
staticState: StaticState(),
|
staticState: StaticState(),
|
||||||
userCompanyStates: BuiltList(
|
userCompanyStates: BuiltList(
|
||||||
List<int>.generate(kMaxNumberOfCompanies, (i) => i + 1)
|
List<int>.generate(kMaxNumberOfCompanies, (i) => i + 1)
|
||||||
.map((index) => UserCompanyState())
|
.map((index) => UserCompanyState(reportErrors))
|
||||||
.toList()),
|
.toList()),
|
||||||
uiState: UIState(currentRoute: currentRoute),
|
uiState: UIState(currentRoute: currentRoute),
|
||||||
prefState: prefState ?? PrefState(),
|
prefState: prefState ?? PrefState(),
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ Middleware<AppState> _createLoginRequest(AuthRepository repository) {
|
||||||
action.completer.completeError(message);
|
action.completer.completeError(message);
|
||||||
}
|
}
|
||||||
store.dispatch(UserLoginFailure(message));
|
store.dispatch(UserLoginFailure(message));
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
@ -115,6 +116,7 @@ Middleware<AppState> _createSignUpRequest(AuthRepository repository) {
|
||||||
action.completer.completeError(message);
|
action.completer.completeError(message);
|
||||||
}
|
}
|
||||||
store.dispatch(UserLoginFailure(message));
|
store.dispatch(UserLoginFailure(message));
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
@ -148,6 +150,7 @@ Middleware<AppState> _createOAuthLoginRequest(AuthRepository repository) {
|
||||||
action.completer.completeError(message);
|
action.completer.completeError(message);
|
||||||
}
|
}
|
||||||
store.dispatch(UserLoginFailure(message));
|
store.dispatch(UserLoginFailure(message));
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
@ -176,6 +179,7 @@ Middleware<AppState> _createOAuthSignUpRequest(AuthRepository repository) {
|
||||||
action.completer.completeError(message);
|
action.completer.completeError(message);
|
||||||
}
|
}
|
||||||
store.dispatch(UserLoginFailure(message));
|
store.dispatch(UserLoginFailure(message));
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
@ -229,6 +233,7 @@ Middleware<AppState> _createRefreshRequest(AuthRepository repository) {
|
||||||
action.completer.completeError(message);
|
action.completer.completeError(message);
|
||||||
}
|
}
|
||||||
store.dispatch(RefreshDataFailure(message));
|
store.dispatch(RefreshDataFailure(message));
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import 'package:invoiceninja_flutter/redux/group/group_reducer.dart';
|
||||||
|
|
||||||
UserCompanyState companyReducer(UserCompanyState state, dynamic action) {
|
UserCompanyState companyReducer(UserCompanyState state, dynamic action) {
|
||||||
if (action is DeleteCompanySuccess) {
|
if (action is DeleteCompanySuccess) {
|
||||||
return UserCompanyState();
|
return UserCompanyState(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.rebuild((b) => b
|
return state.rebuild((b) => b
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,10 @@ part 'company_state.g.dart';
|
||||||
|
|
||||||
abstract class UserCompanyState
|
abstract class UserCompanyState
|
||||||
implements Built<UserCompanyState, UserCompanyStateBuilder> {
|
implements Built<UserCompanyState, UserCompanyStateBuilder> {
|
||||||
factory UserCompanyState() {
|
factory UserCompanyState(bool reportErrors) {
|
||||||
return _$UserCompanyState._(
|
return _$UserCompanyState._(
|
||||||
lastUpdated: 0,
|
lastUpdated: 0,
|
||||||
userCompany: UserCompanyEntity(),
|
userCompany: UserCompanyEntity(reportErrors),
|
||||||
documentState: DocumentState(),
|
documentState: DocumentState(),
|
||||||
productState: ProductState(),
|
productState: ProductState(),
|
||||||
clientState: ClientState(),
|
clientState: ClientState(),
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class _ClientViewDetailsState extends State<ClientViewDetails> {
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
launch('${contact.link}&client_hash=${client.clientHash}',
|
launch('${contact.silentLink}&client_hash=${client.clientHash}',
|
||||||
forceWebView: false, forceSafariVC: false);
|
forceWebView: false, forceSafariVC: false);
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ class WebUtils {
|
||||||
static String get browserUrl =>
|
static String get browserUrl =>
|
||||||
formatApiUrl(window.location.href.split('#')[0]);
|
formatApiUrl(window.location.href.split('#')[0]);
|
||||||
|
|
||||||
|
static String getHtmlValue(String field) =>
|
||||||
|
window.document.documentElement.dataset[field];
|
||||||
|
|
||||||
static Future<String> filePicker() {
|
static Future<String> filePicker() {
|
||||||
final completer = new Completer<String>();
|
final completer = new Completer<String>();
|
||||||
final InputElement input = document.createElement('input');
|
final InputElement input = document.createElement('input');
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import 'package:redux/redux.dart';
|
||||||
class WebUtils {
|
class WebUtils {
|
||||||
static String get browserUrl => null;
|
static String get browserUrl => null;
|
||||||
|
|
||||||
|
static String getHtmlValue(String field) => null;
|
||||||
|
|
||||||
static Future<String> filePicker() => null;
|
static Future<String> filePicker() => null;
|
||||||
|
|
||||||
static void downloadTextFile(String filename, String data) {}
|
static void downloadTextFile(String filename, String data) {}
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@ packages:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.8.1"
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html data-report-errors="1">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="report_errors" content="1">
|
||||||
<title>Invoice Ninja</title>
|
<title>Invoice Ninja</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue