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-image-manager.min.js"></script> <!-- crmv@201352 -->
<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">
{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/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}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">
<input type="hidden" id="nlw_templateEditId" value="{$TPL_ID}" />

View File

@ -51,6 +51,15 @@
border-radius: 0;
}
.gjs-rte-action {
width: auto;
min-width: 25px;
}
.gjs-rte-action svg {
width: 20px;
}
.template-vars-input {
background-color: white;
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 = '_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;
//crmv@10488
$REMINDER_EMAIL_ID ='_USER_SUPPORT_EMAIL_';
$REMINDER_NAME = 'VTE Notification System';
$REMINDER_NAME = $enterprise_mode.' Notification System'; // crmv@261010_1
//crmv@10488 e\
/* database configuration

View File

@ -232,6 +232,11 @@ private function isDir($dir) {
if(!in_array($size[2], array(1, 2, 3, 7, 8))) {
$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('.','-'));
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 */
!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}])});
/*! 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),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
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', {
label: 'Ordered List',
attributes: {
@ -207,20 +235,26 @@ VTE.GrapesEditor = VTE.GrapesEditor || {
}
// crmv@202326e
//selezione in automatico del tab Settings al trascinamento di un link
// crmv@261314
editor.on('component:mount', function(model) {
if(model.is('link')){
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');
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.customizeEditor(editor);
me.loadAssets(me.images_uploaded);
},
checkEndpoint: function(){
@ -418,10 +452,25 @@ VTE.GrapesEditor = VTE.GrapesEditor || {
attributes: {
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){

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
if ($loadResult == 'EXPIRED') { // crmv@187476
// generate a token for the change password (1 hour only)
$key = getUserAuthtokenKey('password_recovery',$focus->id,3600);
// crmv@261010_1 generate a token for the change password
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
exit;
}

View File

@ -4,13 +4,17 @@
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
/* crmv@192078 */
// crmv@171581
/* crmv@192078 crmv@171581 crmv@261010_1 */
class RecoverPwd {
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) {
global $default_charset;
@ -20,8 +24,10 @@ class RecoverPwd {
header('Content-Type: text/html; charset=' . $default_charset);
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') {
$body = $this->displayRecoverLandingPage($smarty, $request['key']);
} elseif ($action == 'recover1') {
$body = $this->displayRecover($smarty, $request['key']);
} elseif ($action == 'send') {
$body = $this->displaySend($smarty, $post['user_name']);
@ -55,7 +61,20 @@ class RecoverPwd {
public function displayMainForm($smarty) {
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="__csrf_token" value="'.RequestHandler::getCSRFToken().'">
<table class="table borderless">
@ -90,117 +109,141 @@ class RecoverPwd {
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) {
global $adb, $table_prefix;
global $site_URL, $current_user;
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->id = $current_user->retrieve_user_id($username);
$current_user->retrieve_entity_info($current_user->id, 'Users');
$current_language = $current_user->column_fields['default_language'];
if ($current_user->column_fields['email1'] != '') {
require_once('modules/Emails/mail.php');
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;
$success = false;
$key = getUserAuthtokenKey($this->user_auth_token_type,$current_user->id,$this->user_auth_seconds_to_expire,true);
if ($key !== false) {
$mail_error = false;
$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 .= '<br><br>'.getTranslatedString("LBL_REGARDS",'HelpDesk').',<br>'.getTranslatedString("LBL_TEAM",'HelpDesk');
//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'];
$success = $this->sendMail($current_user->column_fields['email1'], getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT','Users'), $body);
}
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 = '
<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" 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;
}
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) {
global $current_user, $site_URL;
@ -216,18 +259,20 @@ class RecoverPwd {
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->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">
<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="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">
<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;
}
public function displayChangePwd($smarty, $key, $newpwd) {
public function displayChangePwd($smarty, $username, $newpwd) {
global $site_URL, $current_user;
global $adb, $table_prefix;
$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;
}
// removed validateUserAuthtokenKey, there is already the CSRFT check in rpwd.php
$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');
//crmv@28327
@ -316,7 +351,7 @@ class RecoverPwd {
//crmv@35153
} elseif ($current_user->id == 1 && isFreeVersion()) {
$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");
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
@ -348,18 +383,18 @@ class RecoverPwd {
});
</script>
';
emptyUserAuthtokenKey($this->user_auth_token_type,$user_id);
emptyUserAuthtokenKey($this->user_auth_token_type,$current_user->id);
//crmv@35153e
} else {
$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 = '
<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 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>
';
</table>';
}
//crmv@28327e
@ -383,8 +418,9 @@ class RecoverPwd {
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $user_id;
// crmv@206770_3.2
$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="action" value="change_old_pwd_send">
<input type="hidden" name="key" value="'.$key.'">
@ -514,4 +550,87 @@ class RecoverPwd {
if (!$msg) $msg = 'Internal error';
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);
// 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;
}

View File

@ -1,4 +1,5 @@
<?php
global $enterprise_mode;
$mod_strings = array(
'LBL_MODULE_NAME'=>'Users',
'LBL_MODULE_TITLE'=>'Users: Home',
@ -575,16 +576,19 @@ $mod_strings = array(
'LBL_KEEP_ME_LOGGED_IN'=>'Keep me logged in',
'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_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_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_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_SYSTEM2'=>'please click',
'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_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_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.',

View File

@ -3,6 +3,7 @@
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
global $enterprise_mode;
$mod_strings = array (
'LBL_MODULE_NAME' => 'Utenti',
'LBL_MODULE_TITLE' => 'Utenti: Home',
@ -623,16 +624,19 @@ $mod_strings = array (
'LBL_KEEP_ME_LOGGED_IN' => 'Resta collegato',
'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_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_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_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_SYSTEM2' => 'ti preghiamo di cliccare',
'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_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
'LBL_SAVELOGIN_HELP' => 'Assicurati che il server abbia session.gc_maxlifetime = 2592000 nel php.ini per attivare la funzionalità.',
//crmv@28327

View File

@ -6,10 +6,10 @@
$patch_version = '';
$modified_database = '';
$vte_legacy_version = '5.2.1';
$enterprise_current_version = '20.04.1';
$enterprise_current_build = '2210';
$enterprise_current_version = '20.04.2';
$enterprise_current_build = '2214';
$enterprise_base_build = '2103'; // just to know where we started
$enterprise_mode = 'VTENEXTCE';
$enterprise_project = '';
$enterprise_subversion = 'VTENEXTCE200401';
$enterprise_subversion = 'VTENEXTCE200402';
$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',
);