Coder Social home page Coder Social logo

sankethbk / local_session_timeout Goto Github PK

View Code? Open in Web Editor NEW
12.0 3.0 19.0 225 KB

Redirect user to authentication page if the application doesn't receive any user interaction, or been running in the background for "x" duration.

Home Page: https://pub.dev/packages/local_session_timeout

License: BSD 3-Clause "New" or "Revised" License

Dart 81.90% Swift 1.80% Objective-C 2.85% Ruby 6.03% Java 2.30% Shell 5.12%
flutter

local_session_timeout's Issues

Warning alert with timer reducing before logout

Right now current features are working fine whatever is implemented in this plugin. But one more feature should be included in this

Requirement is :

Prior to logging out at the designated time, it is our intention to display an alert containing relevant content. This alert will offer the user the option to "remain signed in."

Handle SessionTimeoutManager.sessionConfig change

Hi,
I have a use case where SessionTimeoutManager.sessionConfig can change at any time through user settings (user can set invalidateSessionForUserInactivity timeout through settings screen/page).

When SessionTimeoutManager.sessionConfig changes, SessionTimeoutManager doesn't handle the change at all.
I would expect internal timer _userInactivityTimer would be reset in this case, so the new setting would be applied immediately - currently the new setting is applied when first user activity is detected?

Not working on desktop

Can anyone else confirm? I believe flutter still doesn't support lifecycle on desktop and I can see the source of this using the built in lifecycle feature.

Upgrading to Flutter 3.0 shows warning

Error Message
/D:/flutter_windows_3.0.3-stable/.pub-cache/hosted/pub.dartlang.org/local_session_timeout-0.2.0/lib/src/session_timeout_manager.dart:35:20: Warning: Operand of null-aware operation '?.' has type 'WidgetsBinding' which excludes null.

  • 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('/D:/flutter_windows_3.0.3-stable/packages/flutter/lib/src/widgets/binding.dart').
    package:flutter/โ€ฆ/widgets/binding.dart:1
    WidgetsBinding.instance?.addObserver(this);

Because of this warning, when session timeout has ended it is not navigating to Login Page.

timeoutEvent == SessionTimeoutState.userInactivityTimeout

hey,

i installed your package and in my test, it looks like this function keep triggering when i'm active no the way around !

  if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
        // handle user  inactive timeout
        // Navigator.of(context).pushNamed("/auth");

  
      }

reset timer when user interactive on ui

 child: Listener(
            onPointerDown: (event) {
              sessionStateStream.add(SessionState.stopListening);
            },
            onPointerUp: (event) {
              sessionStateStream.add(SessionState.startListening);
            },
            child: Stack(...

I try to detect user activity on the reading page like this but after do like this timer does not start again is it the limit to this lib? or what am I doing wrong?

Timeout event is not firing when duration set to 8 hours and app is in background

Hi,

Thank u for the useful library.

I am facing an issue. I have used the below code

final sessionConfig = SessionConfig(
    invalidateSessionForAppLostFocus: const Duration(hours: 8),
    invalidateSessionForUserInactivity: const Duration(hours: 8));

I kept the app in the background for more than 8 hours and when I opened the app again, the timeout event was not firing. (it is supposed to redirect to the login screen after 8. hours) .

Irregular Session State Stream behaviour

I have my SessionStateStream set up in a Provider using River Pod like so:

final inactivityManagerProvider = ChangeNotifierProvider(
  (ref) => InactivityManagerViewModel(),
);

class InactivityManagerViewModel with ChangeNotifier {
  var sessionStateStream = StreamController<SessionState>();

  SessionConfig? sessionConfig;
}

In MyApp's build method, I have initialized it like this:

final timeOutProvider = ref.watch(inactivityManagerProvider);
    timeOutProvider.sessionConfig = SessionConfig(
      invalidateSessionForAppLostFocus: const Duration(seconds: 40),
      invalidateSessionForUserInactivity: const Duration(seconds: 40),
    );
    timeOutProvider.sessionConfig?.stream.listen((timeOutEvent) async {
      // timeOutProvider.sessionStateStream.add(SessionState.stopListening);
      if (timeOutEvent == SessionTimeoutState.userInactivityTimeout) {
        await ref
            .read(authenticationProvider)
            .signOut(authToken: getIt<UserDependencies>().getAuthToken())
            .then((value) {
          NotificationManager.topBarNotifyError("Signed Out Due to Inactivity");
        });
      } else if (timeOutEvent == SessionTimeoutState.appFocusTimeout) {
        await ref
            .read(authenticationProvider)
            .signOut(authToken: getIt<UserDependencies>().getAuthToken())
            .then((value) {
          NotificationManager.topBarNotifyError("Signed Out Due to Inactivity");
        });
      }
    });
But whenever I want to use the sessionStateStream.add(SessionState.startListenint) from the provider, it pops the screen I'm going to and I'm not sure why.

Not getting it to work

I'm trying to apply this plugin to detect idle activity to log users out. Eventually, I used Riverpod per the documentation, but I wasn't getting any event from the stream. Then I copied the example code from the example folder, but still not detecting any event.

I'm testing on an Xcode simulator ios 16.0 and ios physical device.

Is there some sort of configuration I'm missing or something?

suggestion

Hey,

i really like this package, it does what i need, but one thing is missing, is when user deletes the app .

my app has rooms, and i use the package to kick user out after being inactive for x amount of time.

but if user deletes the app then the user will not be kicked .

i hope you consider adding this to the package

thank you

Session manager times out on auth screen

Session manager still times out on auth screen even after i stop listening or havent started listerning at all.
ie. I start listening after login button is clicked.

i use the sample code presented in pub.dev

 final sessionConfig = SessionConfig(
      invalidateSessionForAppLostFocus: const Duration(seconds: 30),
      invalidateSessionForUserInactivity: const Duration(minutes: 1),
    );
    sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
      // stop listening, as user will already be in login page
      appModel?.sessionStateStream.add(SessionState.stopListening);

      if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
        appModel?.handleTimeoutAndLogin();
      } else if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
        appModel?.handleTimeoutAndLogin();
      }
    });  

and i dont start listening till i click the button on login. I dont understand why then it times out on login/auth screen

Localizations Delegate

Hi,

I have this issue where the whole MaterialApp() seems like rebuild whenever i try to do sessionStateStream.add().
After troubleshooting a while i found out that after i remove the AppLocalizations delegate from my MaterialApp(), it is working as usual without keep rebuilding everytime i do sessionStateStream.add().
Do you have any idea what is going on?

Thanks in advance.

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final AuthBloc _signInBloc = AuthBloc();
  
  @override
  Widget build(BuildContext context) {
    final sessionConfig = SessionConfig(
      invalidateSessionForAppLostFocus: const Duration(seconds: 240),
      invalidateSessionForUserInactivity: const Duration(seconds: 240),
    );
    sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
      // stop listening, as user will already be in auth page
      _signInBloc.state.sessionStateStream.add(SessionState.stopListening);
      if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
        // handle user  inactive timeout
        _signInBloc.add(Logout());
        navigatorKey.currentState?.popUntil((route) => route.isFirst);
      } else if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
        _signInBloc.add(Logout());
        navigatorKey.currentState?.popUntil((route) => route.isFirst);
      }
    });
    return SessionTimeoutManager(
      sessionConfig: sessionConfig,
      sessionStateStream: _signInBloc.state.sessionStateStream.stream,
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: !appStore.isDarkModeOn
            ? AppThemeData.lightTheme
            : AppThemeData.darkTheme,
        onGenerateRoute: (settings) {
          return generateRoute(settings, _signInBloc, sessionConfig);
        },
        navigatorKey: navigatorKey,
        scrollBehavior: SBehavior(),
        supportedLocales: LanguageDataModel.languageLocales(),
        localizationsDelegates: [
          THIS LINE HERE
          // AppLocalizations(),
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate
        ],
        localeResolutionCallback: (locale, supportedLocales) => locale,
        locale: Locale(appStore.selectedLanguageCode),
      ),
    );
  }

  @override
  void dispose() {
    _signInBloc.close();
    super.dispose();
  }
}

My AppLocalizations class

class AppLocalizations extends LocalizationsDelegate<BaseLanguage> {
  const AppLocalizations();

  @override
  Future<BaseLanguage> load(Locale locale) async {
    switch (locale.languageCode) {
      case 'en':
        return LanguageEn();
      case 'ar':
        return LanguageAr();
      case 'hi':
        return LanguageHi();
      case 'fr':
        return LanguageFr();
      default:
        return LanguageEn();
    }
  }

  @override
  bool isSupported(Locale locale) => LanguageDataModel.languages().contains(locale.languageCode);

  @override
  bool shouldReload(LocalizationsDelegate<BaseLanguage> old) => false;
}

setState is being called on a deactivated widget

At many places setState has been called but the widget is already removed from the widget tree. Due to this, the application that uses the package shows grey screen in release mode.

Screenshots:
image

sessionStateStream issue with Getx

When I call this code sessionStateStream.add(SessionState.startListening) my app refreshes and redirects to the first page.
I followed example code, the only difference being that I used Getx package.
After spending a lot of time searching on Google, I created an issue to ask the package developers for help.

this is main.dart file in my project.

Future<void> main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final sessionConfig = SessionConfig(
      invalidateSessionForAppLostFocus: const Duration(minutes: 5),
      invalidateSessionForUserInactivity: const Duration(minutes: 5),
    );
    sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
      if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
        // logout logic
      } else if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
        // logout logic
      }
    });
    return GetBuilder<SessionStateController>(builder: (sessionStateController) {
      return SessionTimeoutManager(
        sessionConfig: sessionConfig,
        sessionStateStream: sessionStateController.sessionStateStream.stream,
        child: GetMaterialApp(
          ...
          ),
        ),
      );
    });
  }
}

And this is session_state_controller.dart file

import 'dart:async';
import 'package:get/get.dart';
import 'package:local_session_timeout/local_session_timeout.dart';

class SessionStateController extends GetxController {
  final sessionStateStream = StreamController<SessionState>();

  void startListening() {
    if (!sessionStateStream.isClosed && sessionStateStream.hasListener) {
      sessionStateStream.add(SessionState.startListening);
    }
  }

  void stopListening() {
    if (!sessionStateStream.isClosed && sessionStateStream.hasListener) {
      sessionStateStream.add(SessionState.stopListening);
    }
  }

  @override
  void onClose() {
    sessionStateStream.close();
    super.onClose();
  }
}

I used this code when I click login button

    final sessionStateController = Get.put(SessionStateController());
    sessionStateController.startListening();

Events are not firing on Samsung S23 Android 14 device

I am using this useful package in one of my applications, working fine on range of devices though no events are getting fired on Samsung S23 devices (S23 max too) with Android 14 OSv.
None is getting triggered, user inactivity or app focus.

The current implementation is having 4 mins of timeout trigger and targeted for Android and iOS.
Checked on device OS level optimisations and power saving mode too but nothing down to that level is causing it.

One weird thing I noticed too, once we enable the logs (Flutter logs) or run a debug variant of build on same code base, it is triggering events, I can confirm there are no additional steps performed in release/signing stages other than ripping out the debug info.
Any ideas on it would be helpful to get myself unblocked.

Flutter Web: SessionTimeoutState.userInactivityTimeout event keep calling even when user interacts with the app

Using Flutter channel stable, 3.13.5 / Chrome - develop for the web :

I know people had asked about this before. But the solution provided did not help.

I am working on Flutter WEB where this library simply does not work for USER-INTERACTION timeoutEvents. The Web-Application delivers timeoutEvent's no matter how much I interact with my Flutter Web appliction.

(and I know that this library cannot deliver appFocusTimeout for Web - but I am talking about userInactivityTimeout that does not seem to work either for flutter Web.)

What does "userIneraction" mean exactly ?

I would like to prevent logout with this library for any of the following userInteractions:

  • scrolling SingleChildView's
  • Button clicks
  • TextField entries
  • Navigator pushNamed
  • basically any user-interaction I can think of for a Web application built in Flutter

Here is my code:

class MainPage extends StatelessWidget {
  const MainPage({super.key});

  @override
  Widget build(BuildContext context) {
    final sessionConfig = SessionConfig(
      invalidateSessionForAppLostFocus:
          const Duration(seconds: 20),
      invalidateSessionForUserInactivity:
          const Duration(seconds: 30),
    );

    sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
      if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
        // UNFORTUNATELY THE timeoutEvent KICKS IN ALWAYS - NO MATTER WHAT THE USER-INTERACTION IS !!!!!!!!!!!!
        Navigator.pushNamed(context, '/logout');
      } else if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
        Navigator.pushNamed(context, '/logout');
      }
    });
    return SessionTimeoutManager(
      sessionConfig: sessionConfig,
      userActivityDebounceDuration: const Duration(seconds: 1),
      child: MyApp(),
    );
  }
}

What is wrong still ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.