New Community Forums are coming. Watch this space for news.
Subscribe: RSS
  • @yuliyepes

    Ok let's try to work this out.

    I think a prehook will not work because you are effectively trying to prevent login in a login form, does this make sense? I suppose a prehook could stop the entire form from processing, but its not really what is needed.

    I think what you need is a standalone snippet and form which accepts and saves the inputed data, checks for any active sessions of the user, and then responds. It would look like your login on your site, the user will try to login there.

    Then the response is either run login snippet (and can use the data already saved, it might still need a click by the user unless the login form can automatically run), or a message saying, user already has an active session, please close it before logging in.

    I cannot write php myself, but basically

    save form values,

    get user table, look up user and check for sessions, or get active sessions data from the database and search for username.

    IF session/username doesn't exist, then run/display login snippet/button

    ELSE

    username/session exists, then show message

    You'd want to be sure there is no real login except for ones with this snippet standing as a gateway

    HTH, let us know how you are getting along.


    Quote from: yuliyepes at Jan 08, 2019, 04:34 PM
    It should be easy but not. I need do not allowed the login if the user already has a session initiated (in another browser o device), because by default modx let me login many sessions.
    So I have this snippet on my preHooks login:

    
        $formFields = $hook->getValues();
        $username = $formFields['username'];  //take username login
        $modx->user = $modx->getObject('modUser', array(  //query this username
        'username' => $username,
    ));
    if ($modx->user->isAuthenticated('web') == true) { // this is empty
          $modx->sendUnauthorizedPage();
    } 
    return true;



    I really appreciate any help

    • it could even be a modal window over login button, and if it passes the values to the real login it would be smooth
      • Thank you so much, I'm trying this, maybe I'm wrong but I think this solution could works.

        I have created a flag variable in the extended fields of user in a postHook of login, so this variable will be 1 when the user login, and will be 0 when the user log out

        postHook:

        if (!isset($_GET['service'])){ // this first line is for validation, (if the user is not logging out) the user is login so logged=1
            $formFields = $hook->getValues(); 
            $username = $formFields['username']; 
            $modx->user = $modx->getObject('modUser', array(
            'username' => $username,
            ));
            $profile = $modx->user->getOne('Profile');
            $extended = $profile->get('extended');
            $extended['logged'] = 1;
            }
            else if ($_GET['service'] == 'logout' ){ //if the user is logging out logged = 0
                $user = $modx->getUser();
                $profile = $modx->user->getOne('Profile');
                $extended = $profile->get('extended');
                $extended['logged'] = 0;
            } 
            $profile->set('extended', $extended);
            $profile->save();  
        return true;
        


        I did a preHook for validate this variable. I read on the documentation that "Pre-Hooks in Login are fired before the action occurs, but after field validation. If a preHook fails, the snippet won't proceed with its normal action." so what I understand is that I could take the username and to know the profile information, even extended fields.

        I have this in my preHook:

        <?php
        if (!isset($_GET['service'])){
            $formFields = $hook->getValues();
            $username = $formFields['username'];
            $modx->user = $modx->getObject('modUser', array(
            'username' => $username,
        ));
            $profile = $modx->user->getOne('Profile');
            $extended = $profile->get('extended');
            if ($extended['logged'] == '1') {
                  $value = 'userblocked='.$username;
                  $url = $modx->makeURL('21', 'web', $value, 'full');
                  $modx->sendRedirect($url);
               }
        } 
        return true;
        


        If variable is 1, I redirect this user to another page with a link to disconnect (to put this variable on 0) a previous session, else, the user can login.

        Needless to say, it is obvious that I am not an expert in MODX but my intention is to learn a lot from you guys.
          @yulianita
        • Hi @yulianita yes we can help. Many expert coders will read these threads and jump in when a question is clear that they can answer/fix. I myself can only do css but have been here awhile and can read, very roughly, code like php, and of course understand how Modx does stuff.

          Sorry for before, we ended up having a wide discussion instead of looking at your issue! I do think we can work this out. That discussion helped me understand the situation better.

          For your code, first off what we need is for the prehook to fail upon finding the existing session. The login should fail if the prehook fails, but we need to know what failure even means.

          With your code, I can think read a bit, is to get the value (1=existing session) and then redirect, that's not failure. You have to have failure first, then redirect. But I don't know exactly what will ensure failure every time.

          Are you getting the right value about the session existing now?

          Anyway I think you could take what you've got and add in the error.

          If (value) = 1, then log error, then redirect
          • The posthook is interesting, it runs on login and logout, right? Does it successfully set the value?

            I think it could be a good way, just a quick placement of a value automatically on login and logout...not perhaps necessary but possibly effective.

            Ideally we can take the username as inputed as you do in the posthook, and just query the user session table of the db directly (in the prehook), but there are many ways to win, and there even could be advantages to this way.
            • I just found something that could be interesting, its perhaps older code but the core of Modx doesn't change too much so it should still work.

              https://gist.github.com/splittingred/1234763

              It queries the Modx db for sessions, and it seems to me it could be easily converted to take the query it is already doing, and then checking for the username.

              It could save you some time depending on where you are at. Just a random find in github lol
              • @yulianita, You may be correct that my solution using hasSessionContext() wouldn't work. Your preHook looks to me like it should work, since it will only return true if the user is not already logged in. It should be easy to find out if it works. Let us know if it does and maybe I'll do a a blog post on it.
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                • Quote from: BobRay at Jan 21, 2019, 04:58 AM
                  @yulianita, You may be correct that my solution using hasSessionContext() wouldn't work. Your preHook looks to me like it should work, since it will only return true if the user is not already logged in. It should be easy to find out if it works. Let us know if it does and maybe I'll do a a blog post on it.

                  Hi BobRay and nuan88, The code that I share is working and I have not had any problem yet "I hope not have it", I didn't use sessions.
                    @yulianita
                  • Then that's a very elegant solution, thanks for the contribution!
                    • Hi Yulianita. Very nice solution.

                      For completeness, could you provide the code from resource 21?

                      What happens if the user forgets to log out and just closes the browser? I don't think MODX would automatically call the login snippet with service='logout'. I could be wrong.

                      If that proves to be a problem, you could possibly check the last login time and give them a pass if it's been x hours since they last logged in.

                        Did I help you? Buy me a beer
                        Get my Book: MODX:The Official Guide
                        MODX info for everyone: http://bobsguides.com/modx.html
                        My MODX Extras
                        Bob's Guides is now hosted at A2 MODX Hosting