<?php

/*
 * @name        JMY CMS
 * @link        https://jmy.su/
 * @copyright   Copyright (C) 2012-2025 JMY LTD
 * @license     LICENSE.txt (see attached file)
 * @version     VERSION.txt (see attached file)
 * @author      Komarov Ivan
 * @edited      Orlov Alexsey
 */

if (!defined('ACCESS')) {
    header('Location: /');
    exit;
}

class auth
{
    var mixed $user_id = 0;
    var bool $isUser = false;
    var bool $isAdmin = false;
    var bool $isModer = false;
    var mixed $group = 0;
    var mixed $user_info = false;
    var mixed $group_info = false;
    var bool $banUser = false;
    var mixed $groups_array = false;
    var array|bool $newPms = false;
    var int $newPmsNumb = 0;

    function __construct($hash = '')
    {
        global $core, $db, $url, $user, $config;
        $ut = str_replace('index.php', '', $_SERVER["REQUEST_URI"]);
        $dsUrl = isset($_REQUEST['url']) && isset($url[0]) && $url[0] !== 'ajax' && $url[0] !== ADMIN ? '/' . (empty($ut) ? $config['mainModule'] : str_replace('index.php?url=', '', $_SERVER["REQUEST_URI"])) : '/' . $config['mainModule'];
        $moduleNow = isset($url[0]) && $url[0] !== 'ajax' && $url[0] !== ADMIN ? $url[0] : $config['mainModule'];
        $hash = empty($hash) ? $_COOKIE[COOKIE_AUTH] ?? '' : $hash;
        $this->groups_array = getcache('groups');
        $u_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        if (empty($groups_array)) {
            $query = $core->select_data('groups');
            while ($rows = $db->getRow($query)) {
                $this->groups_array[$rows['id']] = $rows;
            }
            setcache('groups', $this->groups_array);
        }
        if (empty($hash)) {
            if (!isset($_COOKIE[COOKIE_PAUSE])) {
                $group = SpiderDetect($u_agent) ? $user['botGroup'] : $user['guestGroup'];
                $uid = SpiderDetect($u_agent) ? SpiderDetect($u_agent, true) : 0;
                $core->upd_data('online', '`time` = "' . time() . '"', 'ip = "' . getRealIpAddr() . '" AND `uid` = "' . $this->user_id . '"');
                $error = $db->info();
                if (isset($error)) preg_match('/^\\D+(\\d+)/', $error, $result);
                if (isset($result[1]) && $result[1] == 0) $core->ins_data('online', false, '"' . $uid . '", "' . time() . '", "' . getRealIpAddr() . '", "' . $group . '","' . $dsUrl . '"');
                $core->del_data('online', '`time` <  "' . (time() - PAUSE_TIME) . '"');
                setcookie(COOKIE_PAUSE, time(), time() + 120, '/');
            }
            $this->isUser = false;
            $this->group = $user['guestGroup'];
            $this->group_info = $this->groups_array[$this->group];
        } else {
            $cookie = @unserialize(engine_decode($hash));
            if (empty($cookie['id']) || empty($cookie['nick']) || empty($cookie['password']) || empty($cookie['hash'])) {
                @setcookie(COOKIE_AUTH, false);
                @header('Location: /');
                exit;
            }
            $this->user_info = getcache('userInfo_' . $cookie['id']);
            if (empty($this->user_info)) {
                $this->user_info = $core->row_data('users', 'id = "' . $cookie['id'] . '" AND password = "' . $cookie['password'] . '" AND nick = "' . $cookie['nick'] . '" AND active=1');
                foreach ($this->groups_array as $id => $arr) {
                    if ($arr['special'] == 1 && $this->user_info['points'] >= $arr['points'] && $arr['points'] > 0) $this->user_info['exgroup'] = $id;
                }
                setcache('userInfo_' . $cookie['id'], $this->user_info, 'userInfo');
            }
            $checkHash = md5(@$u_agent . $config['uniqKey']);
            if (($cookie['hash'] == $checkHash || $u_agent == 'Shockwave Flash') && $this->user_info['nick'] != '') {
                $this->user_id = $cookie['id'];
                $this->group = $this->user_info['group'];
                if (isset($this->groups_array[$this->group])) {
                    $group_info = $this->groups_array[$this->group];
                    $group_info['gname'] = $group_info['name'];
                    $group_info['gid'] = $group_info['id'];
                    unset($group_info['name'], $group_info['id']);
                    if ($this->user_info['exgroup'] != 0 && isset($this->groups_array[$this->user_info['exgroup']])) {
                        $group_info['exname'] = $this->groups_array[$this->user_info['exgroup']]['name'];
                        $group_info['excolor'] = $this->groups_array[$this->user_info['exgroup']]['color'];
                        $group_info['exicon'] = $this->groups_array[$this->user_info['exgroup']]['icon'];
                    }
                    $this->group_info = $group_info;
                    $this->user_info = array_merge($this->user_info, $this->group_info);
                    unset($group_info);
                }
                if ($this->user_info['group'] != $user['banGroup']) {
                    if ($this->group_info) {
                        if ($this->group_info['user'] == 1) $this->isUser = true;
                        if ($this->group_info['admin'] == 1) $this->isAdmin = true;
                        if ($this->group_info['moderator'] == 1) $this->isModer = true;
                    }
                    if (!isset($_COOKIE[COOKIE_PAUSE])) {
                        setcookie(COOKIE_PAUSE, time() + PAUSE_TIME, time() + PAUSE_TIME, '/');
                        $core->upd_data('online', '`time` = "' . time() . '", `ip` = "' . getRealIpAddr() . '"', '`uid` = "' . $this->user_id . '"');
                        $error = $db->info();
                        if (isset($error)) preg_match('/^\\D+(\\d+)/', $error, $result);
                        if (isset($result[1]) && $result[1] == 0) {
                            $core->ins_data('online', false, '"' . $this->user_id . '", "' . time() . '", "' . getRealIpAddr() . '", "' . $this->user_info['group'] . '","' . $dsUrl . '"');
                            $core->upd_data('users', '`last_visit` = "' . time() . '", `ip` = "' . getRealIpAddr() . '"', '`id` = "' . $this->user_id . '"');
                        }
                        $core->del_data('online', '`time` < "' . (time() - PAUSE_TIME) . '"');
                        if ($user['pmShown'] == 1) {
                            $where = '';
                            if (isset($_COOKIE['PMLASTCHECK'])) $where = " AND time > '" . intval($_COOKIE['PMLASTCHECK']) . "'";
                            $result = $core->select_data('pm', 'pm.toid = "' . $this->user_id . '" AND pm.status=0' . $where, 'time DESC', 'pm.*, u.nick', 'as pm LEFT JOIN ' . DB_PREFIX . '_users as u on (pm.fromid = u.id)');
                            $this->newPms = array();
                            if ($db->numRows($result) > 0) {
                                while ($message = $db->getRow($result)) {
                                    $this->newPms[] = array($message) ? $message : '';
                                    $this->newPmsNumb++;
                                }
                                setcookie('PMLASTCHECK', time(), time() + 86400, '/');
                                $this->audio_alert($this->user_id);
                            }
                        }
                    } else {
                        if ($_COOKIE[COOKIE_PAUSE] - PAUSE_TIME * 2 / 3 < time()) {
                            $core->upd_data('online', '`time` = "' . time() . '", `url` = "' . $dsUrl . '"', 'uid = "' . $this->user_id . '"');
                            $core->upd_data('users', '`last_visit` = "' . time() . '", `ip` = "' . getRealIpAddr() . '"', '`id` = "' . $this->user_id . '"');
                            $error = $db->info();
                            if (isset($error)) preg_match('/^\\D+(\\d+)/', $error, $result);
                            if (isset($result[1]) && $result[1] == 0) $core->ins_data('online', false, '"' . $this->user_id . '", "' . time() . '", "' . getRealIpAddr() . '", "' . $this->user_info['group'] . '","' . $dsUrl . '"');
                            setcookie(COOKIE_PAUSE, false);
                            setcookie(COOKIE_PAUSE, time() + PAUSE_TIME, time() + PAUSE_TIME, '/');
                        }
                    }
                } else {
                    $this->banUser = true;
                }
                unset($result, $error, $cookie);
            } else {
                $this->logout();
                location();
                unset($this->user_info);
            }
        }
    }

    function audio_alert($uid): void
    {
        global $core;
        $rows = $core->row_data('users', 'id = "' . $uid . '"');
        $audio_alert = $rows['audio_alert'] == 1 ? '<embed src="media/sound/notifications.mp3" autostart="true" hidden="false" loop="false" width="0" height="0" align="bottom"> ' : '';
        echo $audio_alert;
    }

    function logout(): void
    {
        global $core;
        setcookie(COOKIE_AUTH, false, time(), '/');
        setcookie(COOKIE_PAUSE, false, time(), '/');
        delcache('userInfo_' . $this->user_id);
        $core->del_data('online', 'uid = "' . $this->user_id . '" OR ip = "' . filter(getRealIpAddr()) . '"');
    }

    function login($login, $password)
    {
        global $core, $config, $user;
        if ($user['auth_open'] > 0) {
            $core->del_data('online', 'ip = "' . filter(getRealIpAddr()) . '"');
            setcookie(COOKIE_PAUSE, false, time(), '/');
            $where = $user['auth_metod'] == 'nick' ? 'nick = "' . $login . '"' : 'email = "' . $login . '"';
            $password = md5(md5($password));
            $access = $core->row_data('users', $where . ' AND active= 1', false, 'id, password, tail');
            $users = $core->row_data('users', $where);
            if (is_array($access)) {
                if (md5(mb_substr($password, 0, -mb_strlen($access['tail'])) . $access['tail']) == $access['password']) {
                    delcache('userInfo_' . $this->user_id);
                    $newHash = md5(@$_SERVER['HTTP_USER_AGENT'] . $config['uniqKey']);
                    setcookie(COOKIE_AUTH, engine_encode(serialize(array('id' => $access['id'], 'nick' => $users['nick'], 'password' => md5(mb_substr($password, 0, -mb_strlen($access['tail'])) . $access['tail']), 'hash' => $newHash))), time() + COOKIE_TIME, '/');
                    return true;
                } else {
                    setcookie(COOKIE_AUTH, '', time(), '/');
                    return false;
                }
            }
        }
    }

    function login_social($provider, $social_id): bool
    {
        global $core, $db, $config;
        $core->del_data('online', 'ip = "' . getRealIpAddr() . '"');
        setcookie(COOKIE_PAUSE, false, time(), '/');
        $provider = filter($provider, 'provider');
        $social_id = intval($social_id);
        $access = $core->row_data('users', 'provider = "' . $db->safesql($provider) . '" AND social_id = "' . $db->safesql($social_id) . '" AND	active=1', false, 'id, nick, password, tail');
        if (!empty($access['id'])) {
            delcache('userInfo_' . $this->user_id);
            $newHash = md5(@$_SERVER['HTTP_USER_AGENT'] . $config['uniqKey']);
            setcookie(COOKIE_AUTH, engine_encode(serialize(array('id' => $access['id'], 'nick' => $access['nick'], 'password' => $access['password'], 'hash' => $newHash))), time() + COOKIE_TIME, '/');
            return true;
        } else {
            setcookie(COOKIE_AUTH, '', time(), '/');
            session_start();
            unset($_SESSION['user_auth']);
            return false;
        }
    }

    function updateProfile($mail, $timezones, $icq, $skype, $phone, $surname, $name, $no_mail, $audio_alert, $ochestvo, $place, $age, $gender, $birthDate, $hobby, $signature, $fields, $bday_visibility, $twofactor, $key_pin, $attempt, $banned_time, $uid = false, $group = false, $exgroup = false): void
    {
        global $core, $db;
        delcache('userInfo_' . $this->user_id);
        $core->upd_data('users', 'email = "' . filter($mail, 'mail') . '", timezones = "' . filter($timezones) . '", icq = "' . filter($icq, 'a') . '", skype = "' . filter($skype, 'a') . '", phone = "' . filter($phone, 'a') . '", surname = "' . filter($surname, 'a') . '", name = "' . filter($name, 'a') . '", no_mail = "' . intval($no_mail) . '", audio_alert = "' . intval($audio_alert) . '", ochestvo = "' . filter($ochestvo, 'a') . '", place = "' . filter($place, 'a') . '", age = "' . intval($age) . '", sex = "' . intval($gender) . '", birthday = "' . filter($birthDate, 'a') . '", `group` = "' . intval($group) . '", `exgroup` = "' . intval($exgroup) . '", hobby = "' . filter($hobby, 'a') . '", signature = "' . $db->safesql(parseBB($signature)) . '", fields = "' . $db->safesql($fields) . '", bday_visibility = "' . $db->safesql($bday_visibility) . '", `twofactor` = "' . intval($twofactor) . '", `key_pin` = "' . intval($key_pin) . '", `attempt` = "' . intval($attempt) . '", `banned_time` = "' . intval($banned_time) . '"', 'id ="' . ($uid ?: $this->user_id) . '"');
    }

    function updatePassword($password, $uid = false): void
    {
        global $core;
        delcache('userInfo_' . ($uid ?: $this->user_id));
        $tail = gencode(rand(6, 11));
        $updPass = md5(mb_substr(md5(md5($password)), 0, -mb_strlen($tail)) . $tail);
        $core->upd_data('users', 'password = "' . $updPass . '", tail = "' . filter($tail, 'a') . '"', 'id ="' . ($uid ?: $this->user_id) . '"');
    }

    function forgotPass($new_pass, $tail, $uid): void
    {
        global $core;
        delcache('userInfo_' . $uid);
        $core->upd_data('users', 'password = "' . md5(mb_substr(md5(md5($new_pass)), 0, -mb_strlen($tail)) . $tail) . '", tail = "' . filter($tail, 'a') . '"', 'id ="' . $uid . '"');
    }

    function activate($mail): void
    {
        global $core, $db;
        $core->upd_data('users', 'active = 1', 'email = "' . $db->safesql(filter($mail, 'mail')) . '"');
    }

    function register($user_login, $password, $tail, $email, $icq, $skype, $phone, $surname, $name, $ochestvo, $age, $sex, $birthday, $hobby, $signature, $group = '2', $activate = false, $ip = false): void
    {
        loadConfig('user');
        global $core, $db;
        $core->ins_data('users', 'id,nick,password,tail,email,timezones,provider,social_id,status,icq,phone,skype,surname,name,ochestvo,place,age,sex,birthday,hobby,signature,points,carma,user_comments,user_news,group,exgroup,last_visit,regdate,active,mailsend,distsend,no_mail,audio_alert,dist_id,ip,fields,avatar_auth,bday_visibility', 'NULL,"' . filter($user_login, 'a') . '","' . md5(mb_substr(md5(md5($password)), 0, -mb_strlen($tail)) . $tail) . '","' . filter($tail, 'a') . '","' . filter($email, 'mail') . '","","","",0,"' . filter($icq, 'a') . '","' . filter($phone, 'a') . '","' . filter($skype, 'a') . '","' . filter($surname, 'a') . '","' . filter($name, 'a') . '","' . filter($ochestvo, 'a') . '","","' . intval($age) . '","' . intval($sex) . '","' . filter($birthday, 'birthday') . '","' . filter($hobby, 'a') . '","' . $db->safesql(parseBB($signature)) . '",0,0,0,0,"' . intval($group) . '",0,"' . time() . '","' . time() . '","' . intval($activate) . '",0,0,0,0,0,"' . filter($ip, 'ip') . '","","",0');
    }

    function register_social($user_login, $password, $tail, $email, $social_id, $provider, $birthday, $avatar_auth, $icq, $skype, $surname, $name, $ochestvo, $age, $sex, $hobby, $signature, $activate, $group = '2', $phone = false, $ip = false): void
    {
        loadConfig('user');
        global $core, $db;
        $core->ins_data('users', 'id,nick,password,tail,email,timezones,provider,social_id,status,icq,phone,skype,surname,name,ochestvo,place,age,sex,birthday,hobby,signature,points,carma,user_comments,user_news,group,exgroup,last_visit,regdate,active,mailsend,distsend,no_mail,audio_alert,dist_id,ip,fields,avatar_auth,bday_visibility', 'NULL,"' . filter($user_login, 'a') . '","' . md5(mb_substr(md5(md5($password)), 0, -mb_strlen($tail)) . $tail) . '","' . filter($tail, 'a') . '","' . filter($email, 'mail') . '","","' . $provider . '","' . $social_id . '",0,"' . filter($icq, 'a') . '","' . filter($phone, 'a') . '","' . filter($skype, 'a') . '","' . filter($surname, 'a') . '","' . filter($name, 'a') . '","' . filter($ochestvo, 'a') . '","","' . intval($age) . '","' . intval($sex) . '","' . filter($birthday, 'birthday') . '","' . filter($hobby, 'a') . '","' . $db->safesql(parseBB($signature)) . '",0,0,0,0,"' . intval($group) . '",0,"' . time() . '","' . time() . '","' . intval($activate) . '",0,0,1,1,0,"' . filter($ip, 'ip') . '","","' . filter($avatar_auth, 'avatar_auth') . '",0');
    }
}