app = $app;
}
public function CheckTimeOut()
{
$this->session_id = session_id();
if(isset($_COOKIE['CH42SESSION']) && $_COOKIE['CH42SESSION']!='')
{
$this->session_id = $_COOKIE['CH42SESSION'];
if(!(isset($_GET) && isset($_GET['module']) && isset($_GET['action']) && $_GET['module'] == 'welcome' && $_GET['action'] == 'poll'))$this->app->DB->Update("UPDATE useronline SET time=NOW(),login=1 WHERE sessionid='".$this->app->DB->real_escape_string($_COOKIE["CH42SESSION"])."' LIMIT 1");
}
if (empty($this->session_id)) {
return false;
}
// check if user is applied
$sessid = $this->app->DB->Select("SELECT sessionid FROM useronline,user WHERE
login='1' AND sessionid='".$this->app->DB->real_escape_string($this->session_id)."' AND user.id=useronline.user_id AND user.activ='1' LIMIT 1");
if($this->session_id == $sessid)
{
// check if time is expired
$time = $this->app->DB->Select("SELECT UNIX_TIMESTAMP(time) FROM useronline,user WHERE
login='1' AND sessionid='".$this->app->DB->real_escape_string($this->session_id)."' AND user.id=useronline.user_id AND user.activ='1' LIMIT 1");
if(($this->app->DB->Select('SELECT UNIX_TIMESTAMP(now())')-$time) > $this->app->Conf->WFconf['logintimeout'])
{
if(!isset($_COOKIE['CH42SESSION']) || $_COOKIE['CH42SESSION']=='')
{
$this->Logout("Ihre Zeit ist abgelaufen, bitte melden Sie sich erneut an.",true);
return false;
}
}
else {
// update time
if(!(isset($_GET) && isset($_GET['module']) && isset($_GET['action']) && $_GET['module'] == 'welcome' && $_GET['action'] == 'poll'))$this->app->DB->Update("UPDATE useronline,user SET useronline.time=NOW() WHERE
login='1' AND sessionid='".$this->app->DB->real_escape_string($this->session_id)."' AND user.id=useronline.user_id AND user.activ='1'");
session_write_close(); // Blockade wegnehmen
return true;
}
}
}
/**
* @param string $usertype
* @param string $module
* @param string $action
* @param string $userid
*
* @return bool
*/
public function Check($usertype,$module,$action, $userid='')
{
$ret = false;
$permissions =
!empty($this->app->Conf->WFconf['permissions'])
&& !empty($this->app->Conf->WFconf['permissions'][$usertype])
&& isset($this->app->Conf->WFconf['permissions'][$usertype][$module])
?$this->app->Conf->WFconf['permissions'][$usertype][$module]
:null;
if($usertype==='admin'){
return true;
}
if($this->app->User->GetID() > 0) {
if($module==='ajax') {
return true;
}
if($module === 'welcome') {
if(
in_array(
$action,
[
'css',
'logo',
'start',
'meineapps',
'spooler',
'redirect',
'login',
'logout',
'passwortvergessen',
]
)
) {
return true;
}
}
if($module === 'gpsstechuhr') {
if(in_array($action, ['create','save'])) {
return true;
}
}
if($module === 'learningdashboard') {
if(in_array($action, ['list', 'ajax', ''])) {
return true;
}
}
if($module==='drucker' && $action==='spoolerdownload') {
return true;
}
if($module==='wizard' && $action==='ajax') {
return true;
}
if($module==='supersearch' && $action==='ajax') {
return true;
}
if($module === 'appstore' && $action = 'list') {
return true;
}
}
// Change Userrights with new 'userrights'-Table
if(!is_array($permissions)) {
$permissions = [];
}
if(is_numeric($userid) && $userid>0) {
$permission_db = $this->app->DB->Select("SELECT permission FROM userrights WHERE module='".$this->app->DB->real_escape_string($module)."' AND action='".$this->app->DB->real_escape_string($action)."' AND user='$userid' LIMIT 1");
$actionkey = array_search($action, $permissions);
if($actionkey===false) {
if($permission_db=='1')
$permissions[] = $action;
}else {
if($permission_db=='0'){
unset($permissions[$actionkey]);
$permissions = array_values($permissions);
}
}
}
// --- END ---
foreach($permissions as $key => $val) {
if($val==$action) {
$ret = true;
break;
}
}
if($action=='' && $module==''){
$ret = true;
}
if($module === 'welcome' && in_array($action, array('login','main','logout'))) {
$ret = true;
}
if($ret && $usertype!=='admin') {
$id = (int)$this->app->Secure->GetGET('id');
if($id) {
if(
$action === 'edit' || $action === 'delete' || $action === 'copy' || $action === 'dateien'
|| ($action === 'rollen' && $module === 'adresse')
|| $action === 'inlinepdf' || $action === 'pdf' || $action === 'send'
) {
switch($module)
{
case 'auftrag':
case 'rechnung':
case 'gutschrift':
case 'angebot':
case 'anfrage':
case 'lieferschein':
$ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")) || ($this->app->erp->ModulVorhanden('vertriebscockpit') && ($this->app->DB->Select("SELECT a.id FROM adresse a INNER JOIN $module t ON a.id = t.adresse WHERE t.id = '$id' AND a.vertrieb = '".$this->app->User->GetAdresse()."' LIMIT 1") > 0 || $this->app->DB->Select("SELECT usereditid FROM $module t WHERE t.id = '$id' AND t.usereditid = '".$this->app->User->GetID()."' LIMIT 1")));
break;
case 'dateien':
$sql = "SELECT objekt FROM datei_stichwoerter WHERE datei = %s";
$dateiModul = strtolower($this->app->DB->Select(sprintf($sql,$id)));
//TODO datei_stichwoerter.objekt ist nicht zuverlässig für alle Datentypen. Deswegen nur zur Absicherung der bekannten Fälle #604706
if(array_search($dateiModul,['auftrag','rechnung','lieferschein','bestellung','angebot','verbindlichkiet','proformarechnung','anfrage','artikel','adresse','produktion'])!==false){
$sql = "SELECT parameter FROM datei_stichwoerter WHERE datei = %s";
$idModul = $this->app->DB->Select(sprintf($sql,$id));
$ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $dateiModul WHERE id = '$idModul'"));
}
break;
case 'konten':
case 'artikel':
case 'onlineshops':
case 'benutzer':
case 'bestellung':
case 'produktion':
$ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'"));
break;
case 'adresse':
$ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")) || ($this->app->erp->ModulVorhanden('vertriebscockpit') && $this->app->DB->Select("SELECT id FROM adresse WHERE id = '$id' AND vertrieb = '".$this->app->User->GetAdresse()."' LIMIT 1") > 0);
break;
}
} else {
$modact = array('artikel'=>array('einkauf', 'dateien','eigenschaften','verkauf','statistik','etikett','offenebestellungen','offeneauftraege','zertifikate','fremdnummern')
,'adresse' => array('rollen','ansprechpartner','lieferadresse','accounts','brief','belege','kundeartikel','abrechnungzeit','artikel','service','serienbrief')
,'lieferschein' => array('paketmarke')
);
foreach($modact as $mod => $actarr)
{
if($module == $mod)
{
foreach($actarr as $v)
{
if($v == $action)
{
if($module === 'adresse')
{
$ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")) || ($this->app->erp->ModulVorhanden('vertriebscockpit') && $this->app->DB->Select("SELECT id FROM adresse WHERE id = '$id' AND vertrieb = '".$this->app->User->GetAdresse()."' LIMIT 1") > 0);
}else{
$ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'"));
}
}
}
}
}
}
}
}
// wenn es nicht erlaubt ist
if($ret!=true)
{
if($this->app->User->GetID()<=0)
{
$this->app->erp->Systemlog("Keine gueltige Benutzer ID erhalten",1);
echo str_replace('BACK',"index.php?module=welcome&action=login",$this->app->Tpl->FinalParse("permissiondenied.tpl"));
}
else {
$this->app->erp->Systemlog("Fehlendes Recht",1);
echo str_replace('BACK',isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'',$this->app->Tpl->FinalParse("permissiondenied.tpl"));
}
http_response_code(401);
exit;
}
return $ret;
}
/**
* @param int $userId
* @param int $addressId
*
* @return array
*/
public function getEmailAddressFromUserAddress(int $userId, int $addressId): array
{
$mailAddress = trim((string)$this->app->DB->Select(
"SELECT `email` FROM `adresse` WHERE `id` = '{$addressId}' AND `geloescht` <> 1 LIMIT 1"
));
$mailAddresses = [];
if($mailAddress !== '') {
$mailAddresses[] = $mailAddress;
}
$isUserAdmin = $this->app->DB->Select(
"SELECT `id` FROM `user` WHERE `id` = '{$userId}' AND `type` = 'admin' LIMIT 1"
) > 0;
if(!$isUserAdmin) {
return $mailAddresses;
}
$mailAddress = trim((string)$this->app->erp->Firmendaten('email'));
if($mailAddress !== '' && $mailAddress !== 'mail@ihr_mail_server.de') {
$mailAddresses[] = $mailAddress;
}
/** @var EnvironmentConfig $environmentConfig */
$environmentConfig = $this->app->Container->get('EnvironmentConfig');
$mailAddresses = array_merge($mailAddresses, $environmentConfig->getSystemFallbackEmailAddresses());
return array_unique($mailAddresses);
}
public function Passwortvergessen()
{
$code = $this->app->Secure->GetGET('code');
$vergessenusername = $this->app->Secure->GetPOST('vergessenusername');
$aendern = $this->app->Secure->GetPOST('aendern');
$this->app->DB->Update("UPDATE `user` SET vergessencode = '' WHERE vergessencode <> '' AND (isnull(`vergessenzeit`) OR `vergessenzeit` = '0000-00-00 00:00:00' OR now() > DATE_ADD(`vergessenzeit`, INTERVAL 1 DAY) )");
if($code)
{
$user = $this->app->DB->Select("SELECT id FROM `user` WHERE vergessencode <> '' AND vergessencode = '$code' LIMIT 1");
if($user)
{
if($aendern)
{
$passwortwiederholen = $this->app->Secure->GetPOST('passwortwiederholen');
$passwort = $this->app->Secure->GetPOST('passwort');
if((string)$passwort !== '') {
if($passwort === $passwortwiederholen) {
if(strlen($passwort) >= 6) {
$salt = hash('sha512',microtime(true));
$passwordsha512 = $this->app->DB->real_escape_string(hash('sha512', $_POST['passwort'].$salt));
$salt = $this->app->DB->real_escape_string($salt);
$this->app->DB->Update("UPDATE `user` SET `vergessencode` = '',`fehllogins` = 0, `password` = '', `passwordmd5` = '',`passwordhash`='', `salt` = '$salt',`passwordsha512` = '".$passwordsha512."' WHERE `id` = '$user' LIMIT 1");
$this->app->DB->Delete("DELETE FROM `useronline` WHERE `user_id`='".$user."'");
$this->app->DB->Insert("INSERT INTO `useronline` (`user_id`,`sessionid`, `ip`, `login`, `time`)
VALUES ('".$user."','".$this->session_id."','".$_SERVER['REMOTE_ADDR']."','1',NOW())");
header('Location: index.php?module=welcome&action=start&msg='.$this->app->erp->base64_url_encode('
Passwort wurde geändert
'));
exit;
}
$this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', 'Das Passwort muss mindestens 6 Zeichen besitzen.
');
}else{
$this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', 'Passwörter stimmen nicht überein.
');
}
}else{
$this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', 'Bitte ein Passwort eingeben.
');
}
}
$this->app->Tpl->Set('VORZURUECKSETZEN', '');
$this->app->Tpl->Set('USERNAME', $this->app->DB->Select("SELECT `username` FROM `user` WHERE `id` = '$user' LIMIT 1"));
}else{
$this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', 'Der Link ist nicht mehr gültig.
');
$this->app->Tpl->Set('VORPASSWORT', '');
}
}
else{
if((string)$vergessenusername !== '') {
$user = $this->app->DB->SelectRow(
"SELECT `id`, `adresse` FROM `user` WHERE `activ` = 1 AND `username` = '{$vergessenusername}' LIMIT 1"
);
$userId = $user['id'] ?? null;
$addressId = $user['adresse'] ?? null;
$emailAddresses = [];
$mailSuccessfullySent = false;
if($userId > 0) {
$emailAddresses = $this->getEmailAddressFromUserAddress((int)$userId, (int)$addressId);
}
if(!empty($emailAddresses)) {
$name = $vergessenusername;
$anrede = '';
if($addressId > 0) {
$addressFields = $this->app->DB->SelectRow(
"SELECT `name`, `anschreiben` FROM `adresse` WHERE `id` = '{$addressId}' LIMIT 1"
);
$name = $addressFields['name'] ?? null;
$anrede = $addressFields['anschreiben'] ?? null;
}
$code = sha1(microtime(true));
if(
!$this->app->DB->Select(
"SELECT `id`
FROM `user`
WHERE `id` = '{$userId}' AND `vergessencode` <> ''
AND ifnull(`vergessenzeit`, '0000-00-00 00:00:00') <> '0000-00-00 00:00:00'
AND `vergessenzeit` > DATE_SUB(now(), INTERVAL 5 MINUTE)
LIMIT 1"
)
) {
$this->app->DB->Update(
"UPDATE `user` SET `vergessencode` = '{$code}', `vergessenzeit` = now() WHERE `id` = '{$userId}' LIMIT 1"
);
$language = $this->app->DB->Select("SELECT `sprachebevorzugen` FROM `user` WHERE `id`='{$userId}' LIMIT 1");
if($language==''){
$language = $this->app->DB->Select("SELECT `sprache` FROM `adresse` WHERE `id`='{$addressId}' LIMIT 1");
}
if($language == ''){
$language = 'deutsch';
}
$mailContent = $this->app->erp->GetGeschaeftsBriefText('passwortvergessen', $language, 0);
$mailSubject = $this->app->erp->GetGeschaeftsBriefBetreff('passwortvergessen', $language, 0);
if((string)$mailContent === '' && $language !== 'deutsch') {
$language = 'deutsch';
$mailContent = $this->app->erp->GetGeschaeftsBriefText('passwortvergessen', $language, 0);
$mailSubject = $this->app->erp->GetGeschaeftsBriefBetreff('passwortvergessen', $language ,0);
}
if((string)$mailSubject === '') {
$mailSubject = 'Xentral Passwort zurücksetzen';
}
if((string)$mailContent === '') {
$mailContent = "{ANREDE} {NAME} Bitte klicken Sie auf dem Link {URL} um Ihr Xentral-Passwort zu ändern";
}
$server = '';
$isSecure = false;
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
$isSecure = true;
}
elseif ((!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') || (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on')) {
$isSecure = true;
}
$REQUEST_PROTOCOL = $isSecure ? 'https' : 'http';
if($_SERVER['SERVER_NAME']!='' && $_SERVER['SERVER_NAME'] !== '_') //MAMP auf macos
{
$server = $REQUEST_PROTOCOL.'://'.$_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT']!=80 && $_SERVER['SERVER_PORT'] != 433)?":".$_SERVER['SERVER_PORT']:'').$_SERVER['REQUESR_URI'].$_SERVER['SCRIPT_NAME'];
}
elseif($_SERVER['SCRIPT_URI'] != '')
{
$server = $_SERVER['SCRIPT_URI'];
}
elseif($_SERVER['REQUEST_URI'] != '' && $_SERVER['SERVER_ADDR']!='' && $_SERVER['SERVER_ADDR']!=='::1' && strpos($_SERVER['SERVER_SOFTWARE'],"nginx")===false)
{
$server = (isset($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_ADDR']?$REQUEST_PROTOCOL.'://'.$_SERVER['SERVER_ADDR'].(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443?':'.$_SERVER['SERVER_PORT']:''):'').$_SERVER['SCRIPT_NAME'];
}
$pos = strripos($server, 'index.php');
if($pos) {
$server = rtrim(substr($server, 0, $pos), '/') . '?module=welcome&action=passwortvergessen&code=' . $code;
}
else {
$server .= '/index.php?module=welcome&action=passwortvergessen&code=' . $code;
}
$serverLocation = $this->app->Location->getServer();
if(!empty($serverLocation)) {
$server = rtrim($serverLocation,'/') . '?module=welcome&action=passwortvergessen&code=' . $code;
}
foreach(['default', 'fallback'] as $sentSetting) {
if($sentSetting === 'fallback') {
$db = $this->app->Conf->WFdbname;
if(
empty(erpAPI::Ioncube_Property('cloudemail'))
|| $this->app->erp->firmendaten[$db]['email'] === erpAPI::Ioncube_Property('cloudemail')
) {
break;
}
$this->app->erp->firmendaten[$db]['mailanstellesmtp'] = 1;
$this->app->erp->firmendaten[$db]['email'] = erpAPI::Ioncube_Property('cloudemail');
}
foreach ($emailAddresses as $email) {
$recipientMailAddress = $email;
$recipientName = $name;
if(empty($recipientMailAddress) || empty($recipientName)) {
continue;
}
$mailContent = str_replace(['{NAME}', '{ANREDE}', '{URL}'], [$recipientName, $anrede, $server], $mailContent);
if(!$this->app->erp->isHTML($mailContent)){
$mailContent = str_replace("\r\n", '
', $mailContent);
}
$mailSuccessfullySent = $this->app->erp->MailSend(
$this->app->erp->GetFirmaMail(), $this->app->erp->GetFirmaAbsender(),
$recipientMailAddress, $recipientName, $mailSubject, $mailContent, '', 0, true, '', '', true
);
if($mailSuccessfullySent){
break 2;
}
}
}
}
}
if($mailSuccessfullySent || $userId <= 0) {
$this->app->Tpl->Set(
'SPERRMELDUNGNACHRICHT',
'Bitte prüfen Sie Ihr E-Mail-Postfach. Falls keine E-Mail angekommen ist wenden Sie sich bitte an den Administrator.
'
);
}
elseif(empty($emailAddresses)) {
$this->app->Tpl->Set(
'SPERRMELDUNGNACHRICHT',
'Es ist keine Email hinterlegt. Bitte wenden Sie sich an den Administrator.
'
);
}
else{
$this->app->Tpl->Set(
'SPERRMELDUNGNACHRICHT',
'Es ist ein Fehler beim Senden der Email aufgetreten. Bitte wenden Sie sich an den Administrator.
'
);
}
}
$this->app->Tpl->Set('VORPASSWORT', '');
}
$this->app->Tpl->Parse('PAGE','passwortvergessen.tpl');
}
/**
* @param int|null $id
*
* @return bool|int
*/
public function IsAdminadmin($id = null)
{
if($id === null && !empty($this->app->User) && method_exists($this->app->User, 'GetID')) {
$id = $this->app->User->GetID();
}
if(!$id) {
return false;
}
$userarr = $this->app->DB->SelectRow("SELECT * FROM `user` WHERE id = '$id' AND activ = 1 AND ifnull(hwtoken, 0) = 0 LIMIT 1");
if(empty($userarr)) {
return false;
}
$hash = 'isadminadmin_'.md5(json_encode($userarr));
$cache = (string)$this->app->User->GetParameter($hash);
if($cache !== '') {
$cache = (int)$cache;
if($cache === 0) {
return false;
}
if($cache === 1) {
return true;
}
if($cache === 2) {
return 2;
}
}
$lastCache = $this->app->User->GetParameter('isadminadmin_lastcache');
$isSameHash = $lastCache === $hash;
if((string)$lastCache !== '' && !$isSameHash){
$this->app->User->deleteParameter($lastCache);
}
if(!$isSameHash) {
$this->app->User->SetParameter('isadminadmin_lastcache', $hash);
}
if($userarr['passwordhash'] != '' && password_verify ( 'admin' , $userarr['passwordhash'] )) {
$this->app->User->SetParameter($hash, 1);
return true;
}
if($userarr['passwordhash'] != '') {
$ret = password_verify ( $userarr['username'] , $userarr['passwordhash'] )?2:false;
$this->app->User->SetParameter($hash, (int)$ret);
return $ret;
}
if($userarr['passwordsha512'] != '' && hash('sha512','admin'.$userarr['salt']) === $userarr['passwordsha512']) {
$this->app->User->SetParameter($hash, 1);
return true;
}
if($userarr['passwordsha512'] != '') {
$ret = hash('sha512',$userarr['username'].$userarr['salt']) === $userarr['passwordsha512']?2:false;
$this->app->User->SetParameter($hash, (int)$ret);
return $ret;
}
if(md5('admin') == $userarr['passwordmd5']) {
$this->app->User->SetParameter($hash, 1);
return true;
}
$ret = md5($userarr['username']) == $userarr['passwordmd5']?2:false;
$this->app->User->SetParameter($hash, (int)$ret);
return $ret;
}
public function Login()
{
include dirname(__DIR__).'/../version.php';
$this->app->Tpl->Set('XENTRALVERSION',"V.".$version_revision);
$this->app->Tpl->Set('LOGINWARNING_VISIBLE', 'hidden');
$result = $this->CheckHtaccess();
if ($result !== true) {
$this->app->Tpl->Set('LOGINWARNING_VISIBLE', '');
$this->app->Tpl->Set('LOGINWARNING_TEXT', "Achtung: Zugriffskonfiguration (htaccess) fehlerhaft. Bitte wenden Sie sich an Ihren an Ihren Administrator.
($result)");
}
if($this->IsInLoginLockMode() === true)
{
$this->app->Tpl->Set('LOGINWARNING_VISIBLE', '');
$this->app->Tpl->Set('LOGINWARNING_TEXT', 'Achtung: Es werden gerade Wartungsarbeiten in Ihrem System (z.B. Update oder Backup) durch Ihre IT-Abteilung durchgeführt. Das System sollte in wenigen Minuten wieder erreichbar sein. Für Rückfragen wenden Sie sich bitte an Ihren Administrator.');
}
$multidbs = $this->app->getDbs();
if(count($multidbs) > 1)
{
$options = '';
foreach($multidbs as $k => $v)
{
$options .= '