Code refactor
This commit is contained in:
parent
79485f6c95
commit
43229f57d6
|
|
@ -79,6 +79,13 @@ class AuthRepository {
|
||||||
return sendRequest(url: url, data: credentials, secret: secret);
|
return sendRequest(url: url, data: credentials, secret: secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<dynamic> logout({@required Credentials credentials}) async {
|
||||||
|
return webClient.post(
|
||||||
|
'${credentials.url}/logout',
|
||||||
|
credentials.token,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<LoginResponse> oauthLogin(
|
Future<LoginResponse> oauthLogin(
|
||||||
{@required String idToken,
|
{@required String idToken,
|
||||||
@required String accessToken,
|
@required String accessToken,
|
||||||
|
|
@ -87,7 +94,6 @@ class AuthRepository {
|
||||||
@required String platform}) async {
|
@required String platform}) async {
|
||||||
final credentials = {
|
final credentials = {
|
||||||
'id_token': idToken,
|
'id_token': idToken,
|
||||||
//'access_token': accessToken,
|
|
||||||
'provider': 'google',
|
'provider': 'google',
|
||||||
};
|
};
|
||||||
url = formatApiUrl(url) + '/oauth_login';
|
url = formatApiUrl(url) + '/oauth_login';
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ Middleware<AppState> _createLoadState(
|
||||||
store.dispatch(RefreshData(
|
store.dispatch(RefreshData(
|
||||||
completer: Completer<Null>()
|
completer: Completer<Null>()
|
||||||
..future.catchError((Object error) {
|
..future.catchError((Object error) {
|
||||||
store.dispatch(UserLogout(action.context));
|
store.dispatch(UserLogout());
|
||||||
})));
|
})));
|
||||||
|
|
||||||
if (uiState.currentRoute != LoginScreen.route &&
|
if (uiState.currentRoute != LoginScreen.route &&
|
||||||
|
|
@ -303,11 +303,11 @@ Middleware<AppState> _createLoadState(
|
||||||
}
|
}
|
||||||
}).catchError((Object error) {
|
}).catchError((Object error) {
|
||||||
print('Error (app_middleware - refresh): $error');
|
print('Error (app_middleware - refresh): $error');
|
||||||
store.dispatch(UserLogout(action.context));
|
store.dispatch(UserLogout());
|
||||||
});
|
});
|
||||||
store.dispatch(RefreshData(completer: completer, clearData: true));
|
store.dispatch(RefreshData(completer: completer, clearData: true));
|
||||||
} else {
|
} else {
|
||||||
store.dispatch(UserLogout(action.context));
|
store.dispatch(UserLogout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,18 @@ class RecoverPasswordFailure implements StopLoading {
|
||||||
final Object error;
|
final Object error;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserLogout implements PersistData, PersistUI {
|
class UserLogout implements PersistData, PersistUI {}
|
||||||
UserLogout(this.context, {this.navigate = true});
|
|
||||||
|
|
||||||
final BuildContext context;
|
class UserLogoutAll implements StartLoading {
|
||||||
final bool navigate;
|
const UserLogoutAll({this.completer});
|
||||||
|
final Completer completer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserLogoutAllSuccess implements StopLoading {}
|
||||||
|
|
||||||
|
class UserLogoutAllFailure implements StopLoading {
|
||||||
|
const UserLogoutAllFailure(this.error);
|
||||||
|
final Object error;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserSignUpRequest implements StartLoading {
|
class UserSignUpRequest implements StartLoading {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ List<Middleware<AppState>> createStoreAuthMiddleware([
|
||||||
AuthRepository repository = const AuthRepository(),
|
AuthRepository repository = const AuthRepository(),
|
||||||
]) {
|
]) {
|
||||||
final userLogout = _createUserLogout();
|
final userLogout = _createUserLogout();
|
||||||
|
final userLogoutAll = _createUserLogoutAll(repository);
|
||||||
final loginRequest = _createLoginRequest(repository);
|
final loginRequest = _createLoginRequest(repository);
|
||||||
final oauthLoginRequest = _createOAuthLoginRequest(repository);
|
final oauthLoginRequest = _createOAuthLoginRequest(repository);
|
||||||
final signUpRequest = _createSignUpRequest(repository);
|
final signUpRequest = _createSignUpRequest(repository);
|
||||||
|
|
@ -33,6 +34,7 @@ List<Middleware<AppState>> createStoreAuthMiddleware([
|
||||||
|
|
||||||
return [
|
return [
|
||||||
TypedMiddleware<AppState, UserLogout>(userLogout),
|
TypedMiddleware<AppState, UserLogout>(userLogout),
|
||||||
|
TypedMiddleware<AppState, UserLogoutAll>(userLogoutAll),
|
||||||
TypedMiddleware<AppState, UserLoginRequest>(loginRequest),
|
TypedMiddleware<AppState, UserLoginRequest>(loginRequest),
|
||||||
TypedMiddleware<AppState, OAuthLoginRequest>(oauthLoginRequest),
|
TypedMiddleware<AppState, OAuthLoginRequest>(oauthLoginRequest),
|
||||||
TypedMiddleware<AppState, UserSignUpRequest>(signUpRequest),
|
TypedMiddleware<AppState, UserSignUpRequest>(signUpRequest),
|
||||||
|
|
@ -57,15 +59,35 @@ Middleware<AppState> _createUserLogout() {
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
||||||
if (action.navigate) {
|
navigatorKey.currentState.pushNamedAndRemoveUntil(
|
||||||
navigatorKey.currentState.pushNamedAndRemoveUntil(
|
LoginScreen.route, (Route<dynamic> route) => false);
|
||||||
LoginScreen.route, (Route<dynamic> route) => false);
|
|
||||||
}
|
|
||||||
|
|
||||||
store.dispatch(UpdateCurrentRoute(LoginScreen.route));
|
store.dispatch(UpdateCurrentRoute(LoginScreen.route));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Middleware<AppState> _createUserLogoutAll(AuthRepository repository) {
|
||||||
|
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||||
|
final action = dynamicAction as UserLogoutAll;
|
||||||
|
|
||||||
|
repository
|
||||||
|
.logout(credentials: store.state.credentials)
|
||||||
|
.then((dynamic response) {
|
||||||
|
print('## DONE MIDDLE');
|
||||||
|
|
||||||
|
store.dispatch(UserLogoutAllSuccess());
|
||||||
|
store.dispatch(UserLogout());
|
||||||
|
}).catchError((Object error) {
|
||||||
|
if (action.completer != null) {
|
||||||
|
//action.completer.completeError(error);
|
||||||
|
}
|
||||||
|
store.dispatch(UserLogoutAllFailure(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
next(action);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Middleware<AppState> _createLoginRequest(AuthRepository repository) {
|
Middleware<AppState> _createLoginRequest(AuthRepository repository) {
|
||||||
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
|
||||||
final action = dynamicAction as UserLoginRequest;
|
final action = dynamicAction as UserLoginRequest;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ class _DesktopSessionTimeoutState extends State<DesktopSessionTimeout> {
|
||||||
state.userCompanyState.lastUpdated;
|
state.userCompanyState.lastUpdated;
|
||||||
|
|
||||||
if (sessionLength > sessionTimeout) {
|
if (sessionLength > sessionTimeout) {
|
||||||
store.dispatch(UserLogout(context));
|
store.dispatch(UserLogout());
|
||||||
} else if (sessionLength > (sessionTimeout - (1000 * 60 * 2))) {
|
} else if (sessionLength > (sessionTimeout - (1000 * 60 * 2))) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isWarned = true;
|
_isWarned = true;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class ErrorDialog extends StatelessWidget {
|
||||||
confirmCallback(
|
confirmCallback(
|
||||||
context: context,
|
context: context,
|
||||||
callback: () {
|
callback: () {
|
||||||
store.dispatch(UserLogout(context));
|
store.dispatch(UserLogout());
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
TextButton(
|
TextButton(
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ class MenuDrawerVM {
|
||||||
message: AppLocalization.of(context).logout,
|
message: AppLocalization.of(context).logout,
|
||||||
context: context,
|
context: context,
|
||||||
callback: () async {
|
callback: () async {
|
||||||
store.dispatch(UserLogout(context));
|
store.dispatch(UserLogout());
|
||||||
if (store.state.user.isConnectedToGoogle) {
|
if (store.state.user.isConnectedToGoogle) {
|
||||||
GoogleOAuth.signOut();
|
GoogleOAuth.signOut();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,7 @@ class _MobileSessionTimeoutState extends State<MobileSessionTimeout> {
|
||||||
state.userCompanyState.lastUpdated;
|
state.userCompanyState.lastUpdated;
|
||||||
|
|
||||||
if (sessionLength > sessionTimeout) {
|
if (sessionLength > sessionTimeout) {
|
||||||
store.dispatch(UserLogout(context, navigate: false));
|
store.dispatch(UserLogout());
|
||||||
WidgetsBinding.instance.addPostFrameCallback((duration) {
|
|
||||||
WebUtils.reloadBrowser();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class AccountManagementVM {
|
||||||
final context = navigatorKey.currentContext;
|
final context = navigatorKey.currentContext;
|
||||||
final state = store.state;
|
final state = store.state;
|
||||||
if (companyLength == 1) {
|
if (companyLength == 1) {
|
||||||
store.dispatch(UserLogout(context));
|
store.dispatch(UserLogout());
|
||||||
if (state.user.isConnectedToGoogle) {
|
if (state.user.isConnectedToGoogle) {
|
||||||
GoogleOAuth.disconnect();
|
GoogleOAuth.disconnect();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,11 @@ class _DeviceSettingsState extends State<DeviceSettings> {
|
||||||
final viewModel = widget.viewModel;
|
final viewModel = widget.viewModel;
|
||||||
final state = viewModel.state;
|
final state = viewModel.state;
|
||||||
final prefState = state.prefState;
|
final prefState = state.prefState;
|
||||||
|
final countSessions = state.tokenState.list
|
||||||
|
.map((tokenId) => state.tokenState.map[tokenId])
|
||||||
|
.where(
|
||||||
|
(token) => token.isSystem && token.createdUserId == state.user.id)
|
||||||
|
.length;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
|
@ -247,6 +252,15 @@ class _DeviceSettingsState extends State<DeviceSettings> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(Icons.logout),
|
||||||
|
title: Text(localization.endAllSessions),
|
||||||
|
subtitle: Text(countSessions == 1
|
||||||
|
? localization.countSession
|
||||||
|
: localization.countSession
|
||||||
|
.replaceFirst(':count', '$countSessions')),
|
||||||
|
onTap: () => viewModel.onLogoutTap(context),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:invoiceninja_flutter/constants.dart';
|
import 'package:invoiceninja_flutter/constants.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/auth/auth_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart';
|
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
|
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
|
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
|
||||||
|
|
@ -34,6 +35,7 @@ class DeviceSettingsVM {
|
||||||
DeviceSettingsVM({
|
DeviceSettingsVM({
|
||||||
@required this.state,
|
@required this.state,
|
||||||
@required this.onRefreshTap,
|
@required this.onRefreshTap,
|
||||||
|
@required this.onLogoutTap,
|
||||||
@required this.onDarkModeChanged,
|
@required this.onDarkModeChanged,
|
||||||
@required this.onLayoutChanged,
|
@required this.onLayoutChanged,
|
||||||
@required this.onRequireAuthenticationChanged,
|
@required this.onRequireAuthenticationChanged,
|
||||||
|
|
@ -71,6 +73,11 @@ class DeviceSettingsVM {
|
||||||
return DeviceSettingsVM(
|
return DeviceSettingsVM(
|
||||||
state: store.state,
|
state: store.state,
|
||||||
onRefreshTap: (BuildContext context) => _refreshData(context),
|
onRefreshTap: (BuildContext context) => _refreshData(context),
|
||||||
|
onLogoutTap: (BuildContext context) {
|
||||||
|
final completer = snackBarCompleter<Null>(
|
||||||
|
context, AppLocalization.of(context).endedAllSessions);
|
||||||
|
store.dispatch(UserLogoutAll(completer: completer));
|
||||||
|
},
|
||||||
onDarkModeChanged: (BuildContext context, bool value) async {
|
onDarkModeChanged: (BuildContext context, bool value) async {
|
||||||
store.dispatch(UpdateUserPreferences(enableDarkMode: value));
|
store.dispatch(UpdateUserPreferences(enableDarkMode: value));
|
||||||
AppBuilder.of(context).rebuild();
|
AppBuilder.of(context).rebuild();
|
||||||
|
|
@ -151,6 +158,7 @@ class DeviceSettingsVM {
|
||||||
|
|
||||||
final AppState state;
|
final AppState state;
|
||||||
final Function(BuildContext) onRefreshTap;
|
final Function(BuildContext) onRefreshTap;
|
||||||
|
final Function(BuildContext) onLogoutTap;
|
||||||
final Function(BuildContext, bool) onDarkModeChanged;
|
final Function(BuildContext, bool) onDarkModeChanged;
|
||||||
final Function(BuildContext, AppLayout) onLayoutChanged;
|
final Function(BuildContext, AppLayout) onLayoutChanged;
|
||||||
final Function(BuildContext, AppSidebarMode) onMenuModeChanged;
|
final Function(BuildContext, AppSidebarMode) onMenuModeChanged;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
static final Map<String, Map<String, String>> _localizedValues = {
|
static final Map<String, Map<String, String>> _localizedValues = {
|
||||||
'en': {
|
'en': {
|
||||||
// STARTER: lang key - do not remove comment
|
// STARTER: lang key - do not remove comment
|
||||||
|
'ended_all_sessions': 'Successfully ended all sessions',
|
||||||
|
'end_all_sessions': 'End All Sessions',
|
||||||
|
'count_session': '1 Session',
|
||||||
|
'count_sessions': ':count Sessions',
|
||||||
'invoice_created': 'Invoice Created',
|
'invoice_created': 'Invoice Created',
|
||||||
'quote_created': 'Quote Created',
|
'quote_created': 'Quote Created',
|
||||||
'credit_created': 'Credit Created',
|
'credit_created': 'Credit Created',
|
||||||
|
|
@ -60306,6 +60310,22 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
_localizedValues[localeCode]['credit_created'] ??
|
_localizedValues[localeCode]['credit_created'] ??
|
||||||
_localizedValues['en']['credit_created'];
|
_localizedValues['en']['credit_created'];
|
||||||
|
|
||||||
|
String get endAllSessions =>
|
||||||
|
_localizedValues[localeCode]['end_all_sessions'] ??
|
||||||
|
_localizedValues['en']['end_all_sessions'];
|
||||||
|
|
||||||
|
String get countSession =>
|
||||||
|
_localizedValues[localeCode]['count_session'] ??
|
||||||
|
_localizedValues['en']['count_session'];
|
||||||
|
|
||||||
|
String get countSessions =>
|
||||||
|
_localizedValues[localeCode]['count_sessions'] ??
|
||||||
|
_localizedValues['en']['count_sessions'];
|
||||||
|
|
||||||
|
String get endedAllSessions =>
|
||||||
|
_localizedValues[localeCode]['ended_all_sessions'] ??
|
||||||
|
_localizedValues['en']['ended_all_sessions'];
|
||||||
|
|
||||||
String lookup(String key) {
|
String lookup(String key) {
|
||||||
final lookupKey = toSnakeCase(key);
|
final lookupKey = toSnakeCase(key);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue