diff --git a/lib/data/repositories/settings_repository.dart b/lib/data/repositories/settings_repository.dart index f4b44b0c7..0942b85f0 100644 --- a/lib/data/repositories/settings_repository.dart +++ b/lib/data/repositories/settings_repository.dart @@ -87,6 +87,29 @@ class SettingsRepository { return userResponse.data; } + Future disconnectOAuthUser( + Credentials credentials, + UserEntity user, + String password, + String idToken, + ) async { + dynamic response; + + final url = credentials.url + + '/users/${user.id}/disconnect_oauth?include=company_user'; + response = await webClient.post( + url, + credentials.token, + password: password, + idToken: idToken, + ); + + final UserItemResponse userResponse = + serializers.deserializeWith(UserItemResponse.serializer, response); + + return userResponse.data; + } + Future disconnectOAuthMailer( Credentials credentials, String password, diff --git a/lib/redux/settings/settings_actions.dart b/lib/redux/settings/settings_actions.dart index 3ea2648a9..6a1e8aaef 100644 --- a/lib/redux/settings/settings_actions.dart +++ b/lib/redux/settings/settings_actions.dart @@ -163,6 +163,33 @@ class ConnecOAuthUserFailure implements StopSaving { final Object error; } +class DisconnecOAuthUserRequest implements StartSaving { + DisconnecOAuthUserRequest({ + @required this.user, + @required this.idToken, + @required this.completer, + @required this.password, + }); + + final UserEntity user; + final Completer completer; + final String password; + final String idToken; +} + +class DisconnectOAuthUserSuccess + implements StopSaving, PersistData, PersistUI, UserVerifiedPassword { + DisconnectOAuthUserSuccess(this.user); + + final UserEntity user; +} + +class DisconnecOAuthUserFailure implements StopSaving { + DisconnecOAuthUserFailure(this.error); + + final Object error; +} + class DisconnectOAuthMailerRequest implements StartSaving { DisconnectOAuthMailerRequest({ @required this.completer, diff --git a/lib/redux/settings/settings_middleware.dart b/lib/redux/settings/settings_middleware.dart index b7089c377..044ad648a 100644 --- a/lib/redux/settings/settings_middleware.dart +++ b/lib/redux/settings/settings_middleware.dart @@ -29,6 +29,7 @@ List> createStoreSettingsMiddleware([ final saveCompany = _saveCompany(repository); final saveAuthUser = _saveAuthUser(repository); final connectOAuthUser = _connectOAuthUser(repository); + final disconnectOAuthUser = _disconnectOAuthUser(repository); final disconnectOAuthMailer = _disconnectOAuthMailer(repository); final connectGmailUser = _connectGmailUser(repository); final saveSettings = _saveSettings(repository); @@ -41,6 +42,7 @@ List> createStoreSettingsMiddleware([ TypedMiddleware(saveCompany), TypedMiddleware(saveAuthUser), TypedMiddleware(connectOAuthUser), + TypedMiddleware(disconnectOAuthUser), TypedMiddleware( disconnectOAuthMailer), TypedMiddleware(connectGmailUser), @@ -168,6 +170,38 @@ Middleware _connectOAuthUser(SettingsRepository settingsRepository) { }; } +Middleware _disconnectOAuthUser( + SettingsRepository settingsRepository) { + return (Store store, dynamic dynamicAction, NextDispatcher next) { + final action = dynamicAction as DisconnecOAuthUserRequest; + + settingsRepository + .disconnectOAuthUser( + store.state.credentials, + action.user, + action.password, + action.idToken, + ) + .then((user) { + store.dispatch(DisconnectOAuthUserSuccess(user)); + if (action.completer != null) { + action.completer.complete(); + } + }).catchError((Object error) { + print(error); + store.dispatch(DisconnecOAuthUserFailure(error)); + if ('$error'.contains('412')) { + store.dispatch(UserUnverifiedPassword()); + } + if (action.completer != null) { + action.completer.completeError(error); + } + }); + + next(action); + }; +} + Middleware _disconnectOAuthMailer( SettingsRepository settingsRepository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { diff --git a/lib/redux/settings/settings_reducer.dart b/lib/redux/settings/settings_reducer.dart index 7e4739b5e..13254f132 100644 --- a/lib/redux/settings/settings_reducer.dart +++ b/lib/redux/settings/settings_reducer.dart @@ -104,6 +104,12 @@ Reducer settingsUIReducer = combineReducers([ ..origUser.replace(action.user) ..isChanged = false); }), + TypedReducer((state, action) { + return state.rebuild((b) => b + ..user.replace(action.user) + ..origUser.replace(action.user) + ..isChanged = false); + }), TypedReducer((state, action) { return state.rebuild((b) => b ..user.replace(action.user) diff --git a/lib/redux/user/user_reducer.dart b/lib/redux/user/user_reducer.dart index ae9a0b2b8..172de2963 100644 --- a/lib/redux/user/user_reducer.dart +++ b/lib/redux/user/user_reducer.dart @@ -196,6 +196,7 @@ final usersReducer = combineReducers([ TypedReducer(_updateUser), TypedReducer(_updateAuthUser), TypedReducer(_connectOAuthUser), + TypedReducer(_disconnectOAuthUser), TypedReducer(_connectGmailUser), TypedReducer(_disconnectOAuthMailer), TypedReducer(_addUser), @@ -257,6 +258,11 @@ UserState _connectOAuthUser( return userState.rebuild((b) => b..map[action.user.id] = action.user); } +UserState _disconnectOAuthUser( + UserState userState, DisconnectOAuthUserSuccess action) { + return userState.rebuild((b) => b..map[action.user.id] = action.user); +} + UserState _disconnectOAuthMailer( UserState userState, DisconnectOAuthMailerSuccess action) { return userState.rebuild((b) => b..map[action.user.id] = action.user); diff --git a/lib/ui/settings/user_details_vm.dart b/lib/ui/settings/user_details_vm.dart index bcae16e30..4a44ea4b8 100644 --- a/lib/ui/settings/user_details_vm.dart +++ b/lib/ui/settings/user_details_vm.dart @@ -180,8 +180,8 @@ class UserDetailsVM { GoogleOAuth.disconnect(); }); store.dispatch( - SaveAuthUserRequest( - user: state.user.rebuild((b) => b..oauthProvider = ''), + DisconnecOAuthUserRequest( + user: state.user, password: password, idToken: idToken, completer: completer, @@ -244,8 +244,8 @@ class UserDetailsVM { final completer = snackBarCompleter(context, AppLocalization.of(context).disconnectedMicrosoft); store.dispatch( - SaveAuthUserRequest( - user: state.user.rebuild((b) => b..oauthProvider = ''), + DisconnecOAuthUserRequest( + user: state.user, password: password, idToken: idToken, completer: completer, @@ -271,8 +271,8 @@ class UserDetailsVM { final completer = snackBarCompleter( context, AppLocalization.of(context).disconnectedApple); store.dispatch( - SaveAuthUserRequest( - user: state.user.rebuild((b) => b..oauthProvider = ''), + DisconnecOAuthUserRequest( + user: state.user, password: password, idToken: idToken, completer: completer,