check_login()) { //Default admin page. echo $this->tpl->load_template('layout', ['title' => 'Admin', 'path_module' => 'admin.home']); } else { header('Location: '.PhangoApp\PhaRouter\Url::make_url('admin', 'app', ['login'])); } break; case 'login': $this->db->connect(); $c_user=$this->db->select_count('useradmin', '', []); $error=1; $error_form=['username_error' => '']; if(!$c_user) { header('Location: '.Url::make_url('admin', 'app', ['signup'])); } else { if($_SERVER['REQUEST_METHOD']=='POST') { //Check csrf token first. if(PhangoApp\PhaRouter\Config::$on_proxy) { $ip=$_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? ''; } else { $ip=$_SERVER['REMOTE_ADDR'] ?? ''; } if($ip!='') { $arr_tries=$this->db->select_a_row('login_tries', [], 'WHERE ip=?', [$ip]); $now=date("Y-m-d H:i:s"); if($arr_tries) { $timestamp_5_min=strtotime($now)-300; $timestamp_last_login=strtotime($arr_tries['date']); if($timestamp_5_min>$timestamp_last_login) { $this->db->delete('login_tries', 'WHERE ip=?', [$ip]); $arr_tries=false; } } $num_tries=$arr_tries['num_tries'] ?? 0; if($num_tries<5) { $username=trim($_POST['username'] ?? ''); $password=trim($_POST['password'] ?? ''); if($username=='') { $error_form['username_error']=_('Username empty'); } $arr_user=$this->db->select_a_row('useradmin', [], 'WHERE username=?', [$username]); if($arr_user) { if(password_verify($password, $arr_user['password'])) { $error=0; $_SESSION['admin_login']=$arr_user['id']; $_SESSION['date_login']=date("Y-m-d H:i:s"); if($arr_user['double_auth']) { $_SESSION['double_auth']=1; $auth_code=PhangoApp\PhaUtils\Utils::get_token(12); $this->db->update('useradmin', ['auth_token' => password_hash($auth_code, PASSWORD_DEFAULT)], 'where id=?', [$arr_user['id']]); // Send email $this->send_mail_auth(PhangoApp\PhaRouter\Config::$email_site, PhangoApp\PhaRouter\Config::$portal_name, $arr_user['email'], $arr_user['username'], $auth_code); } } else { $error_form['username_error']=_('Wrong user or password'); } } else { $error_form['username_error']=_('Wrong user or password'); } if($error) { if(!$arr_tries) { $this->db->insert('login_tries', ['num_tries' => 0, 'ip' => $ip]); } else { $this->db->update('login_tries', ['num_tries' => $arr_tries['num_tries']+1, 'date' => date("Y-m-d H:i:s")], 'WHERE ip=?', [$ip]); } } } else { $error_form['username_error']=_('Sorry, you need wait 5 minutes for retry login.'); } } else { $error_form['username_error']=_('Unknown error'); } echo $this->json(['error' => $error, 'error_form' => $error_form, 'message' => '']); } else { echo $this->tpl->load_template('login', ['title' => 'Login']); } } break; case 'signup': $this->db->connect(); $c_user=$this->db->select_count('useradmin', '', []); if(!$c_user) { if($_SERVER['REQUEST_METHOD']=='POST') { $error=0; $error_form=[]; $arr_data=['username', 'email', 'password', 'repeat_password']; foreach($arr_data as $v) { settype($_POST[$v], 'string'); } $username=trim($_POST['username']); if(!preg_match('/^[A-Za-z0-9_-]+$/', $username) || $username=='') { $error=1; $error_form['username_error']=_("Error: empty value"); } $email=filter_var($_POST['email'], FILTER_VALIDATE_EMAIL); if(!$email) { $error=1; $error_form['email_error']=_("Error: email is not valid"); } $password=trim($_POST['password']); $repeat_password=trim($_POST['repeat_password']); if($password=='') { $error=1; $error_form['password_error']=_("Error: password empty"); } else { if($password!=$repeat_password) { $error=1; $error_form['password_error']=_("Error: password not equal"); } } if(!$error) { if(!$this->db->insert('useradmin', ['username' => $username, 'password' => password_hash($password, PASSWORD_DEFAULT), 'email' => $email])) { $error=1; $error_form['username_error']=_("Error: cannot create the user, please contact with the administrator"); } } echo $this->json(['error' => $error, 'error_form' => $error_form, 'message' => '']); } else { echo $this->tpl->load_template('signup', ['title' => 'Signup']); } } break; case 'check_auth': //Session expired. if($this->check_login()) { if($_SERVER['REQUEST_METHOD']=='POST') { $this->db->connect(); $error=1; $error_form['auth_code_error']=''; $auth_code=$_POST['auth_code'] ?? ''; //($table, $fields, $where_sql='', $values=[]) //$arr_tries=$this->db->select_a_row('login_tries', [], 'WHERE ip=?', [$ip]); $arr_user=$this->db->select_a_row('useradmin', [], 'WHERE id=?', [$_SESSION['admin_login']]); if(password_verify($auth_code, $arr_user['auth_token'])) { unset($_SESSION['double_auth']); $error=0; } else { $error_form['auth_code_error']='Sorry, auth code wrong'; } echo $this->json(['error' => $error, 'error_form' => $error_form]); } else { echo $this->tpl->load_template('check_auth', ['title' => 'Double auth']); } } else { header('Location: '.PhangoApp\PhaRouter\Url::make_url('admin', 'app', ['login'])); } break; case 'logout': $_SESSION=[]; header('Location: '.PhangoApp\PhaRouter\Url::make_url('admin')); break; case 'change_theme': if($this->check_login()) { settype($_GET['theme'], 'integer'); if($_GET['theme']>1 || $_GET['theme']<0) { $_GET['theme']=0; } $error=0; $message=''; $this->db->connect(); if(!$this->db->update('useradmin', ['theme' => $_GET['theme']], 'WHERE id=?', [$_SESSION['admin_login']])) { $error=1; } else { $_SESSION['theme']=$_GET['theme']; } } echo $this->json(['error' => $error, 'message' => $message]); break; } } private function send_mail_auth($email_from, $portal_name, $email_to, $name, $auth_code) { $mail=new PHPMailer(true); try { //$mail->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output $mail->isSMTP(); //Send using SMTP $mail->Host=\PhangoApp\PhaRouter\Config::$data['smtp_host']; //Set the SMTP server to send through $mail->SMTPAuth=true; //Enable SMTP authentication $mail->Username=PhangoApp\PhaRouter\Config::$data['smtp_username']; //SMTP username $mail->Password=PhangoApp\PhaRouter\Config::$data['smtp_password']; //SMTP password $mail->SMTPSecure=PHPMailer::ENCRYPTION_STARTTLS; //Enable implicit TLS encryption $mail->Port=PhangoApp\PhaRouter\Config::$data['smtp_port'] ?? 587; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS` $mail->CharSet='UTF-8'; $mail->setFrom($email_from, $portal_name); $mail->addAddress($email_to, $name); $mail->Subject = 'Code for complete login'; $mail->Body = 'We send to you a code for activate your account using double authentication: '.$auth_code; $mail->send(); } catch (Exception $e) { //echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; return false; } } }