forked from eatvio/eatvio_app
feat(session): centralize session teardown and refresh
Add SessionLifecycleService to reset user-scoped cubits, analytics, socket id and account-scoped preferences on logout, 401 or account deletion. Run the same refresh after every successful auth path, including registration v1/v2, and ignore 401 responses from stale tokens so an old request cannot terminate the new user's session. Refs: #1113
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/core/session/session_lifecycle_service.dart';
|
||||
import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -7,7 +8,11 @@ import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class MenuCubit extends Cubit<MenuState> {
|
||||
final ProfileRepository profileRepository;
|
||||
MenuCubit(this.profileRepository) : super(const MenuState.initial());
|
||||
final SessionLifecycleService sessionLifecycleService;
|
||||
MenuCubit(this.profileRepository, this.sessionLifecycleService)
|
||||
: super(const MenuState.initial());
|
||||
|
||||
Future<void> logout() => sessionLifecycleService.logout();
|
||||
|
||||
Future<void> getMyProfile() async {
|
||||
emit(const MenuState.loading());
|
||||
@@ -23,7 +28,10 @@ class MenuCubit extends Cubit<MenuState> {
|
||||
|
||||
Future<String?> makePassKey() async {
|
||||
try {
|
||||
final passKey = await profileRepository.getPassKey(routeName: 'product_nutritional_value.index', routeParams: {});
|
||||
final passKey = await profileRepository.getPassKey(
|
||||
routeName: 'product_nutritional_value.index',
|
||||
routeParams: {},
|
||||
);
|
||||
return passKey;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/error_reporter.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/firebase_api.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/websockets/ws_manager.dart';
|
||||
import 'package:eatvio_app/features/consultant_rating/presentation/consultant_rating_screen.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultant_finances_screen.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart';
|
||||
import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_cubit.dart';
|
||||
import 'package:eatvio_app/features/video_calls/presentation/bloc/video_call_session/video_call_session_cubit.dart';
|
||||
import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_state.dart';
|
||||
import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart';
|
||||
import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart';
|
||||
@@ -155,6 +148,7 @@ class MenuScreen extends StatelessWidget {
|
||||
|
||||
Future<Null> Function() _onTapLogout(BuildContext context) {
|
||||
return () async {
|
||||
final menuCubit = context.read<MenuCubit>();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CupertinoAlertDialog(
|
||||
@@ -162,25 +156,8 @@ class MenuScreen extends StatelessWidget {
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () async {
|
||||
try {
|
||||
// Logout revokes the Sanctum token. Unregister first, or
|
||||
// FCM / VoIP tokens stay on the server and calls still ring.
|
||||
await sl<FirebaseApi>().unregisterPushTokens();
|
||||
} catch (e, s) {
|
||||
await sl<ErrorReporter>().report(e, s, origin: 'MenuScreen');
|
||||
}
|
||||
try {
|
||||
await sl<Dio>().post('${sl<AppConfig>().baseUrl}/api/profile/logout');
|
||||
} catch (e, s) {
|
||||
await sl<ErrorReporter>().report(e, s, origin: 'MenuScreen');
|
||||
} finally {
|
||||
await sl<VideoCallSessionCubit>().endCall();
|
||||
await sl<WsManager>().clear();
|
||||
await TokenStorage.removeTokenInStorage();
|
||||
if (context.mounted) {
|
||||
GoRouter.of(context).go('/auth-screen', extra: true);
|
||||
}
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
await menuCubit.logout();
|
||||
},
|
||||
isDestructiveAction: true,
|
||||
child: const Text("Выйти"),
|
||||
|
||||
Reference in New Issue
Block a user