Add files via upload

TT-261314: NEW updated GrapesJs plugin
TT-261010: FIX SEC weak password reset token, RCE
TT-261010: FIX SEC file upload
This commit is contained in:
Manuele Maporti 2022-10-20 11:00:24 +02:00 committed by GitHub
parent 45498a0594
commit 1751057dec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 837 additions and 173 deletions

View File

@ -22,7 +22,7 @@
<script src="include/js/grapesjs/grapesjs-preset-newsletter.min.js"></script> <script src="include/js/grapesjs/grapesjs-preset-newsletter.min.js"></script>
<script src="include/js/grapesjs/grapesjs-image-manager.min.js"></script> <!-- crmv@201352 --> <script src="include/js/grapesjs/grapesjs-image-manager.min.js"></script> <!-- crmv@201352 -->
<script src="{"include/js/general.js"|resourcever}"></script> <script src="{"include/js/general.js"|resourcever}"></script>
<script src="modules/SDK/src/Grapes/Grapes.js"></script> <script src="{"modules/SDK/src/Grapes/Grapes.js"|resourcever}"></script>{* crmv@231245 *}
<script type="text/javascript"> <script type="text/javascript">
{if $ALL_VARIABLES} {if $ALL_VARIABLES}

View File

@ -13,9 +13,9 @@
<link rel="stylesheet" type="text/css" href="themes/next/select2.css" media="screen" /> <link rel="stylesheet" type="text/css" href="themes/next/select2.css" media="screen" />
<link rel="stylesheet" type="text/css" href="themes/next/vte_materialize.css" media="screen" /> <link rel="stylesheet" type="text/css" href="themes/next/vte_materialize.css" media="screen" />
<script language="JAVASCRIPT" type="text/javascript" src="include/js/{$CURRENT_LANGUAGE}.lang.js"></script> <script language="JAVASCRIPT" type="text/javascript" src="{"include/js/`$CURRENT_LANGUAGE`.lang.js"|resourcever}"></script>{* crmv@231245 *}
<script language="JavaScript" type="text/javascript" src="{$RELPATH}{"include/js/general.js"|resourcever}"></script> <script language="JavaScript" type="text/javascript" src="{$RELPATH}{"include/js/general.js"|resourcever}"></script>
<script language="JavaScript" type="text/javascript" src="{$RELPATH}modules/Campaigns/Campaigns.js|resourcever}"></script> <script language="JavaScript" type="text/javascript" src="{$RELPATH}{"modules/Campaigns/Campaigns.js"|resourcever}"></script>{* crmv@231245 *}
<div id="nlw_templateEditCont"> <div id="nlw_templateEditCont">
<input type="hidden" id="nlw_templateEditId" value="{$TPL_ID}" /> <input type="hidden" id="nlw_templateEditId" value="{$TPL_ID}" />

View File

@ -51,6 +51,15 @@
border-radius: 0; border-radius: 0;
} }
.gjs-rte-action {
width: auto;
min-width: 25px;
}
.gjs-rte-action svg {
width: 20px;
}
.template-vars-input { .template-vars-input {
background-color: white; background-color: white;
max-width: 120px; max-width: 120px;

View File

@ -26,12 +26,12 @@ $PORTAL_URL = '_SITE_URL_/portal';
// helpdesk support email id and support name (Example: 'support@vte.biz' and 'VTE Support') // helpdesk support email id and support name (Example: 'support@vte.biz' and 'VTE Support')
$HELPDESK_SUPPORT_EMAIL_ID = '_USER_SUPPORT_EMAIL_'; $HELPDESK_SUPPORT_EMAIL_ID = '_USER_SUPPORT_EMAIL_';
$HELPDESK_SUPPORT_NAME = 'VTE Notification System'; $HELPDESK_SUPPORT_NAME = $enterprise_mode.' Notification System'; // crmv@261010_1
$HELPDESK_SUPPORT_EMAIL_REPLY_ID = $HELPDESK_SUPPORT_EMAIL_ID; $HELPDESK_SUPPORT_EMAIL_REPLY_ID = $HELPDESK_SUPPORT_EMAIL_ID;
//crmv@10488 //crmv@10488
$REMINDER_EMAIL_ID ='_USER_SUPPORT_EMAIL_'; $REMINDER_EMAIL_ID ='_USER_SUPPORT_EMAIL_';
$REMINDER_NAME = 'VTE Notification System'; $REMINDER_NAME = $enterprise_mode.' Notification System'; // crmv@261010_1
//crmv@10488 e\ //crmv@10488 e\
/* database configuration /* database configuration

View File

@ -232,6 +232,11 @@ private function isDir($dir) {
if(!in_array($size[2], array(1, 2, 3, 7, 8))) { if(!in_array($size[2], array(1, 2, 3, 7, 8))) {
$this->error(sprintf($this->lang('UPLOAD_IMAGES_TYPE_JPEG_GIF_PNG')),true); $this->error(sprintf($this->lang('UPLOAD_IMAGES_TYPE_JPEG_GIF_PNG')),true);
} }
// crmv@261010_2
if (!in_array(strtolower(pathinfo($_FILES['newfile']['name'], PATHINFO_EXTENSION)), $this->config['images'])) {
$this->error(sprintf($this->lang('UPLOAD_IMAGES_TYPE_JPEG_GIF_PNG')), true);
}
// crmv@261010_2e
} }
$_FILES['newfile']['name'] = $this->cleanString($_FILES['newfile']['name'],array('.','-')); $_FILES['newfile']['name'] = $this->cleanString($_FILES['newfile']['name'],array('.','-'));
if(!$this->config['upload']['overwrite']) { if(!$this->config['upload']['overwrite']) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! grapesjs-plugin-ckeditor - 0.0.9 */ /*! grapesjs-plugin-ckeditor - 0.0.10 */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("grapesjs")):"function"==typeof define&&define.amd?define(["grapesjs"],t):"object"==typeof exports?exports["grapesjs-plugin-ckeditor"]=t(require("grapesjs")):e["grapesjs-plugin-ckeditor"]=t(e.grapesjs)}("undefined"!=typeof self?self:this,function(e){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(1),r=function(e){return e&&e.__esModule?e:{default:e}}(o),i=function(e){return e.stopPropagation()};t.default=r.default.plugins.add("gjs-plugin-ckeditor",function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t,o={options:{},position:"left"};for(var a in o)a in n||(n[a]=o[a]);if(!CKEDITOR)throw new Error("CKEDITOR instance not found");e.setCustomRte({enable:function(t,o){if(o&&"destroyed"!=o.status)return this.focus(t,o),o;t.contentEditable=!0;var a=e.RichTextEditor.getToolbarEl();[].forEach.call(a.children,function(e){e.style.display="none"});var s=n.options;return s.extraPlugins?"string"==typeof s.extraPlugins?s.extraPlugins+=",sharedspace":s.extraPlugins.push("sharedspace"):s.extraPlugins="sharedspace",n.options.sharedSpaces||(n.options.sharedSpaces={top:a}),o=CKEDITOR.inline(t,n.options),o.on("contentDom",function(){var e=o.editable();e.attachListener(e,"click",function(){t.click()})}),o.on("instanceReady",function(t){var n=a.querySelector("#cke_"+o.name);n&&(n.style.display="block"),e.trigger("canvasScroll")}),o.on("dialogShow",function(e){var t=r.default.$(".cke_dialog_background_cover, .cke_dialog");["off","on"].forEach(function(e){return t[e]("mousedown",i)})}),this.focus(t,o),o},disable:function(e,t){e.contentEditable=!1,t&&t.focusManager&&t.focusManager.blur(!0)},focus:function(e,t){t&&t.focusManager.hasFocus||(e.contentEditable=!0,t&&t.focus())}}),e.on("rteToolbarPosUpdate",function(e){switch(n.position){case"center":var t=e.elementWidth/2-e.targetWidth/2;e.left=e.elementLeft+t;break;case"right":var o=e.targetWidth;e.left=e.elementLeft+e.elementWidth-o}e.top<=e.canvasTop&&(e.top=e.elementTop+e.elementHeight),e.left<e.canvasLeft&&(e.left=e.canvasLeft)})})},function(t,n){t.exports=e}])}); !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("grapesjs")):"function"==typeof define&&define.amd?define(["grapesjs"],t):"object"==typeof exports?exports["grapesjs-plugin-ckeditor"]=t(require("grapesjs")):e["grapesjs-plugin-ckeditor"]=t(e.grapesjs)}("undefined"!=typeof self?self:this,function(e){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(1),r=function(e){return e&&e.__esModule?e:{default:e}}(o),a=function(e){return e.stopPropagation()};t.default=r.default.plugins.add("gjs-plugin-ckeditor",function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t,o={options:{},position:"left"};for(var i in o)i in n||(n[i]=o[i]);if(!CKEDITOR)throw new Error("CKEDITOR instance not found");e.setCustomRte({enable:function(t,o){if(o&&"destroyed"!=o.status)return this.focus(t,o),o;t.contentEditable=!0;var i=e.RichTextEditor.getToolbarEl();[].forEach.call(i.children,function(e){e.style.display="none"});var s=n.options;return s.extraPlugins?"string"==typeof s.extraPlugins?s.extraPlugins+=",sharedspace":s.extraPlugins.push("sharedspace"):s.extraPlugins="sharedspace",n.options.sharedSpaces||(n.options.sharedSpaces={top:i}),o=CKEDITOR.inline(t,n.options),o.getContent=o.getData,o.on("contentDom",function(){var e=o.editable();e.attachListener(e,"click",function(){t.click()})}),o.on("instanceReady",function(t){var n=i.querySelector("#cke_"+o.name);n&&(n.style.display="block"),e.trigger("canvasScroll")}),o.on("dialogShow",function(e){var t=r.default.$(".cke_dialog_background_cover, .cke_dialog");["off","on"].forEach(function(e){return t[e]("mousedown",a)})}),this.focus(t,o),o},disable:function(e,t){e.contentEditable=!1,t&&t.focusManager&&t.focusManager.blur(!0)},focus:function(e,t){t&&t.focusManager.hasFocus||(e.contentEditable=!0,t&&t.focus())}}),e.on("rteToolbarPosUpdate",function(e){switch(n.position){case"center":var t=e.elementWidth/2-e.targetWidth/2;e.left=e.elementLeft+t;break;case"right":var o=e.targetWidth;e.left=e.elementLeft+e.elementWidth-o}e.top<=e.canvasTop&&(e.top=e.elementTop+e.elementHeight),e.left<e.canvasLeft&&(e.left=e.canvasLeft)})})},function(t,n){t.exports=e}])});

View File

@ -143,6 +143,34 @@ VTE.GrapesEditor = VTE.GrapesEditor || {
//jQuery('.fa-bars').hide(); //remove Open Layer Manager //jQuery('.fa-bars').hide(); //remove Open Layer Manager
var blockManager = editor.BlockManager; var blockManager = editor.BlockManager;
// crmv@261314
editor.Components.addType('image-with-link', {
extend: 'link',
model: {
defaults: {
style: {
display: 'inline-block',
padding: '5px',
'min-height': '50px',
'min-width': '50px'
},
components: {
type: 'image',
}
}
}
});
blockManager.add('image-with-link', {
label: 'Image Link',
attributes: { class: 'fa fa-image' },
content: {
type: 'image-with-link'
}
});
// crmv@261314e
blockManager.add('olist', { blockManager.add('olist', {
label: 'Ordered List', label: 'Ordered List',
attributes: { attributes: {
@ -207,20 +235,26 @@ VTE.GrapesEditor = VTE.GrapesEditor || {
} }
// crmv@202326e // crmv@202326e
//selezione in automatico del tab Settings al trascinamento di un link // crmv@261314
editor.on('component:mount', function(model) { editor.on('component:mount', function(model) {
if(model.is('link')){
editor.select(model); editor.select(model);
});
editor.on('component:selected', function(model) {
if (model.is('link') || model.is('image-with-link')) {
const openBl = editor.Panels.getButton('views', 'open-tm'); const openBl = editor.Panels.getButton('views', 'open-tm');
openBl && openBl.set('active', 1) openBl && openBl.set('active', 1);
} else {
const openSmBtn = editor.Panels.getButton('views', 'open-sm');
openSmBtn && openSmBtn.set('active', 1);
} }
}); });
// crmv@261314e
me.editor = editor; me.editor = editor;
me.customizeEditor(editor); me.customizeEditor(editor);
me.loadAssets(me.images_uploaded); me.loadAssets(me.images_uploaded);
}, },
checkEndpoint: function(){ checkEndpoint: function(){
@ -418,10 +452,25 @@ VTE.GrapesEditor = VTE.GrapesEditor || {
attributes: { attributes: {
title: 'Edit Code' title: 'Edit Code'
} }
},
{
id: 'undo',
className: 'fa fa-undo',
attributes: { title: 'Undo' },
command: function() {
editor.runCommand('core:undo');
} }
},
{
id: 'redo',
className: 'fa fa-repeat',
attributes: { title: 'Redo' },
command: function() {
editor.runCommand('core:redo');
}
},
] ]
); );
}, },
loadAssets: function(files){ loadAssets: function(files){

View File

@ -0,0 +1,43 @@
<?php
// crmv@261010_1
// change sender name of system emails
$configInc = file_get_contents('config.inc.php');
if (empty($configInc)) {
Update::info("Unable to get config.inc.php contents, please modify it manually.");
} else {
// backup it (only if it doesn't exist)
$newConfigInc = 'config.inc.2211.php';
if (!file_exists($newConfigInc)) {
file_put_contents($newConfigInc, $configInc);
}
if (is_writable('config.inc.php')) {
$configInc = preg_replace('/^\$HELPDESK_SUPPORT_NAME.*$/m', "\$HELPDESK_SUPPORT_NAME = \$enterprise_mode.' Notification System';", $configInc);
$configInc = preg_replace('/^\$REMINDER_NAME.*$/m', "\$REMINDER_NAME = \$enterprise_mode.' Notification System';", $configInc);
file_put_contents('config.inc.php', $configInc);
} else {
Update::info("Unable to update config.inc.php, please modify it manually.");
}
}
global $enterprise_mode;
SDK::setLanguageEntries('Users', 'LBL_RECOVER_EMAIL_BODY2', array(
'it_it'=>'per proseguire ed immettere la nuova password.<br />Hai a disposizione 15 minuti per terminare questo processo di recupero password. Passati i 15 minuti dovrai ripetere la procedura dall\'inizio cliccando nuovamente il link "Hai dimenticato la password?" nella pagina di login.',
'en_us'=>'to continue and enter the new password.<br />You have 15 minutes to finish the password recovery process. Passed the 15 minutes you will have to start by clicking again on the link "Forgot your password?" at the login page.'
));
SDK::setLanguageEntries('Users', 'LBL_RECOVERY_EMAIL_PASSWORD_SAVED', array(
'it_it'=>'La tua password è stata cambiata con successo dall\'indirizzo ip %s. Premere %s per il login.',
'en_us'=>'Your password was successfully changed from the ip %s. Click %s for login.'
));
SDK::setLanguageEntries('Users', 'LBL_RECOVER_EMAIL_SUBJECT', array(
'it_it'=>$enterprise_mode.' Recupero password',
'en_us'=>$enterprise_mode.' Password recovery'
));
SDK::setLanguageEntries('Users', 'LBL_RECOVERY_SYSTEM4', array(
'it_it'=>'altrimenti procedi per inserire la nuova password.',
'en_us'=>'or proceed to enter the new password.'
));
SDK::setLanguageEntries('Users', 'LBL_RECOVERY_TOO_MANY_ATTEMPTS', array(
'it_it'=>'Sei stato temporaneamente bloccato per troppi tentativi di recupero password. Riprova tra 1 ora.',
'en_us'=>'You have been temporarily blocked for too many password recovery attempts. Try again in 1 hour.'
));

View File

@ -0,0 +1,12 @@
<?php
/* new release 20.04.2 */
global $enterprise_current_version, $enterprise_mode;
SDK::setLanguageEntries('APP_STRINGS', 'LBL_BROWSER_TITLE', array(
'it_it'=>"$enterprise_mode $enterprise_current_version",
'en_us'=>"$enterprise_mode $enterprise_current_version",
'de_de'=>"$enterprise_mode $enterprise_current_version",
'nl_nl'=>"$enterprise_mode $enterprise_current_version",
'pt_br'=>"$enterprise_mode $enterprise_current_version")
);

View File

@ -133,8 +133,11 @@ else
// crmv@43592 // crmv@43592
if ($loadResult == 'EXPIRED') { // crmv@187476 if ($loadResult == 'EXPIRED') { // crmv@187476
// generate a token for the change password (1 hour only) // crmv@261010_1 generate a token for the change password
$key = getUserAuthtokenKey('password_recovery',$focus->id,3600); require_once('modules/Users/RecoverPwd.php');
$recoverPwd = new RecoverPwd();
$key = getUserAuthtokenKey($recoverPwd->user_auth_token_type,$focus->id,$recoverPwd->user_auth_seconds_to_expire,true);
// crmv@261010_1e
header('Location: hub/rpwd.php?action=change_old_pwd&key='.$key); // crmv@192078 header('Location: hub/rpwd.php?action=change_old_pwd&key='.$key); // crmv@192078
exit; exit;
} }

View File

@ -4,13 +4,17 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
************************************/ ************************************/
/* crmv@192078 */ /* crmv@192078 crmv@171581 crmv@261010_1 */
// crmv@171581
class RecoverPwd { class RecoverPwd {
public $user_auth_token_type = 'password_recovery'; public $user_auth_token_type = 'password_recovery';
public $user_auth_seconds_to_expire = 86400; // 1 day in seconds public $user_auth_seconds_to_expire = 900; // 15 minutes in seconds
// allow max 5 attempts in 1 hour from the same ip, reached the limit the ip is blocked for 1 hour
private $max_recover_attempts = 5;
private $max_recover_attempts_window = 3600; // seconds
private $max_recover_attempts_sleep = 3600; // seconds
public function process(&$request, &$post) { public function process(&$request, &$post) {
global $default_charset; global $default_charset;
@ -20,8 +24,10 @@ class RecoverPwd {
header('Content-Type: text/html; charset=' . $default_charset); header('Content-Type: text/html; charset=' . $default_charset);
if ($action == 'change_password') { if ($action == 'change_password') {
$body = $this->displayChangePwd($smarty, $post['key'], $post['confirm_new_password']); $body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
} elseif ($action == 'recover') { } elseif ($action == 'recover') {
$body = $this->displayRecoverLandingPage($smarty, $request['key']);
} elseif ($action == 'recover1') {
$body = $this->displayRecover($smarty, $request['key']); $body = $this->displayRecover($smarty, $request['key']);
} elseif ($action == 'send') { } elseif ($action == 'send') {
$body = $this->displaySend($smarty, $post['user_name']); $body = $this->displaySend($smarty, $post['user_name']);
@ -55,7 +61,20 @@ class RecoverPwd {
public function displayMainForm($smarty) { public function displayMainForm($smarty) {
global $site_URL; global $site_URL;
$description = '<form action="" onSubmit="if(checkRecoverForm()){ VteJS_DialogBox.block(); } else { return false; }" method="POST"> $permitted = $this->track();
if (!$permitted) {
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_TOO_MANY_ATTEMPTS','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
return $description;
}
// crmv@206770_3.2
$description = '<form action="" onSubmit="if(checkRecoverForm()){ VteJS_DialogBox.block(); } else { return false; }" method="POST" autocomplete="off">
<input type="hidden" name="action" value="send"> <input type="hidden" name="action" value="send">
<input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'"> <input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'">
<table class="table borderless"> <table class="table borderless">
@ -90,117 +109,141 @@ class RecoverPwd {
return $description; return $description;
} }
function track() {
global $adb;
$ip = getIP();
$type = 'password_recovery';
$now = date('Y-m-d H:i:s');
$user = CRMEntity::getInstance('Users');
$result = $adb->pquery("select * from {$user->track_login_table} where ip = ? and type = ?",array($ip, $type));
if ($result && $adb->num_rows($result) > 0) {
$id = $adb->query_result($result,0,'id');
$attempts = $adb->query_result($result,0,'attempts') + 1;
$current_status = $adb->query_result($result,0,'status');
$first_attempt = $adb->query_result($result,0,'first_attempt');
$last_attempt = $adb->query_result($result,0,'last_attempt');
$update = [
'last_attempt' => $now,
'attempts' => $attempts,
'status' => $current_status,
];
if ($current_status == 'L') {
// new attempt after 1 hour from the last attempt -> reset
if ((time() - strtotime($last_attempt)) >= $this->max_recover_attempts_sleep) {
$update['first_attempt'] = $now;
$update['attempts'] = 1;
$update['status'] = '';
}
} else {
// new attempt in 1 hour from the first attempt
if ((time() - strtotime($first_attempt)) < $this->max_recover_attempts_window) {
if ($attempts >= $this->max_recover_attempts) {
$update['status'] = 'L';
}
} else {
// new attempt after 1 hour from the first attempt -> reset
$update['first_attempt'] = $now;
$update['attempts'] = 1;
}
}
$query = "update {$user->track_login_table} set ".implode('=?,',array_keys($update))."=? where id = ?";
$adb->pquery($query,array($update, $id));
return ($update['status'] == '');
} else {
$params = array(
$adb->getUniqueID($user->track_login_table),
0,
$now,
$now,
$ip,
$type,
1,
''
);
$adb->pquery("insert into {$user->track_login_table} (id, userid, first_attempt, last_attempt, ip, type, attempts, status) values (".generateQuestionMarks($params).")",$params);
}
return true;
}
public function displaySend($smarty, $username) { public function displaySend($smarty, $username) {
global $adb, $table_prefix;
global $site_URL, $current_user; global $site_URL, $current_user;
if (empty($username)) return $this->displayError($smarty); if (empty($username)) return $this->displayError($smarty);
// by default show the success message, to avoid users enumeration
$description =
'<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVER_MAIL_SENT','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
$current_user = CRMEntity::getInstance('Users'); $current_user = CRMEntity::getInstance('Users');
$current_user->id = $current_user->retrieve_user_id($username); $current_user->id = $current_user->retrieve_user_id($username);
$current_user->retrieve_entity_info($current_user->id, 'Users'); $current_user->retrieve_entity_info($current_user->id, 'Users');
$current_language = $current_user->column_fields['default_language']; $current_language = $current_user->column_fields['default_language'];
if ($current_user->column_fields['email1'] != '') { $success = false;
require_once('modules/Emails/mail.php'); $key = getUserAuthtokenKey($this->user_auth_token_type,$current_user->id,$this->user_auth_seconds_to_expire,true);
global $HELPDESK_SUPPORT_NAME, $HELPDESK_SUPPORT_EMAIL_ID;
if (empty($HELPDESK_SUPPORT_EMAIL_ID) || $HELPDESK_SUPPORT_EMAIL_ID == 'admin@vte123abc987.com') {
$result = $adb->query("select email1 from {$table_prefix}_users where id = 1");
$HELPDESK_SUPPORT_EMAIL_ID = $adb->query_result($result,0,'email1');
}
$subject = getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT','Users');
$key = getUserAuthtokenKey($this->user_auth_token_type,$current_user->id,$this->user_auth_seconds_to_expire);
$mail_error = true;
if ($key !== false) { if ($key !== false) {
$mail_error = false;
$link = "<a href='$site_URL/hub/rpwd.php?action=recover&key=$key'>".getTranslatedString('LBL_HERE','APP_STRINGS')."</a>"; $link = "<a href='$site_URL/hub/rpwd.php?action=recover&key=$key'>".getTranslatedString('LBL_HERE','APP_STRINGS')."</a>";
$body = getTranslatedString('Dear','HelpDesk').' '.$_POST['user_name'].',<br><br>'; $body = getTranslatedString('Dear','HelpDesk').' '.$username.',<br><br>';
$body .= sprintf(getTranslatedString('LBL_RECOVER_EMAIL_BODY1','Users'),getIP()).' '.$link.' '.getTranslatedString('LBL_RECOVER_EMAIL_BODY2','Users'); // crmv@193845 $body .= sprintf(getTranslatedString('LBL_RECOVER_EMAIL_BODY1','Users'),getIP()).' '.$link.' '.getTranslatedString('LBL_RECOVER_EMAIL_BODY2','Users'); // crmv@193845
$body .= '<br><br>'.getTranslatedString("LBL_REGARDS",'HelpDesk').',<br>'.getTranslatedString("LBL_TEAM",'HelpDesk'); $body .= '<br><br>'.getTranslatedString("LBL_REGARDS",'HelpDesk').',<br>'.getTranslatedString("LBL_TEAM",'HelpDesk');
$success = $this->sendMail($current_user->column_fields['email1'], getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT','Users'), $body);
//crmv@157490
$serverConfigUtils = ServerConfigUtils::getInstance();
$server = $serverConfigUtils->getConfiguration('email',array('server'),'server_type',true);
//crmv@157490e
if ($server == '') {
$domains = array(
//$_SERVER['SERVER_NAME'],
substr($current_user->column_fields['email1'],strpos($current_user->column_fields['email1'],'@')+1)
);
$focusMessages = CRMEntity::getInstance('Messages');
$userAccounts = $focusMessages->getUserAccounts();
if (!empty($userAccounts)) {
foreach($userAccounts as $account) {
if (!empty($account['server'])) {
$domains[] = $account['server'];
} }
if (!empty($account['domain'])) {
$domains[] = $account['domain'];
}
if (!empty($account['username'])) {
$domains[] = substr($account['username'],strpos($account['username'],'@')+1);
}
}
}
$domains = array_filter($domains);
if(!empty($domains)) {
$exit = false;
foreach ($domains as $domain) {
$mxhosts = array();
getmxrr($domain, $mxhosts);
foreach($mxhosts as $mxhost) {
$servers = array_filter(array($mxhost, gethostbyname($mxhost)));
foreach ($servers as $server) {
$_REQUEST['server'] = $server;
$_REQUEST['server_username'] = '';
$_REQUEST['server_password'] = '';
$_REQUEST['smtp_auth'] = '';
$mail_status = send_mail('Users',$current_user->column_fields['email1'],$HELPDESK_SUPPORT_NAME,$HELPDESK_SUPPORT_EMAIL_ID,$subject,$body);
if($mail_status != 1) {
$mail_error = true;
} else {
$exit = true;
break;
}
}
if ($exit) {
break;
}
}
if ($exit) {
break;
}
}
}
} else {
$mail_status = send_mail('Users',$current_user->column_fields['email1'],$HELPDESK_SUPPORT_NAME,$HELPDESK_SUPPORT_EMAIL_ID,$subject,$body);
if($mail_status != 1) {
$mail_error = true;
}
}
}
if ($mail_error) {
$description = ' $description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small"> <table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVER_MAIL_ERROR','Users').'</td></tr> <tr><td colspan="2">'.getTranslatedString(($success)?'LBL_RECOVER_MAIL_SENT':'LBL_RECOVER_MAIL_ERROR','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr> <tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr> <tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>'; </table>';
}
}
return $description; return $description;
} }
public function displayRecoverLandingPage($smarty, $key) {
global $current_user, $site_URL;
$user_id = validateUserAuthtokenKey($this->user_auth_token_type,$key);
if ($user_id === false) {
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SESSION_EXPIRED','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
return $description;
}
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $user_id;
$current_user->retrieve_entity_info($current_user->id, 'Users');
$login_link = "<a href='$site_URL'>" . getTranslatedString('LBL_HERE', 'Calendar') . "</a>";
// crmv@206770_3.2
$description = '
<form action="" onsubmit="VteJS_DialogBox.block();" name="ChangePassword" method="POST" autocomplete="off">
<input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'">
<input type="hidden" name="action" value="recover1">
<input type="hidden" name="key" value="'.$key.'">
<table class="table borderless">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SYSTEM1','Users').' <b>'.$current_user->column_fields['user_name'].'</b> '.getTranslatedString('LBL_RECOVERY_SYSTEM2','Users').' '.$login_link.' '.getTranslatedString('LBL_RECOVERY_SYSTEM4','Users').'</td></tr>
<tr height="45px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="center">
<input type="submit" class="crmbutton small save" value="'.getTranslatedString('LBL_CHANGE_PASSWORD','Users').'" />
</td></tr>
</table>
</form>';
return $description;
}
public function displayRecover($smarty, $key) { public function displayRecover($smarty, $key) {
global $current_user, $site_URL; global $current_user, $site_URL;
@ -216,18 +259,20 @@ class RecoverPwd {
return $description; return $description;
} }
// remove the token the first time I load the page
emptyUserAuthtokenKey($this->user_auth_token_type,$user_id);
$current_user = CRMEntity::getInstance('Users'); $current_user = CRMEntity::getInstance('Users');
$current_user->id = $user_id; $current_user->id = $user_id;
$current_user->retrieve_entity_info($current_user->id, 'Users'); $current_user->retrieve_entity_info($current_user->id, 'Users');
$login_link = "<a href='$site_URL'>" . getTranslatedString('LBL_HERE', 'Calendar') . "</a>"; $login_link = "<a href='$site_URL'>" . getTranslatedString('LBL_HERE', 'Calendar') . "</a>";
// crmv@206770_3.2
$description = ' $description = '
<form action="" onsubmit="VteJS_DialogBox.block();" name="ChangePassword" method="POST"> <form action="" onsubmit="VteJS_DialogBox.block();" name="ChangePassword" method="POST" autocomplete="off">
<input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'"> <input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'">
<input type="hidden" name="action" value="change_password"> <input type="hidden" name="action" value="change_password">
<input type="hidden" name="key" value="'.$key.'"> <input type="hidden" name="user_name" value="'.$current_user->column_fields['user_name'].'">
<table class="table borderless"> <table class="table borderless">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SYSTEM1','Users').' <b>'.$current_user->column_fields['user_name'].'</b> '.getTranslatedString('LBL_RECOVERY_SYSTEM2','Users').' '.$login_link.' '.getTranslatedString('LBL_RECOVERY_SYSTEM3','Users').'</td></tr> <tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SYSTEM1','Users').' <b>'.$current_user->column_fields['user_name'].'</b> '.getTranslatedString('LBL_RECOVERY_SYSTEM2','Users').' '.$login_link.' '.getTranslatedString('LBL_RECOVERY_SYSTEM3','Users').'</td></tr>
@ -281,24 +326,14 @@ class RecoverPwd {
return $description; return $description;
} }
public function displayChangePwd($smarty, $key, $newpwd) { public function displayChangePwd($smarty, $username, $newpwd) {
global $site_URL, $current_user; global $site_URL, $current_user;
global $adb, $table_prefix; global $adb, $table_prefix;
$user_id = validateUserAuthtokenKey($this->user_auth_token_type,$key); // removed validateUserAuthtokenKey, there is already the CSRFT check in rpwd.php
if ($user_id === false) {
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SESSION_EXPIRED','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
return $description;
}
$current_user = CRMEntity::getInstance('Users'); $current_user = CRMEntity::getInstance('Users');
$current_user->id = $user_id; $current_user->id = $current_user->retrieve_user_id($username);
$current_user->retrieve_entity_info($current_user->id,'Users'); $current_user->retrieve_entity_info($current_user->id,'Users');
//crmv@28327 //crmv@28327
@ -316,7 +351,7 @@ class RecoverPwd {
//crmv@35153 //crmv@35153
} elseif ($current_user->id == 1 && isFreeVersion()) { } elseif ($current_user->id == 1 && isFreeVersion()) {
$result = $adb->query("SELECT hash_version FROM ".$table_prefix."_version"); $result = $adb->query("SELECT hash_version FROM ".$table_prefix."_version");
VteSession::set('vte_hash_version', Users::m_encryption(Users::de_cryption($adb->query_result_no_html($result, 0, 'hash_version')))); // crmv@208111 VteSession::set('vtiger_hash_version', Users::m_encryption(Users::de_cryption($adb->query_result_no_html($result, 0, 'hash_version'))));
$focusMorphsuit = CRMEntity::getInstance("Morphsuit"); $focusMorphsuit = CRMEntity::getInstance("Morphsuit");
$description = ' $description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small"> <table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
@ -348,18 +383,18 @@ class RecoverPwd {
}); });
</script> </script>
'; ';
emptyUserAuthtokenKey($this->user_auth_token_type,$user_id); emptyUserAuthtokenKey($this->user_auth_token_type,$current_user->id);
//crmv@35153e //crmv@35153e
} else { } else {
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); $current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true);
emptyUserAuthtokenKey($this->user_auth_token_type,$user_id); emptyUserAuthtokenKey($this->user_auth_token_type,$current_user->id);
$description = ' $description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small"> <table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_PASSWORD_SAVED','Users').'</td></tr> <tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_PASSWORD_SAVED','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr> <tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr> <tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table> </table>';
';
} }
//crmv@28327e //crmv@28327e
@ -383,8 +418,9 @@ class RecoverPwd {
$current_user = CRMEntity::getInstance('Users'); $current_user = CRMEntity::getInstance('Users');
$current_user->id = $user_id; $current_user->id = $user_id;
// crmv@206770_3.2
$description = ' $description = '
<form action="" onsubmit="VteJS_DialogBox.block();" name="ChangeOldPassword" method="POST"> <form action="" onsubmit="VteJS_DialogBox.block();" name="ChangeOldPassword" method="POST" autocomplete="off">
<input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'"> <input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'">
<input type="hidden" name="action" value="change_old_pwd_send"> <input type="hidden" name="action" value="change_old_pwd_send">
<input type="hidden" name="key" value="'.$key.'"> <input type="hidden" name="key" value="'.$key.'">
@ -514,4 +550,87 @@ class RecoverPwd {
if (!$msg) $msg = 'Internal error'; if (!$msg) $msg = 'Internal error';
return $msg; return $msg;
} }
function sendMail($to_email, $subject, $body) {
require_once('modules/Emails/mail.php');
global $adb, $table_prefix, $site_URL;
global $HELPDESK_SUPPORT_NAME, $HELPDESK_SUPPORT_EMAIL_ID;
if (empty($to_email)) return false;
if (empty($HELPDESK_SUPPORT_EMAIL_ID) || $HELPDESK_SUPPORT_EMAIL_ID == 'admin@vte123abc987.com') {
$result = $adb->query("select email1 from {$table_prefix}_users where id = 1");
$HELPDESK_SUPPORT_EMAIL_ID = $adb->query_result($result,0,'email1');
}
$mail_error = false;
// crmv@226376
// disable smtp validation when sending recovery email
$VTEP = VTEProperties::getInstance();
$VTEP->setOverride('security.smtp.validate_certs', false, 'request');
// crmv@226376e
//crmv@157490
$serverConfigUtils = ServerConfigUtils::getInstance();
$server = $serverConfigUtils->getConfiguration('email',array('server'),'server_type',true);
//crmv@157490e
if ($server == '') {
$domains = array(
//$_SERVER['SERVER_NAME'],
substr($to_email,strpos($to_email,'@')+1)
);
$focusMessages = CRMEntity::getInstance('Messages');
$userAccounts = $focusMessages->getUserAccounts();
if (!empty($userAccounts)) {
foreach($userAccounts as $account) {
if (!empty($account['server'])) {
$domains[] = $account['server'];
}
if (!empty($account['domain'])) {
$domains[] = $account['domain'];
}
if (!empty($account['username'])) {
$domains[] = substr($account['username'],strpos($account['username'],'@')+1);
}
}
}
$domains = array_filter($domains);
if(!empty($domains)) {
$exit = false;
foreach ($domains as $domain) {
$mxhosts = array();
getmxrr($domain, $mxhosts);
foreach($mxhosts as $mxhost) {
$servers = array_filter(array($mxhost, gethostbyname($mxhost)));
foreach ($servers as $server) {
$_REQUEST['server'] = $server;
$_REQUEST['server_username'] = '';
$_REQUEST['server_password'] = '';
$_REQUEST['smtp_auth'] = '';
$mail_status = send_mail('Users',$to_email,$HELPDESK_SUPPORT_NAME,$HELPDESK_SUPPORT_EMAIL_ID,$subject,$body);
if($mail_status != 1) {
$mail_error = true;
} else {
$exit = true;
break;
}
}
if ($exit) {
break;
}
}
if ($exit) {
break;
}
}
}
} else {
$mail_status = send_mail('Users',$to_email,$HELPDESK_SUPPORT_NAME,$HELPDESK_SUPPORT_EMAIL_ID,$subject,$body);
if($mail_status != 1) {
$mail_error = true;
}
}
return !$mail_error;
}
} }

View File

@ -944,6 +944,18 @@ class Users extends CRMEntity { //crmv@392267
if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_CHANGEUSERPWD, $this->id); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_CHANGEUSERPWD, $this->id);
// crmv@90935e // crmv@90935e
// crmv@261010_1
global $site_URL;
require_once('modules/Users/RecoverPwd.php');
$recoverPwd = new RecoverPwd();
$link = "<a href='$site_URL'>".getTranslatedString('LBL_HERE','APP_STRINGS')."</a>";
$body = getTranslatedString('Dear','HelpDesk').' '.$this->column_fields['user_name'].',<br><br>';
$body .= sprintf(getTranslatedString('LBL_RECOVERY_EMAIL_PASSWORD_SAVED','Users'), getIP(), $link);
$body .= '<br><br>'.getTranslatedString("LBL_REGARDS",'HelpDesk').',<br>'.getTranslatedString("LBL_TEAM",'HelpDesk');
$recoverPwd->sendMail($this->column_fields['email1'], getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT','Users'), $body);
// crmv@261010_1e
return true; return true;
} }

View File

@ -1,4 +1,5 @@
<?php <?php
global $enterprise_mode;
$mod_strings = array( $mod_strings = array(
'LBL_MODULE_NAME'=>'Users', 'LBL_MODULE_NAME'=>'Users',
'LBL_MODULE_TITLE'=>'Users: Home', 'LBL_MODULE_TITLE'=>'Users: Home',
@ -575,16 +576,19 @@ $mod_strings = array(
'LBL_KEEP_ME_LOGGED_IN'=>'Keep me logged in', 'LBL_KEEP_ME_LOGGED_IN'=>'Keep me logged in',
'LBL_FORGOT_YOUR_PASSWORD'=>'Forgot your password?', 'LBL_FORGOT_YOUR_PASSWORD'=>'Forgot your password?',
'LBL_RECOVER_INTRO'=>'Please enter your user name.<br />You will receive an email with instructions on how to set a new password.', 'LBL_RECOVER_INTRO'=>'Please enter your user name.<br />You will receive an email with instructions on how to set a new password.',
'LBL_RECOVER_EMAIL_SUBJECT'=>'VTE Password recovery', 'LBL_RECOVER_EMAIL_SUBJECT'=>$enterprise_mode.' Password recovery',
'LBL_RECOVER_EMAIL_BODY1'=>'The password for your account was recovered from the ip %s.<br />To run this operation please click', 'LBL_RECOVER_EMAIL_BODY1'=>'The password for your account was recovered from the ip %s.<br />To run this operation please click',
'LBL_RECOVER_EMAIL_BODY2'=>'to continue and enter the new password.<br />You have 24 hours to finish the password recovery process. Passed the 24 hours you will have to start by clicking again on the link "Forgot your password?" at the login page.', 'LBL_RECOVER_EMAIL_BODY2'=>'to continue and enter the new password.<br />You have 15 minutes to finish the password recovery process. Passed the 15 minutes you will have to start by clicking again on the link "Forgot your password?" at the login page.',
'LBL_RECOVER_MAIL_SENT'=>'The mail with the instructions on how to reset the password has been sent', 'LBL_RECOVER_MAIL_SENT'=>'The mail with the instructions on how to reset the password has been sent',
'LBL_RECOVER_MAIL_ERROR'=>'We are unable to send mail.<br />Contact the administrator and request a password change.', 'LBL_RECOVER_MAIL_ERROR'=>'We are unable to send mail.<br />Contact the administrator and request a password change.',
'LBL_RECOVERY_SYSTEM1'=>'Welcome to the password recovery system.<br />If you are not the user', 'LBL_RECOVERY_SYSTEM1'=>'Welcome to the password recovery system.<br />If you are not the user',
'LBL_RECOVERY_SYSTEM2'=>'please click', 'LBL_RECOVERY_SYSTEM2'=>'please click',
'LBL_RECOVERY_SYSTEM3'=>'or fill out the fields below to replace the old password.', 'LBL_RECOVERY_SYSTEM3'=>'or fill out the fields below to replace the old password.',
'LBL_RECOVERY_SYSTEM4' => 'or proceed to enter the new password.',
'LBL_RECOVERY_PASSWORD_SAVED'=>'New password saved.', 'LBL_RECOVERY_PASSWORD_SAVED'=>'New password saved.',
'LBL_RECOVERY_SESSION_EXPIRED'=>'Session timed out. Please repeat the password recovery process.', 'LBL_RECOVERY_SESSION_EXPIRED'=>'Session timed out. Please repeat the password recovery process.',
'LBL_RECOVERY_EMAIL_PASSWORD_SAVED' => 'Your password was successfully changed from the ip %s. Click %s for login.',
'LBL_RECOVERY_TOO_MANY_ATTEMPTS' => 'You have been temporarily blocked for too many password recovery attempts. Try again in 1 hour.',
'LBL_SAVELOGIN_HELP'=>'Be sure that your server have session.gc_maxlifetime = 2592000 in php.ini file in order to activate this feature.', 'LBL_SAVELOGIN_HELP'=>'Be sure that your server have session.gc_maxlifetime = 2592000 in php.ini file in order to activate this feature.',
'LBL_USER_BLOCKED'=>'The user is blocked because he/she has not been using the account for more then %s months. Please contact your administrator to reactivate it.', 'LBL_USER_BLOCKED'=>'The user is blocked because he/she has not been using the account for more then %s months. Please contact your administrator to reactivate it.',
'LBL_PASSWORD_TO_BE_CHANGED'=>'Please change your password every %s months.', 'LBL_PASSWORD_TO_BE_CHANGED'=>'Please change your password every %s months.',

View File

@ -3,6 +3,7 @@
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com> * SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
************************************/ ************************************/
global $enterprise_mode;
$mod_strings = array ( $mod_strings = array (
'LBL_MODULE_NAME' => 'Utenti', 'LBL_MODULE_NAME' => 'Utenti',
'LBL_MODULE_TITLE' => 'Utenti: Home', 'LBL_MODULE_TITLE' => 'Utenti: Home',
@ -623,16 +624,19 @@ $mod_strings = array (
'LBL_KEEP_ME_LOGGED_IN' => 'Resta collegato', 'LBL_KEEP_ME_LOGGED_IN' => 'Resta collegato',
'LBL_FORGOT_YOUR_PASSWORD' => 'Hai dimenticato la password?', 'LBL_FORGOT_YOUR_PASSWORD' => 'Hai dimenticato la password?',
'LBL_RECOVER_INTRO' => 'Inserisci il tuo nome utente.<br />Ti verrà inviata una mail con le istruzioni per impostare una nuova password.', 'LBL_RECOVER_INTRO' => 'Inserisci il tuo nome utente.<br />Ti verrà inviata una mail con le istruzioni per impostare una nuova password.',
'LBL_RECOVER_EMAIL_SUBJECT' => 'VTE Recupero password', 'LBL_RECOVER_EMAIL_SUBJECT' => $enterprise_mode.' Recupero password',
'LBL_RECOVER_EMAIL_BODY1' => 'È stata eseguita una richiesta di recupero password per il tuo account dall\'indirizzo ip %s.<br />Se hai eseguito tu questa richiesta clicca', 'LBL_RECOVER_EMAIL_BODY1' => 'È stata eseguita una richiesta di recupero password per il tuo account dall\'indirizzo ip %s.<br />Se hai eseguito tu questa richiesta clicca',
'LBL_RECOVER_EMAIL_BODY2' => 'per proseguire ed immettere la nuova password.<br />Hai a disposizione 24 ore per terminare questo processo di recupero password. Passate le 24 ore dovrai ripetere la procedura dall\'inizio cliccando nuovamente il link "Hai dimenticato la password?" nella pagina di login.', 'LBL_RECOVER_EMAIL_BODY2' => 'per proseguire ed immettere la nuova password.<br />Hai a disposizione 15 minuti per terminare questo processo di recupero password. Passati i 15 minuti dovrai ripetere la procedura dall\'inizio cliccando nuovamente il link "Hai dimenticato la password?" nella pagina di login.',
'LBL_RECOVER_MAIL_SENT' => 'La mail con le istruzioni di reset password è stata inviata.', 'LBL_RECOVER_MAIL_SENT' => 'La mail con le istruzioni di reset password è stata inviata.',
'LBL_RECOVER_MAIL_ERROR' => 'Non è stato possibile inviare la mail.<br />Contatta l\'amministratore e richiedi il cambio password.', 'LBL_RECOVER_MAIL_ERROR' => 'Non è stato possibile inviare la mail.<br />Contatta l\'amministratore e richiedi il cambio password.',
'LBL_RECOVERY_SYSTEM1' => 'Benvenuto nel sistema di recupero password.<br />Se non sei l\'utente', 'LBL_RECOVERY_SYSTEM1' => 'Benvenuto nel sistema di recupero password.<br />Se non sei l\'utente',
'LBL_RECOVERY_SYSTEM2' => 'ti preghiamo di cliccare', 'LBL_RECOVERY_SYSTEM2' => 'ti preghiamo di cliccare',
'LBL_RECOVERY_SYSTEM3' => 'altrimenti compila i campi sottostanti con una nuova password che sostituirà la vecchia.', 'LBL_RECOVERY_SYSTEM3' => 'altrimenti compila i campi sottostanti con una nuova password che sostituirà la vecchia.',
'LBL_RECOVERY_SYSTEM4' => 'altrimenti procedi per inserire la nuova password.',
'LBL_RECOVERY_PASSWORD_SAVED' => 'La nuova password è stata salvata.', 'LBL_RECOVERY_PASSWORD_SAVED' => 'La nuova password è stata salvata.',
'LBL_RECOVERY_SESSION_EXPIRED' => 'Sessione scaduta. Ti preghiamo di ripetere la procedura di recupero password.', 'LBL_RECOVERY_SESSION_EXPIRED' => 'Sessione scaduta. Ti preghiamo di ripetere la procedura di recupero password.',
'LBL_RECOVERY_EMAIL_PASSWORD_SAVED' => 'La tua password è stata cambiata con successo dall\'indirizzo ip %s. Premere %s per il login.',
'LBL_RECOVERY_TOO_MANY_ATTEMPTS' => 'Sei stato temporaneamente bloccato per troppi tentativi di recupero password. Riprova tra 1 ora.',
//crmv@27589e //crmv@27520e //crmv@27589e //crmv@27520e
'LBL_SAVELOGIN_HELP' => 'Assicurati che il server abbia session.gc_maxlifetime = 2592000 nel php.ini per attivare la funzionalità.', 'LBL_SAVELOGIN_HELP' => 'Assicurati che il server abbia session.gc_maxlifetime = 2592000 nel php.ini per attivare la funzionalità.',
//crmv@28327 //crmv@28327

View File

@ -6,10 +6,10 @@
$patch_version = ''; $patch_version = '';
$modified_database = ''; $modified_database = '';
$vte_legacy_version = '5.2.1'; $vte_legacy_version = '5.2.1';
$enterprise_current_version = '20.04.1'; $enterprise_current_version = '20.04.2';
$enterprise_current_build = '2210'; $enterprise_current_build = '2214';
$enterprise_base_build = '2103'; // just to know where we started $enterprise_base_build = '2103'; // just to know where we started
$enterprise_mode = 'VTENEXTCE'; $enterprise_mode = 'VTENEXTCE';
$enterprise_project = ''; $enterprise_project = '';
$enterprise_subversion = 'VTENEXTCE200401'; $enterprise_subversion = 'VTENEXTCE200402';
$enterprise_website = array('http://www.vtenext.com','vtenext.com','info@vtenext.com'); $enterprise_website = array('http://www.vtenext.com','vtenext.com','info@vtenext.com');

View File

@ -0,0 +1,43 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
// crmv@67410
global $currentModule, $current_user;
$modObj = CRMEntity::getInstance($currentModule);
$ajaxaction = $_REQUEST["ajxaction"];
if($ajaxaction == "DETAILVIEW")
{
$crmid = $_REQUEST["recordid"];
$tablename = $_REQUEST["tableName"];
$fieldname = $_REQUEST["fldName"];
$fieldvalue = utf8RawUrlDecode($_REQUEST["fieldValue"]);
if($crmid != "")
{
$permEdit = isPermitted($currentModule, 'DetailViewAjax', $crmid);
$permField = getFieldVisibilityPermission($currentModule, $current_user->id, $fieldname);
if ($permEdit == 'yes' && $permField == 0) {
$modObj->retrieve_entity_info($crmid,$currentModule);
$modObj->column_fields[$fieldname] = $fieldvalue;
$modObj->id = $crmid;
$modObj->mode = "edit";
$modObj->save($currentModule);
if($modObj->id != "") {
echo ":#:SUCCESS";
} else {
echo ":#:FAILURE";
}
} else {
echo ":#:FAILURE";
}
} else {
echo ":#:FAILURE";
}
} elseif($ajaxaction == "LOADRELATEDLIST" || $ajaxaction == "DISABLEMODULE"){
require_once 'include/ListView/RelatedListViewContents.php';
}

View File

@ -0,0 +1,19 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
require_once 'modules/VteCore/EditView.php'; //crmv@30447
// crmv@64542
global $currentModule;
$templates = array(
'inventory' => 'Inventory/InventoryEditView.tpl',
'standard' => 'salesEditView.tpl',
);
$templateMode = isInventoryModule($currentModule) ? 'inventory' : 'standard';
$smarty->display($templates[$templateMode]);

View File

@ -0,0 +1,16 @@
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
//crmv@29190 crmv@69568
function set_return(product_id, product_name) {
var formName = getReturnFormName();
var form = (formName ? getReturnForm(formName) : null);
if (form) {
form.parent_name.value = product_name;
form.parent_id.value = product_id;
disableReferenceField(form.parent_name,form.parent_id,form.parent_id_mass_edit_check);
}
}
//crmv@29190e crmv@69568e

View File

@ -0,0 +1,232 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
require_once('data/CRMEntity.php');
require_once('data/Tracker.php');
class ModuleClass extends CRMEntity {
var $db, $log; // Used in class functions of CRMEntity
var $table_name;
var $table_index= 'payslipid';
var $column_fields = Array();
/** Indicator if this is a custom module or standard module */
var $IsCustomModule = true;
/**
* Mandatory table for supporting custom fields.
*/
var $customFieldTable = Array();
/**
* Mandatory for Saving, Include tables related to this module.
*/
var $tab_name = Array();
/**
* Mandatory for Saving, Include tablename and tablekey columnname here.
*/
var $tab_name_index = Array();
/**
* Mandatory for Listing (Related listview)
*/
var $list_fields = Array ();
var $list_fields_name = Array(
/* Format: Field Label => fieldname */
'Payslip Name'=> 'payslipname',
'Assigned To' => 'assigned_user_id'
);
// Make the field link to detail view from list view (Fieldname)
var $list_link_field = 'payslipname';
// For Popup listview and UI type support
var $search_fields = Array();
var $search_fields_name = Array(
/* Format: Field Label => fieldname */
'Payslip Name'=> 'payslipname'
);
// For Popup window record selection
var $popup_fields = Array('payslipname');
// Placeholder for sort fields - All the fields will be initialized for Sorting through initSortFields
var $sortby_fields = Array();
// For Alphabetical search
var $def_basicsearch_col = 'payslipname';
// Column value to use on detail view record text display
var $def_detailview_recname = 'payslipname';
// Required Information for enabling Import feature
var $required_fields = Array('payslipname'=>1);
var $default_order_by = 'payslipname';
var $default_sort_order='ASC';
// Used when enabling/disabling the mandatory fields for the module.
// Refers to vte_field.fieldname values.
var $mandatory_fields = Array('assigned_user_id', 'createdtime', 'modifiedtime', 'payslipname'); // crmv@177975
//crmv@10759
var $search_base_field = 'payslipname';
//crmv@10759 e
function __construct() {
global $log, $table_prefix; // crmv@64542
parent::__construct(); // crmv@37004
$this->table_name = $table_prefix.'_payslip';
$this->customFieldTable = Array($table_prefix.'_payslipcf', 'payslipid');
$this->entity_table = $table_prefix."_crmentity";
$this->tab_name = Array($table_prefix.'_crmentity', $table_prefix.'_payslip', $table_prefix.'_payslipcf');
$this->tab_name_index = Array(
$table_prefix.'_crmentity' => 'crmid',
$table_prefix.'_payslip' => 'payslipid',
$table_prefix.'_payslipcf' => 'payslipid'
);
$this->list_fields = Array(
/* Format: Field Label => Array(tablename, columnname) */
// tablename should not have prefix 'vte_'
'Payslip Name'=> Array($table_prefix.'_payslip', 'payslipname'),
'Assigned To' => Array($table_prefix.'_crmentity','smownerid')
);
$this->search_fields = Array(
/* Format: Field Label => Array(tablename, columnname) */
// tablename should not have prefix 'vte_'
'Payslip Name'=> Array($table_prefix.'_payslip', 'payslipname')
);
$this->column_fields = getColumnFields(get_class()); // crmv@64542
$this->db = PearDatabase::getInstance();
$this->log = $log;
}
/*
// moved in CRMEntity
function getSortOrder() { }
function getOrderBy() { }
*/
// crmv@64542
function save_module($module) {
global $adb,$table_prefix,$iAmAProcess;
// save the products block
if (!empty($module) && isInventoryModule($module)) {
//in ajax save we should not call this function, because this will delete all the existing product values
if(!empty($_REQUEST) && isset($_REQUEST['totalProductCount']) && $_REQUEST['action'] != "{$module}Ajax" && $_REQUEST['ajxaction'] != 'DETAILVIEW' && $_REQUEST['action'] != 'MassEditSave' && !$iAmAProcess) { // crmv@138794 crmv@196424
$InventoryUtils = InventoryUtils::getInstance();
//Based on the total Number of rows we will save the product relationship with this entity
$InventoryUtils->saveInventoryProductDetails($this, $module);
}
// Update the currency id and the conversion rate for the module
$update_query = "UPDATE {$this->table_name} SET currency_id=?, conversion_rate=? WHERE {$this->table_index} = ?";
$update_params = array($this->column_fields['currency_id'], $this->column_fields['conversion_rate'], $this->id);
$adb->pquery($update_query, $update_params);
}
// You can add more options here
// ...
}
// crmv@64542e
/**
* Return query to use based on given modulename, fieldname
* Useful to handle specific case handling for Popup
*/
function getQueryByModuleField($module, $fieldname, $srcrecord) {
// $srcrecord could be empty
}
/**
* Invoked when special actions are performed on the module.
* @param String Module name
* @param String Event Type (module.postinstall, module.disabled, module.enabled, module.preuninstall)
*/
function vtlib_handler($modulename, $event_type) {
global $adb,$table_prefix;
if($event_type == 'module.postinstall') {
$moduleInstance = Vtecrm_Module::getInstance($modulename);
if ($moduleInstance->is_mod_light) { //crmv@106857
$moduleInstance->hide(array('hide_module_manager'=>1,'hide_profile'=>1,'hide_report'=>1));
} else {
//crmv@29617
$result = $adb->pquery('SELECT isentitytype FROM '.$table_prefix.'_tab WHERE name = ?',array($modulename));
if ($result && $adb->num_rows($result) > 0 && $adb->query_result($result,0,'isentitytype') == '1') {
$ModCommentsModuleInstance = Vtecrm_Module::getInstance('ModComments');
if ($ModCommentsModuleInstance) {
$ModCommentsFocus = CRMEntity::getInstance('ModComments');
$ModCommentsFocus->addWidgetTo($modulename);
}
// crmv@164120 - removed changelog
// crmv@164122 - removed modnot
$MyNotesModuleInstance = Vtecrm_Module::getInstance('MyNotes');
if ($MyNotesModuleInstance) {
$MyNotesCommonFocus = CRMEntity::getInstance('MyNotes');
$MyNotesCommonFocus->addWidgetTo($modulename);
}
}
//crmv@29617e
//crmv@92272
$ProcessesFocus = CRMEntity::getInstance('Processes');
$ProcessesFocus->enable($modulename);
//crmv@92272e
//crmv@105882 - initialize home for all users
require_once('include/utils/ModuleHomeView.php');
$MHW = ModuleHomeView::install($modulename);
//crmv@105882e
}
} else if($event_type == 'module.disabled') {
// TODO Handle actions when this module is disabled.
} else if($event_type == 'module.enabled') {
// TODO Handle actions when this module is enabled.
} else if($event_type == 'module.preuninstall') {
// TODO Handle actions when this module is about to be deleted.
} else if($event_type == 'module.preupdate') {
// TODO Handle actions before this module is updated.
} else if($event_type == 'module.postupdate') {
// TODO Handle actions after this module is updated.
}
}
/**
* Handle saving related module information.
* NOTE: This function has been added to CRMEntity (base class).
* You can override the behavior by re-defining it here.
*/
/*
function save_related_module($module, $crmid, $with_module, $with_crmid) {
parent::save_related_module($module, $crmid, $with_module, $with_crmid);
//...
}
*/
/**
* Handle deleting related module information.
* NOTE: This function has been added to CRMEntity (base class).
* You can override the behavior by re-defining it here.
*/
//function delete_related_module($module, $crmid, $with_module, $with_crmid) { }
/**
* Handle getting related list information.
* NOTE: This function has been added to CRMEntity (base class).
* You can override the behavior by re-defining it here.
*/
//function get_related_list($id, $cur_tab_id, $rel_tab_id, $actions=false) { }
/**
* Handle getting dependents list information.
* NOTE: This function has been added to CRMEntity (base class).
* You can override the behavior by re-defining it here.
*/
//function get_dependents_list($id, $cur_tab_id, $rel_tab_id, $actions=false) { }
}

View File

@ -0,0 +1,6 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
require_once('include/Ajax/CommonAjax.php');

View File

@ -0,0 +1,64 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
global $current_user, $currentModule;
$focus = CRMEntity::getInstance($currentModule);
setObjectValuesFromRequest($focus);
$mode = $_REQUEST['mode'];
$record=$_REQUEST['record'];
if($mode) $focus->mode = $mode;
if($record)$focus->id = $record;
// crmv@64542
if (isInventoryModule($currentModule)) {
$focus->column_fields['currency_id'] = $_REQUEST['inventory_currency'];
$cur_sym_rate = getCurrencySymbolandCRate($_REQUEST['inventory_currency']);
$focus->column_fields['conversion_rate'] = $cur_sym_rate['rate'];
}
// crmv@64542e
if($_REQUEST['assigntype'] == 'U') {
$focus->column_fields['assigned_user_id'] = $_REQUEST['assigned_user_id'];
} elseif($_REQUEST['assigntype'] == 'T') {
$focus->column_fields['assigned_user_id'] = $_REQUEST['assigned_group_id'];
}
$focus->save($currentModule);
$return_id = $focus->id;
$search = vtlib_purify($_REQUEST['search_url']);
$parenttab = getParentTab();
if($_REQUEST['return_module'] != '') {
$return_module = vtlib_purify($_REQUEST['return_module']);
} else {
$return_module = $currentModule;
}
if($_REQUEST['return_action'] != '') {
$return_action = vtlib_purify($_REQUEST['return_action']);
} else {
$return_action = "DetailView";
}
if($_REQUEST['return_id'] != '') {
$return_id = vtlib_purify($_REQUEST['return_id']);
}
//crmv@54375
if($_REQUEST['return2detail'] == 'yes') {
$return_module = $currentModule;
$return_action = 'DetailView';
$return_id = $focus->id;
}
//crmv@54375e
$url = "index.php?action=$return_action&module=$return_module&record=$return_id&parenttab=$parenttab&start=".vtlib_purify($_REQUEST['pagenumber']).$search;
$from_module = vtlib_purify($_REQUEST['module']);
if (!empty($from_module)) $url .= "&from_module=$from_module";
RequestHandler::outputRedirect($url); // crmv@150748

View File

@ -0,0 +1,16 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
$mod_strings = Array(
'ModuleName' => 'Module Name',
'SINGLE_ModuleName' => 'Module Name',
'LBL_MODULEBLOCK_INFORMATION' => 'ModuleBlock Information',
'LBL_CUSTOM_INFORMATION' => 'Custom Information',
'LBL_DESCRIPTION_INFORMATION' => 'Description Information',
'ModuleFieldLabel' => 'ModuleFieldLabel Text',
);

View File

@ -0,0 +1,16 @@
<?php
/*************************************
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
$mod_strings = Array(
'ModuleName' => 'Nome Modulo',
'SINGLE_ModuleName' => 'Nome Modulo',
'LBL_MODULEBLOCK_INFORMATION' => 'Informazioni Modulo',
'LBL_CUSTOM_INFORMATION' => 'Informazioni Personalizzate',
'LBL_DESCRIPTION_INFORMATION' => 'Informazioni Descrizione',
'ModuleFieldLabel' => 'ModuleFieldLabel Text',
);