<?php

/**
 * Session short summary.
 *
 * Session description.
 *
 * @version 1.0
 * @author Kaos
 */

    
function auto_logout($field)
{
    $t = time();
    if (!isset($_SESSION[$field]))
        $_SESSION[$field] = time();
    $t0 = $_SESSION[$field];
    $diff = $t - $t0;
    if ($diff > 60)
    {        
        return true;
    }
    else
    {
        return false;
    }
}

class Session extends SessionManager
{
    public function createUserSession($data_ar = array(), $jwt, $token)
    {
        $PHP_FIREWALL_gethostbyaddr = $_SESSION['PHP_FIREWALL_gethostbyaddr'];
        parent::sessionStart($GLOBALS['config']['AppName'], 3600, $GLOBALS['config']['SITE'], $GLOBALS['config']['AppName'], true);
        @ session_cache_expire(30); //cache expiring in 30mins
        if(is_array($data_ar))
        {
            foreach($data_ar as $key => $value)
            {
                $_SESSION[$key] = $value;
            }
        }
        $_SESSION['token'] = $token;
        $_SESSION['PHP_FIREWALL_gethostbyaddr'] = $PHP_FIREWALL_gethostbyaddr;
        $_SESSION['JWT'] = $jwt;
        session_write_close();
    }
    
    public function hasAccess($token) 
    {
        if( parent::preventHijacking())
            return true;
        else
            parent::regenerateSession();
            return false;
    }
    
    private static function token_Generator() 
    {
        //combine the userpart and the domain name p
        $chars = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
        $chars = explode(",", $chars);
        $ints = array();
        for ($i = 0; $i < 25; $i++) {
            array_push($ints, rand(0, 100));
        }
        $password = array();

        //composing the password
        foreach ($ints as $int) {
            $char = $chars[$int * rand(0, 3)];
            if (($int * rand(0, 3)) % 2 == 0) {
                $char = strtoupper($char);
                array_push($password, $int);
            }
            array_push($password, $char);
        }

        //convert the password array to string
        $stringpass = '';
        foreach ($password as $char) {
            $stringpass.=$char;
        }
        return $stringpass;
    }
    
    private function unsecure_session($string)
    {
        return (string)trim(stripslashes(rtrim(base64_decode($string)))); 
    }
    
    private function secure_session($string)
    {
        return (string)rtrim(base64_encode($string));
    }
}

abstract class SessionManager
{
   public function sessionStart($name, $limit = 0, $path = '/', $domain = null, $secure = null)
   {
      // Set the cookie name before we start.
      session_name($name);

      // Set the domain to default to the current domain.
      $domain = isset($domain) ? $domain : isset($_SERVER['SERVER_NAME']);

      // Set the default secure value to whether the site is being accessed with SSL
      $https = isset($secure) ? $secure : isset($_SERVER['HTTPS']);

      // Set the cookie settings and start the session
      session_set_cookie_params($limit, $path, $domain, $https, true);
      @ session_start();

        // Make sure the session hasn't expired, and destroy it if it has
        if(self::validateSession())
        {
            // Check to see if the session is new or a hijacking attempt
            if(!self::preventHijacking())
            {
                // Reset session data and regenerate id
                $_SESSION = array();
                $_SESSION['IPaddress'] = $_SERVER['REMOTE_ADDR'];
                $_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
                self::regenerateSession();

            // Give a 5% chance of the session id changing on any request
            }elseif(rand(1, 100) <= 5){
                self::regenerateSession();
            }
        }else{
            $_SESSION = array();
            session_destroy();
            session_start();
        }
   }
    
    static protected function validateSession()
    {
        if( isset($_SESSION['OBSOLETE']) && !isset($_SESSION['EXPIRES']) )
            return false;

        if(isset($_SESSION['EXPIRES']) && $_SESSION['EXPIRES'] < time())
            return false;

        return true;
    }

    static protected function preventHijacking()
    {
        if(!isset($_SESSION['IPaddress']) || !isset($_SESSION['userAgent']))
            return false;

        if ($_SESSION['IPaddress'] != $_SERVER['REMOTE_ADDR'])
            return false;

        if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT'])
            return false;

        return true;
    }
    
    static protected function regenerateSession()
    {
        // If this session is obsolete it means there already is a new id
        if(@ isset($_SESSION['OBSOLETE']) || @ $_SESSION['OBSOLETE'] == true)
            return;

        // Set current session to expire in 10 seconds
        $_SESSION['OBSOLETE'] = true;
        $_SESSION['EXPIRES'] = time() + 10;

        // Create new session without destroying the old one
        @ session_regenerate_id(false);

        // Grab current session ID and close both sessions to allow other scripts to use them
        $newSession = session_id();
        @ session_write_close();

        // Set session ID to the new one, and start it back up again
        @ session_id($newSession);
        @ session_start();

        // Now we unset the obsolete and expiration values for the session we want to keep
        unset($_SESSION['OBSOLETE']);
        unset($_SESSION['EXPIRES']);
    }
}
