mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 01:10:42 +08:00
Merge next into suite 8
This commit is contained in:
commit
ced5a7deee
121 changed files with 3149 additions and 2014 deletions
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// Swagger needs this, but should remove - CORS
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
|
||||
header('Access-Control-Allow-Methods: POST, PATCH, GET, OPTIONS, PUT, DELETE');
|
||||
header('Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With');
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
|
|
|
@ -76,8 +76,9 @@ class MetaService
|
|||
'default',
|
||||
'len',
|
||||
'precision',
|
||||
'comments',
|
||||
'comment',
|
||||
'required',
|
||||
'vname'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,7 +90,7 @@ class UserPreferencesService
|
|||
$preferences = [];
|
||||
while ($row = $db->fetchByAssoc($result)) {
|
||||
$category = $row['category'];
|
||||
$preferences[$category] = unserialize(base64_decode($row['contents']));
|
||||
$preferences[$category] = unserialize(base64_decode($row['contents']), ['allowed_classes' => false]);
|
||||
}
|
||||
|
||||
$dataResponse = new DataResponse('UserPreference', $params->getUserId());
|
||||
|
|
|
@ -916,7 +916,7 @@ class PackageManager
|
|||
$installed->manifest = base64_encode(serialize($serial_manifest));
|
||||
$installed->save();
|
||||
} else {
|
||||
$serial_manifest = unserialize(base64_decode($installed->manifest));
|
||||
$serial_manifest = unserialize(base64_decode($installed->manifest), ['allowed_classes' => false]);
|
||||
$manifest = $serial_manifest['manifest'];
|
||||
}
|
||||
if (($upgrades_installed==0 || $uh->UninstallAvailable($installeds, $installed))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<img width="180px" height="41px" src="https://suitecrm.com/wp-content/uploads/2017/12/logo.png" align="right" />
|
||||
</a>
|
||||
|
||||
# SuiteCRM 7.14.6
|
||||
# SuiteCRM 7.14.7
|
||||
|
||||
[](https://travis-ci.org/salesagility/SuiteCRM)
|
||||
[](https://codecov.io/gh/salesagility/SuiteCRM/branch/hotfix)
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
{
|
||||
"name": "salesagility/suitecrm",
|
||||
"name": "suitecrm/suitecrm",
|
||||
"description": "SuiteCRM",
|
||||
"homepage": "https://suitecrm.com",
|
||||
"type": "project",
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "SalesAgility Ltd"
|
||||
"name": "SuiteCRM Ltd"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/salesagility/SuiteCRM/issues",
|
||||
"issues": "https://github.com/suitecrm/SuiteCRM/issues",
|
||||
"wiki": "https://docs.suitecrm.com",
|
||||
"forum": "https://community.suitecrm.com",
|
||||
"chat": "https://gitter.im/suitecrm/Lobby",
|
||||
"source": "https://github.com/salesagility/SuiteCRM"
|
||||
"source": "https://github.com/suitecrm/SuiteCRM"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "vendor",
|
||||
|
@ -39,10 +38,11 @@
|
|||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-intl": "*",
|
||||
"consolidation/robo": "^3.0",
|
||||
"elasticsearch/elasticsearch": "^7.13",
|
||||
"ezyang/htmlpurifier": "^4.10",
|
||||
"google/apiclient": "^2.7",
|
||||
"google/apiclient": "^2.14",
|
||||
"google/recaptcha": "^1.1",
|
||||
"gymadarasz/ace": "^1.2",
|
||||
"gymadarasz/imagesloaded": "^4.1",
|
||||
|
@ -60,13 +60,12 @@
|
|||
"slim/slim": "^3.8",
|
||||
"smarty/smarty": "^4",
|
||||
"soundasleep/html2text": "~0.5",
|
||||
"symfony/options-resolver": "^3.4",
|
||||
"symfony/validator": "^3.4",
|
||||
"symfony/options-resolver": "^5.4",
|
||||
"symfony/validator": "^5.4",
|
||||
"symfony/yaml": "^5.2",
|
||||
"tecnickcom/tcpdf": "^6.4",
|
||||
"tedivm/jshrink": "^1.3",
|
||||
"tinymce/tinymce": "^5.10",
|
||||
"vlucas/phpdotenv": "^3.5",
|
||||
"voku/anti-xss": "^4.0",
|
||||
"wikimedia/composer-merge-plugin": "^2.0",
|
||||
"zbateson/mail-mime-parser": "^2.2",
|
||||
|
@ -74,8 +73,7 @@
|
|||
"zf1/zend-loader": "^1.12",
|
||||
"zf1/zend-oauth": "^1.12",
|
||||
"zf1/zend-registry": "^1.12",
|
||||
"zf1/zend-search-lucene": "^1.12",
|
||||
"ext-intl": "*"
|
||||
"zf1/zend-search-lucene": "^1.12"
|
||||
},
|
||||
"require-dev": {
|
||||
"browserstack/browserstack-local": "^1.1",
|
||||
|
@ -95,7 +93,8 @@
|
|||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rector/rector": "^0.16.0",
|
||||
"scssphp/scssphp": "^1.5"
|
||||
"scssphp/scssphp": "^1.5",
|
||||
"vlucas/phpdotenv": "^5.5"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
|
|
2425
public/legacy/composer.lock
generated
2425
public/legacy/composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -57,7 +57,7 @@ if (!is_windows()) {
|
|||
$cronUser = getRunningUser();
|
||||
|
||||
if ($cronUser == '') {
|
||||
$GLOBALS['log']->warning('cron.php: can\'t determine running user. No cron user checks will occur.');
|
||||
$GLOBALS['log']->warn('cron.php: can\'t determine running user. No cron user checks will occur.');
|
||||
} elseif (array_key_exists('cron', $sugar_config) && array_key_exists('allowed_cron_users', $sugar_config['cron'])) {
|
||||
if (!in_array($cronUser, $sugar_config['cron']['allowed_cron_users'])) {
|
||||
$GLOBALS['log']->fatal("cron.php: running as $cronUser is not allowed in allowed_cron_users ".
|
||||
|
@ -70,7 +70,7 @@ if (!is_windows()) {
|
|||
sugar_die('cron.php running with user that is not in allowed_cron_users in config.php');
|
||||
}
|
||||
} else {
|
||||
$GLOBALS['log']->warning('cron.php: missing expected allowed_cron_users entry in config.php. ' .
|
||||
$GLOBALS['log']->warn('cron.php: missing expected allowed_cron_users entry in config.php. ' .
|
||||
'No cron user checks will occur.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1012,7 +1012,11 @@ class SugarController
|
|||
require_once($this->entry_point_registry[$entryPoint]['file']);
|
||||
$this->_processed = true;
|
||||
$this->view = '';
|
||||
} else {
|
||||
$this->no_action();
|
||||
}
|
||||
} elseif (isset($_REQUEST['entryPoint'])) {
|
||||
$this->no_action();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ $action_view_map['modulelistmenu']= 'modulelistmenu';
|
|||
$action_view_map['favorites']= 'favorites';
|
||||
$action_view_map['ajaxui']= 'ajaxui';
|
||||
$action_view_map['noaccess']= 'noaccess';
|
||||
$action_view_map['errors']= 'errors';
|
||||
|
||||
// SugarPDF
|
||||
$action_view_map['sugarpdf']= 'sugarpdf';
|
||||
|
|
|
@ -572,7 +572,7 @@ class SugarApplication
|
|||
if ($dieIfInvalid) {
|
||||
header("Cache-Control: no-cache, must-revalidate");
|
||||
$ss = new Sugar_Smarty;
|
||||
$ss->assign('host', $http_host[0]);
|
||||
$ss->assign('host', securexss($http_host[0]));
|
||||
$ss->assign('action', $this->controller->action);
|
||||
$ss->assign('whiteListString', $whiteListString);
|
||||
$ss->display('include/MVC/View/tpls/xsrf.tpl');
|
||||
|
@ -591,7 +591,7 @@ class SugarApplication
|
|||
$whiteListString = "'" . implode("', '", $whiteListActions) . "'";
|
||||
|
||||
$ss = new Sugar_Smarty;
|
||||
$ss->assign('host', $http_ref['host']);
|
||||
$ss->assign('host', securexss($http_ref['host']));
|
||||
$ss->assign('action', $this->controller->action);
|
||||
$ss->assign('whiteListString', $whiteListString);
|
||||
$ss->display('include/MVC/View/tpls/xsrf.tpl');
|
||||
|
|
39
public/legacy/include/MVC/View/views/view.errors.php
Normal file
39
public/legacy/include/MVC/View/views/view.errors.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SUITECRM, SUITECRM DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
|
||||
class ViewErrors extends SugarView
|
||||
{
|
||||
public $type = 'errors';
|
||||
|
||||
/**
|
||||
* @see SugarView::display()
|
||||
*/
|
||||
public function display()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -89,6 +89,8 @@ class OutboundEmail
|
|||
public $mail_smtpssl; // bool
|
||||
public $mail_smtpdisplay; // calculated value, not in DB
|
||||
public $new_with_id = false;
|
||||
public $auth_type; // no_auth, oauth2, external_oauth
|
||||
public $external_oauth_connection_id; // no_auth, oauth2, external_oauth
|
||||
|
||||
/**
|
||||
* Sole constructor
|
||||
|
@ -389,6 +391,19 @@ class OutboundEmail
|
|||
return $allowAccess;
|
||||
}
|
||||
|
||||
public function getSystemEmail(): ?object
|
||||
{
|
||||
$q = "SELECT id FROM outbound_email WHERE type = 'system' AND deleted = 0";
|
||||
$r = $this->db->query($q);
|
||||
$a = $this->db->fetchByAssoc($r);
|
||||
|
||||
if (!empty($a)) {
|
||||
return $this->retrieve($a['id']) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the system's Outbound options
|
||||
*/
|
||||
|
|
|
@ -187,7 +187,7 @@ class SearchForm
|
|||
$this->th->ss->assign('action', $this->action);
|
||||
$this->th->ss->assign('displayView', $this->displayView);
|
||||
$this->th->ss->assign('viewTab', $this->getViewTab());
|
||||
$this->th->ss->assign('user_options', get_user_array(false)); // Fix https://github.com/salesagility/SuiteCRM/issues/10264
|
||||
$this->th->ss->assign('user_options', get_user_array(false));
|
||||
|
||||
require_once('modules/MySettings/StoreQuery.php');
|
||||
$storeQuery = new StoreQuery();
|
||||
|
|
|
@ -868,8 +868,6 @@ class SubPanelDefinitions
|
|||
*/
|
||||
public function get_hidden_subpanels()
|
||||
{
|
||||
global $moduleList;
|
||||
|
||||
//create variable as static to minimize queries
|
||||
static $hidden_subpanels = null;
|
||||
|
||||
|
@ -884,25 +882,9 @@ class SubPanelDefinitions
|
|||
$hidden_subpanels = $administration->settings['MySettings_hide_subpanels'];
|
||||
$hidden_subpanels = trim($hidden_subpanels);
|
||||
|
||||
//make sure serialized string is not empty
|
||||
if (!empty($hidden_subpanels)) {
|
||||
//decode and unserialize to retrieve the array
|
||||
$hidden_subpanels = base64_decode($hidden_subpanels);
|
||||
$hidden_subpanels = unserialize($hidden_subpanels);
|
||||
|
||||
//Ensure modules saved in the preferences exist.
|
||||
//get user preference
|
||||
//unserialize and add to array if not empty
|
||||
$pref_hidden = array();
|
||||
foreach ($pref_hidden as $id => $pref_hidden_panel) {
|
||||
$hidden_subpanels[] = $pref_hidden_panel;
|
||||
}
|
||||
} else {
|
||||
//no settings found, return empty
|
||||
return $hidden_subpanels;
|
||||
$hidden_subpanels = unserialize(base64_decode($hidden_subpanels), ['allowed_classes' => false]);
|
||||
}
|
||||
} else { //no settings found, return empty
|
||||
return $hidden_subpanels;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ class SugarCacheFile extends SugarCacheAbstract
|
|||
) {
|
||||
// load up the external cache file
|
||||
if (is_file($cachedfile = sugar_cached($this->_cacheFileName))) {
|
||||
$this->localCache = unserialize(file_get_contents($cachedfile));
|
||||
$this->localCache = unserialize(file_get_contents($cachedfile), ['allowed_classes' => false]);
|
||||
}
|
||||
|
||||
if (isset($this->_localStore[$key])) {
|
||||
|
|
|
@ -141,7 +141,7 @@ class SugarCacheRedis extends SugarCacheAbstract
|
|||
}
|
||||
|
||||
return is_string($returnValue) ?
|
||||
unserialize($returnValue) :
|
||||
unserialize($returnValue, ['allowed_classes' => false]) :
|
||||
$returnValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class SugarCacheZend extends SugarCacheAbstract
|
|||
return null;
|
||||
}
|
||||
return is_string($raw_cache_value) ?
|
||||
unserialize($raw_cache_value) :
|
||||
unserialize($raw_cache_value, ['allowed_classes' => false]) :
|
||||
$raw_cache_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,5 +40,4 @@
|
|||
|
||||
*}
|
||||
{{capture name=display_size assign=size}}{{$displayParams.size|default:6}}{{/capture}}
|
||||
|
||||
{html_options name='{{$vardef.name}}[]' options=$user_options size="{{$size}}" style="width: 150px" {{if $size > 1}}multiple="1"{{/if}} selected={{sugarvar key='value' string=true}}}
|
||||
|
|
|
@ -132,23 +132,28 @@ class SugarPHPMailer extends PHPMailer
|
|||
$this->Mailer = 'smtp';
|
||||
$this->Host = $oe->mail_smtpserver;
|
||||
$this->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$this->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$this->SMTPSecure = 'tls';
|
||||
} // if
|
||||
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $oe->mail_smtpuser;
|
||||
$this->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$this->setSecureProtocol($oe->mail_smtpssl);
|
||||
$this->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$this->Mailer = 'sendmail';
|
||||
}
|
||||
}
|
||||
|
||||
public function setSystemFromAddress(): void
|
||||
{
|
||||
require_once 'include/OutboundEmail/OutboundEmail.php';
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemMailerSettings();
|
||||
|
||||
$this->From = $oe->smtp_from_addr ?? '';
|
||||
$this->FromName = $oe->smtp_from_name ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefills mailer for system
|
||||
*/
|
||||
|
@ -166,22 +171,81 @@ class SugarPHPMailer extends PHPMailer
|
|||
$this->Mailer = 'smtp';
|
||||
$this->Host = $oe->mail_smtpserver;
|
||||
$this->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$this->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$this->SMTPSecure = 'tls';
|
||||
} // if
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $oe->mail_smtpuser;
|
||||
$this->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$this->setSecureProtocol($oe->mail_smtpssl);
|
||||
$this->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$this->Mailer = 'sendmail';
|
||||
}
|
||||
}
|
||||
|
||||
public function initSMTPAuth(
|
||||
string $authType,
|
||||
string $externalOAuthConnectionId,
|
||||
string $smtpUser,
|
||||
string $smtpPass,
|
||||
): void {
|
||||
|
||||
if ($authType === 'oauth') {
|
||||
$this->initOAuth(
|
||||
$authType,
|
||||
$externalOAuthConnectionId,
|
||||
$smtpUser,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($authType === 'basic') {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $smtpUser;
|
||||
$this->Password = $smtpPass;
|
||||
}
|
||||
}
|
||||
|
||||
public function initOAuth(
|
||||
string $authType,
|
||||
string $externalOAuthConnectionId,
|
||||
string $smtpUser
|
||||
): void
|
||||
{
|
||||
if ($authType !== 'oauth') {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->isSMTP();
|
||||
$this->SMTPAuth = true;
|
||||
|
||||
$this->AuthType = 'XOAUTH2';
|
||||
|
||||
$oAuthConnectionId = $externalOAuthConnectionId;
|
||||
|
||||
require_once 'modules/ExternalOAuthConnection/services/OAuthAuthorizationService.php';
|
||||
$oAuth = new OAuthAuthorizationService();
|
||||
|
||||
$oAuth->refreshExpiredOAuthToken($oAuthConnectionId);
|
||||
|
||||
/** @var ExternalOAuthConnection $oauthConnection */
|
||||
$oauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $oAuthConnectionId);
|
||||
$providerId = $oauthConnection->external_oauth_provider_id;
|
||||
|
||||
$oauthConfig = new \PHPMailer\PHPMailer\OAuth([
|
||||
'provider' => $oAuth?->getProvider($providerId)?->getProvider($oauthConnection->client_id, $oauthConnection->client_secret),
|
||||
'clientId' => $oauthConnection->client_id,
|
||||
'refreshToken' => $oauthConnection->refresh_token,
|
||||
'clientSecret' => $oauthConnection->client_secret,
|
||||
'userName' => $smtpUser
|
||||
]);
|
||||
|
||||
$this->setOAuth(
|
||||
$oauthConfig
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* handles Charset translation for all visual parts of the email.
|
||||
*/
|
||||
|
@ -469,7 +533,7 @@ eoq;
|
|||
$ret = parent::send();
|
||||
$this->exceptions = $saveExceptionsState;
|
||||
} catch (Exception $e) {
|
||||
$phpMailerExceptionMsg=$e->errorMessage(); //Pretty error messages from PHPMailer
|
||||
$phpMailerExceptionMsg =$e->getMessage(); //Pretty error messages from PHPMailer
|
||||
if ($phpMailerExceptionMsg) {
|
||||
$GLOBALS['log']->error("send: PHPMailer Exception: { $phpMailerExceptionMsg }");
|
||||
}
|
||||
|
@ -490,4 +554,18 @@ eoq;
|
|||
*/
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function setSecureProtocol($smtpSsl): void
|
||||
{
|
||||
$this->protocol = ($smtpSsl) ? "ssl://" : "tcp://";
|
||||
if ($smtpSsl == 1) {
|
||||
$this->protocol = "ssl://";
|
||||
$this->SMTPSecure = 'ssl';
|
||||
}
|
||||
if ($smtpSsl == 2) {
|
||||
$this->protocol = "ssl://";
|
||||
$this->SMTPSecure = 'tls';
|
||||
}
|
||||
}
|
||||
|
||||
} // end class definition
|
||||
|
|
|
@ -341,7 +341,7 @@ class SugarTheme
|
|||
}
|
||||
if (!inDeveloperMode()) {
|
||||
if (is_file($cachedfile = sugar_cached($this->getFilePath().'/pathCache.php'))) {
|
||||
$caches = unserialize(file_get_contents($cachedfile));
|
||||
$caches = unserialize(file_get_contents($cachedfile), ['allowed_classes' => false]);
|
||||
if (isset($caches['jsCache'])) {
|
||||
$this->_jsCache = $caches['jsCache'];
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ class SugarTheme
|
|||
}
|
||||
$cachedfile = sugar_cached($this->getFilePath().'/spriteCache.php');
|
||||
if (!empty($GLOBALS['sugar_config']['use_sprites']) && is_file($cachedfile)) {
|
||||
$this->_spriteCache = unserialize(sugar_file_get_contents($cachedfile));
|
||||
$this->_spriteCache = unserialize(sugar_file_get_contents($cachedfile), ['allowed_classes' => false]);
|
||||
}
|
||||
}
|
||||
$this->_initialCacheSize = array(
|
||||
|
|
|
@ -75,12 +75,25 @@ class Sugar_Smarty extends Smarty
|
|||
mkdir_recursive(SUGAR_SMARTY_DIR . 'cache', true);
|
||||
}
|
||||
|
||||
$this->template_dir = '.';
|
||||
$this->compile_dir = SUGAR_SMARTY_DIR . 'templates_c';
|
||||
$this->config_dir = SUGAR_SMARTY_DIR . 'configs';
|
||||
$this->cache_dir = SUGAR_SMARTY_DIR . 'cache';
|
||||
//$this->request_use_auto_globals = true; // to disable Smarty from using long arrays
|
||||
$this->setTemplateDir('.');
|
||||
$this->setCompileDir(SUGAR_SMARTY_DIR . 'templates_c');
|
||||
$this->setCacheDir(SUGAR_SMARTY_DIR . 'cache');
|
||||
$this->setConfigDir(SUGAR_SMARTY_DIR . 'configs');
|
||||
|
||||
$this->registerPHPFunctions([
|
||||
'count',
|
||||
'intval',
|
||||
'is_string',
|
||||
'key',
|
||||
'preg_match',
|
||||
'substr',
|
||||
'strpos',
|
||||
'strstr',
|
||||
'strtoupper',
|
||||
'strval',
|
||||
'url2html'
|
||||
]);
|
||||
|
||||
//TODO fix literals
|
||||
$this->auto_literal = false;
|
||||
|
||||
|
@ -94,7 +107,16 @@ class Sugar_Smarty extends Smarty
|
|||
$this->assign("VERSION_MARK", getVersionedPath(''));
|
||||
}
|
||||
|
||||
|
||||
public function registerPHPFunctions(array $functions): void
|
||||
{
|
||||
foreach ($functions as $function) {
|
||||
try {
|
||||
$this->registerPlugin(Smarty::PLUGIN_MODIFIER, $function, $function);
|
||||
} catch (SmartyException $e) {
|
||||
$GLOBALS['log']->fatal('Smarty: Failed to register PHP function' . $function . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default _unlink method call to fix Bug 53010
|
||||
|
|
|
@ -125,10 +125,11 @@ class SugarWidgetSubPanelDetailViewLink extends SugarWidgetField
|
|||
$detailView = $layout_def['DetailView'] ?? '';
|
||||
$ownerId = $layout_def['owner_id'] ?? '';
|
||||
$ownerModule = $layout_def['owner_module'] ?? '';
|
||||
$groupAccessView = SecurityGroup::groupHasAccess($module,$record,'view');
|
||||
if (!empty($record) &&
|
||||
($detailView && !$layout_def['owner_module']
|
||||
|| $detailView && !ACLController::moduleSupportsACL($layout_def['owner_module'])
|
||||
|| ACLController::checkAccess($ownerModule, 'view', $ownerId == $current_user->id))) {
|
||||
|| $detailView && !ACLController::moduleSupportsACL($layout_def['owner_module'])
|
||||
|| ACLController::checkAccess($ownerModule, 'view', $ownerId == $current_user->id, 'module', $groupAccessView))) {
|
||||
$link = ajaxLink("index.php?module=$module&action=$action&record={$record}{$parent}");
|
||||
if ($module == 'EAPM') {
|
||||
$link = "index.php?module=$module&action=$action&record={$record}{$parent}";
|
||||
|
|
|
@ -115,8 +115,7 @@ class SugarWidgetSubPanelRemoveButton extends SugarWidgetField
|
|||
$hideremove = true;
|
||||
}
|
||||
|
||||
//based on listview since that lets you select records
|
||||
if ($layout_def['ListView'] && !$hideremove) {
|
||||
if ($layout_def['EditView'] && !$hideremove) {
|
||||
$retStr = "<a href=\"javascript:sub_p_rem('$subpanel', '$linked_field'"
|
||||
. ", '$record', $refresh_page);\""
|
||||
. ' class="listViewTdToolsS1"'
|
||||
|
|
|
@ -308,6 +308,12 @@ $app_list_strings = array(
|
|||
'Dr.' => 'Dr.',
|
||||
'Prof.' => 'Prof.',
|
||||
),
|
||||
|
||||
'redirect_uri_type_dom' => [
|
||||
'pretty_url' => 'Pretty URL (/ep/)',
|
||||
'query_string' => 'Query String (index.php?entryPoint=)'
|
||||
],
|
||||
|
||||
//time is in seconds; the greater the time the longer it takes;
|
||||
'reminder_max_time' => 90000,
|
||||
'reminder_time_options' => array(
|
||||
|
@ -750,6 +756,12 @@ $app_list_strings = array(
|
|||
'oauth' => 'OAuth',
|
||||
],
|
||||
|
||||
'dom_outbound_email_auth_types' => [
|
||||
'no_auth' => 'No Auth',
|
||||
'basic' => 'Basic Auth',
|
||||
'oauth' => 'OAuth',
|
||||
],
|
||||
|
||||
'dom_external_oauth_connection_types' => [
|
||||
'personal' => 'Personal',
|
||||
'group' => 'Group',
|
||||
|
@ -1406,6 +1418,7 @@ $app_strings = array(
|
|||
'LBL_EMAIL_SETTINGS_CHECK_INTERVAL' => 'Check for New Mail',
|
||||
'LBL_EMAIL_SETTINGS_FROM_ADDR' => 'From Address',
|
||||
'LBL_EMAIL_SETTINGS_FROM_TO_EMAIL_ADDR' => 'Email Address For Test Notification:',
|
||||
'LBL_EMAIL_SETTINGS_FROM_ADDR_NOT_SET' => 'From address and/or From name not set',
|
||||
'LBL_EMAIL_SETTINGS_FROM_NAME' => 'From Name',
|
||||
'LBL_EMAIL_SETTINGS_REPLY_TO_ADDR' => 'Reply to Address',
|
||||
'LBL_EMAIL_SETTINGS_FULL_SYNC' => 'Synchronize All Mail Accounts',
|
||||
|
@ -4020,6 +4033,8 @@ $app_strings['LBL_VALUE_SET_PLACEHOLDER'] = 'Value set. Enter new value to overr
|
|||
$app_strings['ERR_IMAP_OAUTH_CONNECTION_ERROR'] = 'Not able to connect using OAuth login with Inbound Email server. For connection: ';
|
||||
$app_strings['WARN_OAUTH_TOKEN_SESSION_EXPIRED'] = 'Your IMAP OAuth session has expired, please login again in the connection: ';
|
||||
|
||||
$app_strings['ERR_OAUTH_CONNECTION_ERROR'] = 'Not able to connect using OAuth login. For connection: ';
|
||||
|
||||
$app_strings['LBL_KEY'] = 'Key';
|
||||
$app_strings['LBL_VALUE'] = 'Value';
|
||||
$app_strings['LBL_OPTIONAL'] = 'Optional';
|
||||
|
|
|
@ -154,7 +154,7 @@ class nusoap_wsdlcache
|
|||
$this->debug("$wsdl ($filename) not in cache (2)");
|
||||
}
|
||||
$this->releaseMutex($filename);
|
||||
return (!is_null($s)) ? unserialize($s) : null;
|
||||
return (!is_null($s)) ? unserialize($s, ['allowed_classes' => false]) : null;
|
||||
}
|
||||
$this->debug("Unable to obtain mutex for $filename in get");
|
||||
|
||||
|
|
|
@ -2423,7 +2423,7 @@ function clean_xss($str, $cleanImg = true)
|
|||
$sugar_config['email_xss'] = getDefaultXssTags();
|
||||
}
|
||||
|
||||
$xsstags = unserialize(base64_decode($sugar_config['email_xss']));
|
||||
$xsstags = unserialize(base64_decode($sugar_config['email_xss']), ['allowed_classes' => false]);
|
||||
|
||||
// cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.)
|
||||
$jsEvents = 'onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|';
|
||||
|
@ -6005,7 +6005,7 @@ function sugar_unserialize($value)
|
|||
return false;
|
||||
}
|
||||
|
||||
return unserialize($value);
|
||||
return unserialize($value, ['allowed_classes' => false]);
|
||||
}
|
||||
|
||||
define('DEFAULT_UTIL_SUITE_ENCODING', 'UTF-8');
|
||||
|
|
|
@ -589,343 +589,6 @@ EOQ;
|
|||
|
||||
//--End of scenarios
|
||||
|
||||
//---------------
|
||||
// SMTP Settings
|
||||
//-------------------->
|
||||
|
||||
// smtp
|
||||
// TODO-t: test it for all types
|
||||
$MAIL_SSL_OPTIONS_GMAIL = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], '2');
|
||||
//$MAIL_SSL_OPTIONS_YAHOO = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], '1');
|
||||
$MAIL_SSL_OPTIONS_EXCHG = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], 'none');
|
||||
$MAIL_SSL_OPTIONS_OTHER = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], 'none');
|
||||
|
||||
// set default notify_allow_default_outbound checkbox value
|
||||
$notify_allow_default_outbound_checked = empty($_SESSION['notify_allow_default_outbound']) ? '' : ' checked="checked" ';
|
||||
|
||||
// set default smtp toggle buttons selected value
|
||||
if (empty($_SESSION['smtp_tab_selected'])) {
|
||||
$_SESSION['smtp_tab_selected'] = 'smtp_tab_other';
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['smtp_from_name']) || !$_SESSION['smtp_from_name']) {
|
||||
$_SESSION['smtp_from_name'] = 'SuiteCRM';
|
||||
}
|
||||
if (!isset($_SESSION['smtp_from_addr']) || !$_SESSION['smtp_from_addr']) {
|
||||
$_SESSION['smtp_from_addr'] = 'do_not_reply@example.com';
|
||||
}
|
||||
|
||||
$out .= <<<EOQ
|
||||
<div class="floatbox full" id="fb2">
|
||||
<!-- smtp settings -->
|
||||
<h3 onclick="$(this).next().toggle();" class="toggler">» {$mod_strings['LBL_MAIL_SMTP_SETTINGS']}</h3>
|
||||
<div style="display: none;">
|
||||
|
||||
<br>
|
||||
<!--
|
||||
<p>{$mod_strings['LBL_WIZARD_SMTP_DESC']}</p>
|
||||
-->
|
||||
|
||||
<!-- smtp types toggler buttons -->
|
||||
|
||||
<p style="display: inline;">
|
||||
|
||||
<div>
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_FROM_NAME']}</label>
|
||||
<input type="text" name="smtp_from_name" value="{$_SESSION['smtp_from_name']}">
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_FROM_ADDR']}</label>
|
||||
<input type="email" name="smtp_from_addr" value="{$_SESSION['smtp_from_addr']}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
|
||||
{$mod_strings['LBL_CHOOSE_EMAIL_PROVIDER']} </p><div class="tooltip-toggle"> <em>i</em> <div class="tooltip">{$mod_strings['LBL_WIZARD_SMTP_DESC']}</div></div>
|
||||
<div class="clear"></div>
|
||||
<div>
|
||||
<input type="button" class="smtp_tab_toggler" id="smtp_tab_gmail_toggler" for="smtp_tab_gmail" value="{$mod_strings['LBL_SMTPTYPE_GMAIL']}" />
|
||||
<input type="button" class="smtp_tab_toggler" id="smtp_tab_yahoo_toggler" for="smtp_tab_yahoo" value="{$mod_strings['LBL_SMTPTYPE_YAHOO']}" />
|
||||
<input type="button" class="smtp_tab_toggler" id="smtp_tab_exchange_toggler" for="smtp_tab_exchange" value="{$mod_strings['LBL_SMTPTYPE_EXCHANGE']}" />
|
||||
<input type="button" class="smtp_tab_toggler selected" id="smtp_tab_other_toggler" for="smtp_tab_other" value="{$mod_strings['LBL_SMTPTYPE_OTHER']}" />
|
||||
<input type="hidden" name="smtp_tab_selected" value="{$_SESSION['smtp_tab_selected']}">
|
||||
</div>
|
||||
<!-- smtp / gmail tab -->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_gmail">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPSERVER']}</label>
|
||||
<input type="text" name="smtp_tab_gmail[mail_smtpserver]" size="25" maxlength="255" value="smtp.gmail.com">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPPORT']}</label>
|
||||
<input type="text" name="smtp_tab_gmail[mail_smtpport]" size="5" maxlength="5" value="587">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPAUTH_REQ']}</label>
|
||||
<input type="checkbox" name="smtp_tab_gmail[mail_smtpauth_req]" id="smtp_tab_gmail__mail_smtpauth_req" value="1" checked="checked" onclick="toggleSMTPAuthSettings(this, 'toggleArea_1');">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EMAIL_SMTP_SSL_OR_TLS']}</label>
|
||||
<select name="smtp_tab_gmail[mail_smtpssl]">
|
||||
{$MAIL_SSL_OPTIONS_GMAIL}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
|
||||
<div class="toggleArea" id="toggleArea_1">
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_GMAIL_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_gmail[mail_smtpuser]" id="smtp_tab_gmail__mail_smtpuser" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_GMAIL_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_gmail[mail_smtppass]" id="smtp_tab_gmail__mail_smtppass" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input name="smtp_tab_gmail[notify_allow_default_outbound]" id="smtp_tab_gmail__notify_allow_default_outbound" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!-- smtp / yahoo! mail tab -->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_yahoo">
|
||||
|
||||
<input type="hidden" name="smtp_tab_yahoo[mail_smtpserver]" size="25" maxlength="255" value="smtp.mail.yahoo.com">
|
||||
<input type="text" name="smtp_tab_yahoo[mail_smtpport]" size="5" maxlength="5" value="465">
|
||||
<input type="hidden" name="smtp_tab_yahoo[mail_smtpssl]" value="1">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_YAHOOMAIL_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_yahoo[mail_smtpuser]" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_YAHOOMAIL_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_yahoo[mail_smtppass]" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input name="smtp_tab_yahoo[notify_allow_default_outbound]" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!-- smtp / ms-exchange tab -->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_exchange">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPSERVER']}</label>
|
||||
<input type="text" name="smtp_tab_exchange[mail_smtpserver]" size="25" maxlength="255" value="">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPPORT']}</label>
|
||||
<input type="text" name="smtp_tab_exchange[mail_smtpport]" size="5" maxlength="5" value="25">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPAUTH_REQ']}</label>
|
||||
<input type="checkbox" name="smtp_tab_exchange[mail_smtpauth_req]" id="smtp_tab_exchange__mail_smtpauth_req" value="1" checked="checked" onclick="toggleSMTPAuthSettings(this, 'toggleArea_2');">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EMAIL_SMTP_SSL_OR_TLS']}</label>
|
||||
<select name="smtp_tab_exchange[mail_smtpssl]" tabindex="501">
|
||||
{$MAIL_SSL_OPTIONS_EXCHG}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="toggleArea" id="toggleArea_2">
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_exchange[mail_smtpuser]" id="smtp_tab_exchange__mail_smtpuser" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_exchange[mail_smtppass]" id="smtp_tab_exchange__mail_smtppass" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input name="smtp_tab_exchange[notify_allow_default_outbound]" id="smtp_tab_exchange__notify_allow_default_outbound" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!-- smtp / other tab-->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_other">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPSERVER']}</label>
|
||||
<input type="text" name="smtp_tab_other[mail_smtpserver]" size="25" maxlength="255" value="">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPPORT']}</label>
|
||||
<input type="text" name="smtp_tab_other[mail_smtpport]" size="5" maxlength="5" value="25">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPAUTH_REQ']}</label>
|
||||
<input type="hidden" name="smtp_tab_other[mail_smtpauth_req]" value="0">
|
||||
<input type="checkbox" id="mail_smtpauth_req_chk" name="smtp_tab_other[mail_smtpauth_req]" value="1" checked="checked" onclick="toggleSMTPAuthSettings(this, 'toggleArea_3');">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EMAIL_SMTP_SSL_OR_TLS']}</label>
|
||||
<select name="smtp_tab_other[mail_smtpssl]" tabindex="501">
|
||||
{$MAIL_SSL_OPTIONS_OTHER}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="toggleArea" id="toggleArea_3">
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_other[mail_smtpuser]" id="smtp_tab_other__mail_smtpuser" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_other[mail_smtppass]" id="smtp_tab_other__mail_smtppass" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input type="hidden" name="smtp_tab_other[notify_allow_default_outbound]" value="0">
|
||||
<input id="notify_allow_default_outbound_chk" name="smtp_tab_other[notify_allow_default_outbound]" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
<!-- </div> -->
|
||||
|
||||
<!-- smtp default values & tabs toggler js & tooltip help -->
|
||||
|
||||
<script>
|
||||
|
||||
var toggleSMTPAuthFields = {
|
||||
toggleArea_1 : {
|
||||
user: 'smtp_tab_gmail__mail_smtpuser',
|
||||
pass: 'smtp_tab_gmail__mail_smtppass',
|
||||
allow: 'smtp_tab_gmail__notify_allow_default_outbound'
|
||||
},
|
||||
toggleArea_2 : {
|
||||
user: 'smtp_tab_exchange__mail_smtpuser',
|
||||
pass: 'smtp_tab_exchange__mail_smtppass',
|
||||
allow: 'smtp_tab_exchange__notify_allow_default_outbound'
|
||||
},
|
||||
toggleArea_3 : {
|
||||
user: 'smtp_tab_other__mail_smtpuser',
|
||||
pass: 'smtp_tab_other__mail_smtppass',
|
||||
allow: 'notify_allow_default_outbound_chk'
|
||||
}
|
||||
};
|
||||
|
||||
var toggleSMTPAuthSettings = function(chkbox, elemID) {
|
||||
if($(chkbox).prop('checked')) {
|
||||
$('#' + elemID).show();
|
||||
}
|
||||
else {
|
||||
$('#' + toggleSMTPAuthFields[elemID].user).val('');
|
||||
$('#' + toggleSMTPAuthFields[elemID].pass).val('');
|
||||
$('#' + toggleSMTPAuthFields[elemID].allow).prop('checked', false);
|
||||
$('#' + elemID).hide();
|
||||
}
|
||||
};
|
||||
|
||||
$(function(){
|
||||
|
||||
$('.smtp_tab_toggler').click(function(){
|
||||
$('.smtp_tab_toggler.selected').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
$('.smtp_tab').hide();
|
||||
$('#'+$(this).attr('for')).show();
|
||||
$('input[name="smtp_tab_selected"]').val($(this).attr('for'));
|
||||
});
|
||||
|
||||
// save last selected tab and set as default when form (re)load
|
||||
$('#{$_SESSION['smtp_tab_selected']}_toggler').click();
|
||||
|
||||
$('select[name="smtp_tab_gmail[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
$('select[name="smtp_tab_yahoo[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
$('select[name="smtp_tab_exchange[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
$('select[name="smtp_tab_other[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
toggleSMTPAuthSettings(document.getElementById('smtp_tab_gmail__mail_smtpauth_req'), 'toggleArea_1');
|
||||
toggleSMTPAuthSettings(document.getElementById('smtp_tab_exchange__mail_smtpauth_req'), 'toggleArea_2');
|
||||
toggleSMTPAuthSettings(document.getElementById('mail_smtpauth_req_chk'), 'toggleArea_3');
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
</div> <!-- toggle hidden box end -->
|
||||
EOQ;
|
||||
|
||||
|
||||
// db setup (dbConfig_a.php)
|
||||
$out2 =<<<EOQ2
|
||||
<input type='hidden' name='setup_db_drop_tables' id='setup_db_drop_tables' value=''>
|
||||
|
@ -956,8 +619,6 @@ EOQ2;
|
|||
$out .= <<<EOQ
|
||||
|
||||
<!-- Branding -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="floatbox full" id="fb3">
|
||||
<h3 onclick="$(this).next().toggle();" class="toggler">» {$mod_strings['LBL_WIZARD_SYSTEM_TITLE']}</h3>
|
||||
|
||||
|
|
|
@ -1121,6 +1121,8 @@ EOQ;
|
|||
RewriteBase {$basePath}
|
||||
RewriteRule ^cache/jsLanguage/(.._..).js$ index.php?entryPoint=jslang&modulename=app_strings&lang=$1 [L,QSA]
|
||||
RewriteRule ^cache/jsLanguage/(\w*)/(.._..).js$ index.php?entryPoint=jslang&modulename=$1&lang=$2 [L,QSA]
|
||||
|
||||
RewriteRule ^ep/(.*?)$ index.php?entryPoint=$1 [L,QSA]
|
||||
|
||||
# --------- DEPRECATED --------
|
||||
RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
|
|
@ -143,6 +143,7 @@ class SearchResults
|
|||
|
||||
$obj->load_relationships();
|
||||
$fieldDefs = $obj->getFieldDefinitions();
|
||||
$obj = $this->formatForDisplay($obj, $fieldDefs);
|
||||
$parsed[$module][] = $this->updateFieldDefLinks($obj, $fieldDefs);
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +151,68 @@ class SearchResults
|
|||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format data so it can be correctly displayed on search results
|
||||
*
|
||||
* @param SugarBean $obj
|
||||
* @param array $fieldDefs
|
||||
* @return SugarBean
|
||||
*/
|
||||
protected function formatForDisplay(SugarBean $obj, array $fieldDefs): SugarBean
|
||||
{
|
||||
global $app_list_strings, $locale;
|
||||
|
||||
foreach ($fieldDefs as $fieldDef) {
|
||||
$value = $obj->{$fieldDef['name']};
|
||||
if (isset($value)) {
|
||||
switch ($fieldDef['type']){
|
||||
case 'enum':
|
||||
case 'dynamicenum':
|
||||
|
||||
if (isset($app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']][$value]) &&
|
||||
isset($obj->field_name_map[$fieldDef['name']]['options'])
|
||||
) {
|
||||
$obj->{$fieldDef['name']} = $app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']][$value];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'multienum':
|
||||
|
||||
if (isset($obj->field_name_map[$fieldDef['name']]['options']) &&
|
||||
isset($app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']])
|
||||
) {
|
||||
$multienumString = '';
|
||||
$multienumValues = unencodeMultienum($value);
|
||||
$arrayCount = count($multienumValues);
|
||||
$i = 0;
|
||||
foreach ($multienumValues as $multienumValue) {
|
||||
$i++;
|
||||
$multienumString .= $app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']][$multienumValue];
|
||||
if($i !== ($arrayCount)) $multienumString .= ", ";
|
||||
}
|
||||
$obj->{$fieldDef['name']} = $multienumString;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'currency':
|
||||
|
||||
if (substr($fieldDef['name'], -9) !== '_usdollar') {
|
||||
$params['currency_id'] = getCurrencyId($obj->module_dir, $obj->id);
|
||||
$params['currency_symbol'] = $locale->currencies[$params['currency_id']]['symbol'];
|
||||
} else {
|
||||
$params['currency_id'] = $locale->getPrecedentPreference('currency');
|
||||
$params['currency_symbol'] = $locale->getPrecedentPreference('default_currency_symbol');
|
||||
$params['convert'] = true;
|
||||
}
|
||||
$obj->{$fieldDef['name']} = currency_format_number($value, $params);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param SugarBean $obj
|
||||
|
@ -210,7 +273,12 @@ class SearchResults
|
|||
{
|
||||
$relField = $idName;
|
||||
if (isset($obj->$link)) {
|
||||
$relId = $obj->$link->getFocus()->$relField;
|
||||
$linkedBeans = $obj->$link->getBeans();
|
||||
if(count($linkedBeans) === 1){
|
||||
$relId = array_keys($linkedBeans)[0];
|
||||
} else {
|
||||
$relId = $obj->$link->getFocus()->$relField;
|
||||
}
|
||||
if (is_object($relId)) {
|
||||
if (method_exists($relId, "getFocus")) {
|
||||
$relId = $relId->getFocus()->id;
|
||||
|
@ -242,9 +310,9 @@ class SearchResults
|
|||
*/
|
||||
protected function getLink(string $label, string $module, string $record, string $action): string
|
||||
{
|
||||
global $sugar_config;
|
||||
|
||||
return "<a href=\"{$sugar_config['site_url']}/index.php?action={$action}&module={$module}&record={$record}&offset=1\"><span>{$label}</span></a>";
|
||||
$link = ajaxLink("index.php?action={$action}&module={$module}&record={$record}");
|
||||
|
||||
return "<a href=\"{$link}\"><span>{$label}</span></a>";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,8 +143,15 @@ class SearchResultsController extends Controller
|
|||
$smarty->assign('results', $this->results);
|
||||
$smarty->assign('APP', $app_strings);
|
||||
$smarty->assign('SITE_URL', $siteUrl);
|
||||
$moduleName = [];
|
||||
try {
|
||||
$smarty->assign('resultsAsBean', $this->results->getHitsAsBeans());
|
||||
$hitsAsBeans = $this->results->getHitsAsBeans();
|
||||
foreach($hitsAsBeans as $bean){
|
||||
$moduleName[$bean[0]->module_name] = translate('LBL_MODULE_NAME', $bean[0]->module_name);
|
||||
}
|
||||
$smarty->assign('moduleLabel', $moduleName);
|
||||
|
||||
$smarty->assign('resultsAsBean', $hitsAsBeans);
|
||||
} catch (\SuiteCRM\Exception\Exception $e) {
|
||||
LoggerManager::getLogger()->fatal("Failed to retrieve ElasticSearch options");
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
{/if}
|
||||
|
||||
{foreach from=$resultsAsBean item=beans key=module}
|
||||
<h3>{$module}</h3>
|
||||
<h3>{$moduleLabel[$module]}</h3>
|
||||
<div class="unified-search-table-wrapper">
|
||||
<table class="list view">
|
||||
<thead>
|
||||
|
|
|
@ -406,7 +406,6 @@ EOF;
|
|||
options: {
|
||||
grouping:'$grouping',
|
||||
backgroundGrid:false,
|
||||
backgroundGrid:false,
|
||||
gutterBottom: 150,
|
||||
gutterTop:25,
|
||||
gutterLeft:128,
|
||||
|
|
|
@ -56,10 +56,10 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path),['allowed_classes' => false]);
|
||||
$html .= "report_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->report_module, $condition_name->module_path[0]))))."\";";
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
@ -84,9 +84,9 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path),['allowed_classes' => false]);
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
|
|
@ -61,7 +61,7 @@ function display_field_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$field_name = BeanFactory::newBean('AOR_Fields');
|
||||
$field_name->retrieve($row['id']);
|
||||
$field_name->module_path = unserialize(base64_decode($field_name->module_path));
|
||||
$field_name->module_path = unserialize(base64_decode($field_name->module_path),['allowed_classes' => false]);
|
||||
$html .= "report_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->report_module, $field_name->module_path[0]))))."\";";
|
||||
$field_item = json_encode($field_name->toArray());
|
||||
$html .= "loadFieldLine(".$field_item.");";
|
||||
|
|
|
@ -205,7 +205,7 @@ class AOR_Report extends Basic
|
|||
$field = BeanFactory::newBean('AOR_Fields');
|
||||
$field->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
|
||||
|
@ -311,7 +311,7 @@ class AOR_Report extends Basic
|
|||
$GLOBALS['log']->fatal('ambiguous group display for report ' . $this->id);
|
||||
} else {
|
||||
if ($rowsCount == 1) {
|
||||
$rows[0]['module_path'] = unserialize(base64_decode($rows[0]['module_path']));
|
||||
$rows[0]['module_path'] = unserialize(base64_decode($rows[0]['module_path']),['allowed_classes' => false]);
|
||||
if (!$rows[0]['module_path'][0]) {
|
||||
$module = new $beanList[$this->report_module]();
|
||||
$rows[0]['field_id_name'] = $module->field_defs[$rows[0]['field']]['id_name'] ? $module->field_defs[$rows[0]['field']]['id_name'] : $module->field_defs[$rows[0]['field']]['name'];
|
||||
|
@ -440,7 +440,7 @@ class AOR_Report extends Basic
|
|||
|
||||
$field_label = str_replace(' ', '_', (string) $field->label);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_module = $module;
|
||||
$table_alias = $field_module->table_name;
|
||||
|
@ -670,7 +670,7 @@ class AOR_Report extends Basic
|
|||
$field = BeanFactory::newBean('AOR_Fields');
|
||||
$field->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
|
||||
|
@ -905,7 +905,7 @@ class AOR_Report extends Basic
|
|||
// End
|
||||
}
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
|
||||
|
@ -1047,7 +1047,7 @@ class AOR_Report extends Basic
|
|||
$field = BeanFactory::newBean('AOR_Fields');
|
||||
$field->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
$field_module = $this->report_module;
|
||||
$field_alias = $field_bean->table_name;
|
||||
|
@ -1240,7 +1240,7 @@ class AOR_Report extends Basic
|
|||
|
||||
$field->label = str_replace(' ', '_', (string) $field->label) . $i;
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_module = $module;
|
||||
$table_alias = $field_module->table_name;
|
||||
|
@ -1263,7 +1263,6 @@ class AOR_Report extends Basic
|
|||
$field_module = $new_field_module;
|
||||
}
|
||||
}
|
||||
|
||||
$data = $field_module->field_defs[$field->field] ?? [];
|
||||
|
||||
if (!empty($data)){
|
||||
|
@ -1339,10 +1338,11 @@ class AOR_Report extends Basic
|
|||
unset($query['id_select'][$table_alias]);
|
||||
}
|
||||
|
||||
if ($field->group_by == 1) {
|
||||
if ($field->field_function != null) {
|
||||
$unique = $field->group_by == 1 ? 'DISTINCT ' : '';
|
||||
$select_field = $field->field_function . '(' . $unique . $select_field . ')';
|
||||
} elseif ($field->group_by == 1) {
|
||||
$query['group_by'][] = $select_field;
|
||||
} elseif ($field->field_function != null) {
|
||||
$select_field = $field->field_function . '(' . $select_field . ')';
|
||||
} else {
|
||||
$query['second_group_by'][] = $select_field;
|
||||
}
|
||||
|
@ -1489,14 +1489,14 @@ class AOR_Report extends Basic
|
|||
$condition = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path),['allowed_classes' => false]);
|
||||
|
||||
$condition_module = $module;
|
||||
$table_alias = $condition_module->table_name;
|
||||
$oldAlias = $table_alias;
|
||||
if (!empty($path[0]) && $path[0] != $module->module_dir) {
|
||||
foreach ($path as $rel) {
|
||||
if (empty($rel)) {
|
||||
if (empty($rel) || !is_string($rel)) {
|
||||
continue;
|
||||
}
|
||||
// Bug: Prevents relationships from loading.
|
||||
|
@ -1628,7 +1628,7 @@ class AOR_Report extends Basic
|
|||
break;
|
||||
|
||||
case 'Date':
|
||||
$params = unserialize(base64_decode($condition->value));
|
||||
$params = unserialize(base64_decode($condition->value),['allowed_classes' => false]);
|
||||
|
||||
// Fix for issue #1272 - AOR_Report module cannot update Date type parameter.
|
||||
if ($params == false) {
|
||||
|
|
|
@ -185,7 +185,7 @@ function getConditionsAsParameters($report, $override = array())
|
|||
continue;
|
||||
}
|
||||
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path),['allowed_classes' => false]);
|
||||
$field_module = $report->report_module;
|
||||
if ($path[0] != $report->report_module) {
|
||||
foreach ($path as $rel) {
|
||||
|
@ -196,7 +196,7 @@ function getConditionsAsParameters($report, $override = array())
|
|||
}
|
||||
}
|
||||
|
||||
$additionalConditions = unserialize(base64_decode($condition->value));
|
||||
$additionalConditions = unserialize(base64_decode($condition->value),['allowed_classes' => false]);
|
||||
|
||||
|
||||
$value = isset($override[$condition->id]['value']) ? $override[$condition->id]['value'] : $value = $condition->value;
|
||||
|
|
|
@ -38,9 +38,9 @@ class AOR_ReportsViewDetail extends ViewDetail
|
|||
if (!$condition->parameter) {
|
||||
continue;
|
||||
}
|
||||
$condition->module_path = implode(":", unserialize(base64_decode($condition->module_path)));
|
||||
$condition->module_path = implode(":", unserialize(base64_decode($condition->module_path),['allowed_classes' => false]));
|
||||
if ($condition->value_type == 'Date') {
|
||||
$condition->value = unserialize(base64_decode($condition->value));
|
||||
$condition->value = unserialize(base64_decode($condition->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = $condition->toArray();
|
||||
$display = getDisplayForField($condition->module_path, $condition->field, $this->bean->report_module);
|
||||
|
|
|
@ -82,10 +82,10 @@ class AOR_ReportsViewEdit extends ViewEdit
|
|||
$condition_name = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
if (!$condition_name->parenthesis) {
|
||||
$condition_name->module_path = implode(":", unserialize(base64_decode($condition_name->module_path)));
|
||||
$condition_name->module_path = implode(":", unserialize(base64_decode($condition_name->module_path),['allowed_classes' => false]));
|
||||
}
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = $condition_name->toArray();
|
||||
|
||||
|
@ -115,7 +115,7 @@ class AOR_ReportsViewEdit extends ViewEdit
|
|||
while ($row = $this->bean->db->fetchByAssoc($result)) {
|
||||
$field_name = BeanFactory::newBean('AOR_Fields');
|
||||
$field_name->retrieve($row['id']);
|
||||
$field_name->module_path = implode(":", unserialize(base64_decode($field_name->module_path)));
|
||||
$field_name->module_path = implode(":", unserialize(base64_decode($field_name->module_path),['allowed_classes' => false]));
|
||||
$arr = $field_name->toArray();
|
||||
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ class AOR_Scheduled_Reports extends basic
|
|||
|
||||
public function get_email_recipients()
|
||||
{
|
||||
$params = unserialize(base64_decode($this->email_recipients));
|
||||
$params = unserialize(base64_decode($this->email_recipients),['allowed_classes' => false]);
|
||||
|
||||
$emails = array();
|
||||
if (isset($params['email_target_type'])) {
|
||||
|
|
|
@ -42,7 +42,7 @@ function display_email_lines($focus, $field, $value, $view)
|
|||
{
|
||||
global $app_list_strings;
|
||||
$aorEmailToList = $app_list_strings['aor_email_to_list'] ?? '';
|
||||
$params = unserialize(base64_decode($value));
|
||||
$params = unserialize(base64_decode($value),['allowed_classes' => false]);
|
||||
|
||||
if ($view == 'EditView') {
|
||||
$html = '<script src="modules/AOR_Scheduled_Reports/emailRecipients.js"></script>';
|
||||
|
|
|
@ -67,7 +67,7 @@ class templateParser
|
|||
if (isset($field_def['name']) && $field_def['name'] != '') {
|
||||
$fieldName = $field_def['name'];
|
||||
|
||||
if (empty($focus->$fieldName)) {
|
||||
if (!isset($focus->$fieldName) || $focus->$fieldName === '') {
|
||||
$repl_arr[$key . '_' . $fieldName] = '';
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ function display_lines($focus, $field, $value, $view)
|
|||
if ($serviceCount == 0) {
|
||||
$service .= "<tr>";
|
||||
$service .= "<td width='5%' class='tabDetailViewDL' style='text-align: left;padding:2px;' scope='row'> </td>";
|
||||
$service .= "<td width='46%' class='dataLabel' style='text-align: left;padding:2px;' colspan='2' scope='row'>".$mod_strings['LBL_SERVICE_NAME']."</td>";
|
||||
$service .= "<td width='22%' class='dataLabel' style='text-align: left;padding:2px;' colspan='2' scope='row'>".$mod_strings['LBL_SERVICE_NAME']."</td>";
|
||||
$service .= "<td width='12%' class='dataLabel' style='text-align: right;padding:2px;' scope='row'>".$mod_strings['LBL_SERVICE_LIST_PRICE']."</td>";
|
||||
$service .= "<td width='12%' class='dataLabel' style='text-align: right;padding:2px;' scope='row'>".$mod_strings['LBL_SERVICE_DISCOUNT']."</td>";
|
||||
$service .= "<td width='12%' class='dataLabel' style='text-align: right;padding:2px;' scope='row'>".$mod_strings['LBL_SERVICE_PRICE']."</td>";
|
||||
|
|
|
@ -57,13 +57,13 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOW_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path), ['allowed_classes' => false]);
|
||||
if ($condition_name->module_path == '') {
|
||||
$condition_name->module_path = $focus->flow_module;
|
||||
}
|
||||
$html .= "flow_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->flow_module, $condition_name->module_path[0]))))."\";";
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value), ['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
@ -88,13 +88,13 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOW_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path), ['allowed_classes' => false]);
|
||||
if (empty($condition_name->module_path)) {
|
||||
$condition_name->module_path[0] = $focus->flow_module;
|
||||
}
|
||||
$html .= "flow_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->flow_module, $condition_name->module_path[0]))))."\";";
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value), ['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
|
|
@ -389,7 +389,7 @@ class AOW_WorkFlow extends Basic
|
|||
public function build_query_where(AOW_Condition $condition, $module, $query = array())
|
||||
{
|
||||
global $beanList, $app_list_strings, $sugar_config, $timedate;
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path), ['allowed_classes' => false]);
|
||||
|
||||
$condition_module = $module;
|
||||
$table_alias = $condition_module->table_name;
|
||||
|
@ -514,7 +514,7 @@ class AOW_WorkFlow extends Basic
|
|||
return array();
|
||||
case 'Date':
|
||||
|
||||
$params = @unserialize(base64_decode($condition->value));
|
||||
$params = @unserialize(base64_decode($condition->value), ['allowed_classes' => false]);
|
||||
if ($params === false) {
|
||||
LoggerManager::getLogger()->error('Unserializable data given');
|
||||
$params = [null];
|
||||
|
@ -749,7 +749,7 @@ class AOW_WorkFlow extends Basic
|
|||
$condition = BeanFactory::newBean('AOW_Conditions');
|
||||
$condition->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path), ['allowed_classes' => false]);
|
||||
|
||||
$condition_bean = $bean;
|
||||
|
||||
|
@ -815,7 +815,7 @@ class AOW_WorkFlow extends Basic
|
|||
break;
|
||||
|
||||
case 'Date':
|
||||
$params = unserialize(base64_decode($value));
|
||||
$params = unserialize(base64_decode($value), ['allowed_classes' => false]);
|
||||
$dateType = 'datetime';
|
||||
if ($params[0] == 'now') {
|
||||
$value = date('Y-m-d H:i:s');
|
||||
|
@ -1055,7 +1055,7 @@ class AOW_WorkFlow extends Basic
|
|||
|
||||
|
||||
$flow_action = new $action_name($action->id);
|
||||
if (!$flow_action->run_action($bean, unserialize(base64_decode($action->parameters)), $in_save)) {
|
||||
if (!$flow_action->run_action($bean, unserialize(base64_decode($action->parameters), ['allowed_classes' => false]), $in_save)) {
|
||||
$pass = false;
|
||||
$processed->aow_actions->add($action->id, array('status' => 'Failed'));
|
||||
} else {
|
||||
|
|
|
@ -559,7 +559,7 @@ class AOW_WorkFlowController extends SugarController
|
|||
$aow_action = BeanFactory::newBean('AOW_Actions');
|
||||
$aow_action->retrieve($_REQUEST['id']);
|
||||
$id = $aow_action->id;
|
||||
$params = unserialize(base64_decode($aow_action->parameters ?? ''));
|
||||
$params = unserialize(base64_decode($aow_action->parameters ?? ''), ['allowed_classes' => false]);
|
||||
|
||||
if ($params === false) {
|
||||
$params = [];
|
||||
|
|
|
@ -206,7 +206,7 @@ if ($mail->Mailer == 'smtp' && $mail->Host == '') {
|
|||
|
||||
$focus = BeanFactory::newBean('InboundEmail');
|
||||
$focus->checkImap();
|
||||
$storedOptions = unserialize(base64_decode($focus->stored_options ?? ''));
|
||||
$storedOptions = unserialize(base64_decode($focus->stored_options ?? ''), ['allowed_classes' => false]);
|
||||
$email_templates_arr = get_bean_select_array(true, 'EmailTemplate', 'name', '', 'name', true);
|
||||
$create_case_email_template = (isset($storedOptions['create_case_email_template'])) ? $storedOptions['create_case_email_template'] : "";
|
||||
$TMPL_DRPDWN_LOST = get_select_options_with_id($email_templates_arr, $res['lostpasswordtmpl']);
|
||||
|
|
|
@ -66,7 +66,8 @@ class Controller extends AbstractController
|
|||
*/
|
||||
public function doSave(): void
|
||||
{
|
||||
$searchEngine = filter_input(INPUT_POST, 'search-engine');
|
||||
$searchEngine = filter_input(INPUT_POST, 'search-engine', FILTER_SANITIZE_STRING);
|
||||
$aod = $searchEngine === 'BasicAndAodEngine';
|
||||
|
||||
SearchConfigurator::make()
|
||||
->setEngine($searchEngine)
|
||||
|
|
|
@ -98,7 +98,7 @@ $has_updates= false;
|
|||
if (!empty($license->settings['license_latest_versions'])) {
|
||||
$encodedVersions = $license->settings['license_latest_versions'];
|
||||
|
||||
$versions = unserialize(base64_decode($encodedVersions));
|
||||
$versions = unserialize(base64_decode($encodedVersions), ['allowed_classes' => false]);
|
||||
include('sugar_version.php');
|
||||
if (!empty($versions)) {
|
||||
foreach ($versions as $version) {
|
||||
|
|
|
@ -78,7 +78,7 @@ while ($row = $db->fetchByAssoc($result)) {
|
|||
$prefs = array();
|
||||
$newprefs = array();
|
||||
|
||||
$prefs = unserialize(base64_decode($row['user_preferences']));
|
||||
$prefs = unserialize(base64_decode($row['user_preferences']), ['allowed_classes' => false]);
|
||||
$setTo = '';
|
||||
$alreadySet = '';
|
||||
if (!empty($prefs)) {
|
||||
|
|
|
@ -196,7 +196,7 @@ function check_now($send_usage_info=true, $get_request_data=false, $response_dat
|
|||
|
||||
if ($response_data || !$sclient->getError()) {
|
||||
$serializedResultData = sugarDecode($key, $encodedResult);
|
||||
$resultData = unserialize($serializedResultData);
|
||||
$resultData = unserialize($serializedResultData, ['allowed_classes' => false]);
|
||||
if ($response_data && empty($resultData)) {
|
||||
$resultData = array();
|
||||
$resultData['validation'] = 'invalid validation key';
|
||||
|
|
|
@ -231,7 +231,7 @@ class CalendarDisplay
|
|||
if (empty($activity)) {
|
||||
$activity = $this->activity_colors;
|
||||
}
|
||||
$newActivities = unserialize(base64_decode($current_user->getPreference("CalendarActivities") ?? ''));
|
||||
$newActivities = unserialize(base64_decode($current_user->getPreference("CalendarActivities") ?? ''), ['allowed_classes' => false]);
|
||||
if ($newActivities) {
|
||||
$activity = array_merge($activity, $newActivities);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ function get_campaign_mailboxes_with_stored_options()
|
|||
$r = $db->query($q);
|
||||
|
||||
while ($a = $db->fetchByAssoc($r)) {
|
||||
$ret[$a['id']] = unserialize(base64_decode($a['stored_options']));
|
||||
$ret[$a['id']] = unserialize(base64_decode($a['stored_options']), ['allowed_classes' => false]);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
|
|
@ -49,21 +49,28 @@ class TemplateDatetimecombo extends TemplateRange
|
|||
{
|
||||
public $type = 'datetimecombo';
|
||||
public $len = '';
|
||||
public $dateStrings = array(
|
||||
'-none-' => '',
|
||||
'today'=>'now',
|
||||
'yesterday'=> '-1 day',
|
||||
'tomorrow'=>'+1 day',
|
||||
'next week'=> '+1 week',
|
||||
'next monday'=>'next monday',
|
||||
'next friday'=>'next friday',
|
||||
'two weeks'=> '+2 weeks',
|
||||
'next month'=> '+1 month',
|
||||
'first day of next month'=> 'first of next month', // must handle this non-GNU date string in SugarBean->populateDefaultValues; if we don't this will evaluate to 1969...
|
||||
'three months'=> '+3 months', //kbrill Bug #17023
|
||||
'six months'=> '+6 months',
|
||||
'next year'=> '+1 year',
|
||||
);
|
||||
public $dateStrings;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
global $app_strings;
|
||||
$this->dateStrings = array(
|
||||
$app_strings['LBL_NONE']=>'',
|
||||
$app_strings['LBL_YESTERDAY']=> '-1 day',
|
||||
$app_strings['LBL_TODAY']=>'now',
|
||||
$app_strings['LBL_TOMORROW']=>'+1 day',
|
||||
$app_strings['LBL_NEXT_WEEK']=> '+1 week',
|
||||
$app_strings['LBL_NEXT_MONDAY']=>'next monday',
|
||||
$app_strings['LBL_NEXT_FRIDAY']=>'next friday',
|
||||
$app_strings['LBL_TWO_WEEKS']=> '+2 weeks',
|
||||
$app_strings['LBL_NEXT_MONTH']=> '+1 month',
|
||||
$app_strings['LBL_FIRST_DAY_OF_NEXT_MONTH']=> 'first day of next month', // must handle this non-GNU date string in SugarBean->populateDefaultValues; if we don't this will evaluate to 1969...
|
||||
$app_strings['LBL_THREE_MONTHS']=> '+3 months', //kbrill Bug #17023
|
||||
$app_strings['LBL_SIXMONTHS']=> '+6 months',
|
||||
$app_strings['LBL_NEXT_YEAR']=> '+1 year',
|
||||
);
|
||||
}
|
||||
|
||||
public $hoursStrings = array(
|
||||
'' => '',
|
||||
|
|
|
@ -153,7 +153,7 @@ class TemplateEnum extends TemplateText
|
|||
$def['studio'] = 'visible';
|
||||
// this class may be extended, so only do the unserialize for genuine TemplateEnums
|
||||
if (get_class($this) == 'TemplateEnum' && empty($def['dependency'])) {
|
||||
$def['dependency'] = $this->ext4 !== null? unserialize(html_entity_decode((string) $this->ext4)) : null ;
|
||||
$def['dependency'] = $this->ext4 !== null? unserialize(html_entity_decode((string) $this->ext4), ['allowed_classes' => false]) : null ;
|
||||
}
|
||||
if (!empty($this->visibility_grid)) {
|
||||
$def['visibility_grid'] = $this->visibility_grid;
|
||||
|
|
|
@ -128,7 +128,7 @@ class TemplateMultiEnum extends TemplateEnum
|
|||
// turn off error reporting in case we are unpacking a value that hasn't been packed...
|
||||
// this is kludgy, but unserialize doesn't throw exceptions correctly
|
||||
if ($this->ext4[0] == 'a' && $this->ext4[1] == ':') {
|
||||
$unpacked = @unserialize($this->ext4) ;
|
||||
$unpacked = @unserialize($this->ext4, ['allowed_classes' => false]) ;
|
||||
} else {
|
||||
$unpacked = false;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ require_once('modules/Notes/Note.php');
|
|||
$note = BeanFactory::newBean('Notes');
|
||||
//check if file is an email image
|
||||
if (!$note->retrieve_by_string_fields(array('id' => $_REQUEST['id'], 'parent_type' => "Emails"))) {
|
||||
//die("Not a Valid Entry Point");
|
||||
die("Not a Valid Entry Point");
|
||||
}
|
||||
|
||||
$location = $GLOBALS['sugar_config']['upload_dir']."/" . $_REQUEST['id'];
|
||||
|
|
|
@ -81,8 +81,7 @@ if (isset($admin->settings['massemailer_email_copy'])) {
|
|||
$emailsPerSecond = 10;
|
||||
|
||||
$mail->setMailerForSystem();
|
||||
$mail->From = "no-reply@example.com";
|
||||
$mail->FromName = "no-reply";
|
||||
$mail->setSystemFromAddress();
|
||||
$mail->ContentType = "text/html";
|
||||
|
||||
$campaign_id = null;
|
||||
|
@ -226,32 +225,29 @@ do {
|
|||
$mail->Mailer = 'smtp';
|
||||
$mail->Host = $outboundEmailAccount->mail_smtpserver;
|
||||
$mail->Port = $outboundEmailAccount->mail_smtpport;
|
||||
if ($outboundEmailAccount->mail_smtpssl == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} elseif ($outboundEmailAccount->mail_smtpssl == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} else {
|
||||
$mail->SMTPSecure = '';
|
||||
}
|
||||
if ($outboundEmailAccount->mail_smtpauth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $outboundEmailAccount->mail_smtpuser;
|
||||
$mail->Password = $outboundEmailAccount->mail_smtppass;
|
||||
} else {
|
||||
$mail->SMTPAuth = false;
|
||||
$mail->Username = '';
|
||||
$mail->Password = '';
|
||||
}
|
||||
|
||||
$mail->setSecureProtocol($ssltls ?? false);
|
||||
$mail->initSMTPAuth(
|
||||
$outboundEmailAccount->auth_type ?? '',
|
||||
$outboundEmailAccount->external_oauth_connection_id ?? '',
|
||||
$outboundEmailAccount->mail_smtpuser ?? '',
|
||||
$outboundEmailAccount->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = 'sendmail';
|
||||
}
|
||||
|
||||
$mail->oe->mail_smtpauth_req = $outboundEmailAccount->mail_smtpauth_req;
|
||||
$mail->oe->mail_smtpuser = $outboundEmailAccount->mail_smtpuser;
|
||||
$mail->oe->mail_smtppass = $outboundEmailAccount->mail_smtppass;
|
||||
$mail->oe->mail_smtpserver = $outboundEmailAccount->mail_smtpserver;
|
||||
$mail->oe->mail_smtpport = $outboundEmailAccount->mail_smtpport;
|
||||
$mail->oe->mail_smtpssl = $outboundEmailAccount->mail_smtpssl;
|
||||
$mail->oe->auth_type = $outboundEmailAccount->auth_type ?? '';
|
||||
$mail->oe->external_oauth_connection_id = $outboundEmailAccount->external_oauth_connection_id ?? '';
|
||||
$mail->oe->mail_smtpauth_req = $outboundEmailAccount->mail_smtpauth_req ?? '';
|
||||
$mail->oe->mail_smtpuser = $outboundEmailAccount->mail_smtpuser ?? '';
|
||||
$mail->oe->mail_smtppass = $outboundEmailAccount->mail_smtppass ?? '';
|
||||
$mail->oe->mail_smtpserver = $outboundEmailAccount->mail_smtpserver ?? '';
|
||||
$mail->oe->mail_smtpport = $outboundEmailAccount->mail_smtpport ?? '';
|
||||
$mail->oe->mail_smtpssl = $outboundEmailAccount->mail_smtpssl ?? '';
|
||||
|
||||
$mail->FromName = $outboundEmailAccount->smtp_from_name ?? $outboundEmailAccount->mail_smtpuser;
|
||||
$mail->From = $outboundEmailAccount->smtp_from_address ?? $outboundEmailAccount->mail_smtpuser;
|
||||
}
|
||||
|
||||
if ((empty($row['related_confirm_opt_in']) || $row['related_confirm_opt_in'] == '0')) {
|
||||
|
|
|
@ -61,15 +61,6 @@ class EmailManController extends SugarController
|
|||
$_REQUEST['mail_sendtype'] = "SMTP";
|
||||
}
|
||||
|
||||
// save Outbound settings #Bug 20033 Ensure data for Outbound email exists before trying to update the system mailer.
|
||||
if (isset($_REQUEST['mail_sendtype']) && empty($_REQUEST['campaignConfig'])) {
|
||||
$oe = new OutboundEmail();
|
||||
$oe->populateFromPost();
|
||||
$oe->saveSystem();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$focus = BeanFactory::newBean('Administration');
|
||||
|
||||
if (isset($_POST['tracking_entities_location_type'])) {
|
||||
|
|
|
@ -139,6 +139,7 @@ $mod_strings = array(
|
|||
'LBL_FROM_ADDRESS_HELP' => 'When enabled, the assigning user\\\'s name and email address will be included in the From field of the email. This feature might not work with SMTP servers that do not allow sending from a different email account than the server account.',
|
||||
'LBL_HELP' => 'Help' /*for 508 compliance fix*/,
|
||||
'LBL_OUTBOUND_EMAIL_ACCOUNT_VIEW' => 'View Outbound Email Accounts',
|
||||
'LBL_SYSTEM_OUTBOUND_EMAIL_ACCOUNT' => 'System Outbound Email Account',
|
||||
'LBL_ALLOW_SEND_AS_USER' => 'Users may send as themselves:',
|
||||
'LBL_ALLOW_SEND_AS_USER_DESC' => 'When enabled, <b>all</b> users can send email using the outgoing mail server, using their own primary email address as the "From:" address.<br>This feature might not work with SMTP servers that do not allow sending from a different email account than the server account.',
|
||||
);
|
||||
|
|
|
@ -52,9 +52,22 @@ global $mod_strings;
|
|||
global $app_list_strings;
|
||||
global $app_strings;
|
||||
global $current_user;
|
||||
global $sugar_config;
|
||||
|
||||
$testMaxTimeout = 30; // seconds
|
||||
if (isset($sugar_config['outbound_email_test_max_timeout']) && is_numeric($sugar_config['outbound_email_test_max_timeout'])) {
|
||||
$testMaxTimeout = (int)$sugar_config['outbound_email_test_max_timeout'];
|
||||
}
|
||||
|
||||
ini_set('max_execution_time', $testMaxTimeout);
|
||||
|
||||
$json = getJSONobj();
|
||||
$pass = '';
|
||||
|
||||
if (empty($_REQUEST['mail_smtppass'])) {
|
||||
$_REQUEST['mail_smtppass'] = BeanFactory::getBean('OutboundEmailAccounts', $_REQUEST['record'])?->mail_smtppass ?? '';
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['mail_smtppass'])) {
|
||||
$pass = $_REQUEST['mail_smtppass'];
|
||||
} elseif (isset($_REQUEST['mail_type'])) {
|
||||
|
@ -73,13 +86,15 @@ $out = $email->sendEmailTest(
|
|||
$_REQUEST['mail_smtpserver'],
|
||||
$_REQUEST['mail_smtpport'],
|
||||
$_REQUEST['mail_smtpssl'],
|
||||
($_REQUEST['mail_smtpauth_req'] == 'true' ? 1 : 0),
|
||||
(isTrue($_REQUEST['mail_smtpauth_req']) ? 1 : 0),
|
||||
$_REQUEST['mail_smtpuser'],
|
||||
$pass,
|
||||
$_REQUEST['outboundtest_from_address'],
|
||||
$_REQUEST['outboundtest_to_address'],
|
||||
$_REQUEST['mail_sendtype'],
|
||||
$_REQUEST['mail_from_name']
|
||||
$_REQUEST['mail_from_name'],
|
||||
$_REQUEST['mail_auth_type'] ?? 'no_auth',
|
||||
$_REQUEST['mail_external_oauth_connection_id'] ?? '',
|
||||
);
|
||||
|
||||
$out = $json->encode($out);
|
||||
|
|
|
@ -105,96 +105,39 @@ function change_state(radiobutton) {
|
|||
{$MOD.LBL_OUTGOING_SECTION_HELP}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="{$OUTBOUND_TYPE_CLASS}">
|
||||
<td width="20%" scope="row">{$MOD.LBL_MAIL_SENDTYPE}</td>
|
||||
<td width="30%">
|
||||
<select id="mail_sendtype" name="mail_sendtype" onChange="notify_setrequired(document.ConfigureSettings); SUGAR.user.showHideGmailDefaultLink(this);" tabindex="1">{$mail_sendtype_options}</select>
|
||||
</td>
|
||||
<td scope="row" class="mobile-hide"> </td>
|
||||
<td class="mobile-hide"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" scope="row">
|
||||
{$MOD.LBL_SYSTEM_OUTBOUND_EMAIL_ACCOUNT}
|
||||
</td>
|
||||
{if empty($system_outbound_email_id)}
|
||||
<td width="30%">
|
||||
{sugar_link
|
||||
module="OutboundEmailAccounts"
|
||||
label=$APP.LBL_CREATE_BUTTON_LABEL
|
||||
action='Edit'
|
||||
class="btn btn-sm btn-primary"
|
||||
extraparams="type=system"
|
||||
}
|
||||
</td>
|
||||
{/if}
|
||||
{if !empty($system_outbound_email_id)}
|
||||
<td width="30%">
|
||||
{sugar_link
|
||||
module="OutboundEmailAccounts"
|
||||
record=$system_outbound_email_id
|
||||
label=$system_outbound_email_name
|
||||
action='DetailView'
|
||||
}
|
||||
</td>
|
||||
{/if}
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td width="20%" scope="row">{$MOD.LBL_NOTIFY_FROMNAME} <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" > <input id='notify_fromname' name='notify_fromname' tabindex='1' size='25' maxlength='128' type="text" value="{$notify_fromname}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20%" scope="row">{$MOD.LBL_NOTIFY_FROMADDRESS} <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%"><input id='notify_fromaddress' name='notify_fromaddress' tabindex='1' size='25' maxlength='128' type="text" value="{$notify_fromaddress}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" scope="row" colspan="4">{$MOD.LBL_CHOOSE_EMAIL_PROVIDER}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<div id="smtpButtonGroup" class="yui-buttongroup">
|
||||
<span id="gmail" class="yui-button yui-radio-button{if $mail_smtptype == 'gmail'} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="gmail" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_GMAIL}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span id="yahoomail" class="yui-button yui-radio-button{if $mail_smtptype == 'yahoomail'} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="yahoomail" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_YAHOO}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span id="exchange" class="yui-button yui-radio-button{if $mail_smtptype == 'exchange'} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="exchange" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_EXCHANGE}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span id="other" class="yui-button yui-radio-button{if $mail_smtptype == 'other' || empty($mail_smtptype)} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="other" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_OTHER}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<td colspan="2">
|
||||
<div id="smtp_settings">
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr id="mailsettings1">
|
||||
<td width="20%" scope="row"><span id="mail_smtpserver_label">{$MOD.LBL_MAIL_SMTPSERVER}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" ><input type="text" id="mail_smtpserver" name="mail_smtpserver" tabindex="1" size="25" maxlength="255" value="{$mail_smtpserver}"></td>
|
||||
<td width="20%" scope="row"><span id="mail_smtpport_label">{$MOD.LBL_MAIL_SMTPPORT}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" ><input type="text" id="mail_smtpport" name="mail_smtpport" tabindex="1" size="5" maxlength="5" value="{$mail_smtpport}"></td>
|
||||
</tr>
|
||||
<tr id="mailsettings2">
|
||||
<td scope="row"><span id='mail_smtpauth_req_label'>{$MOD.LBL_MAIL_SMTPAUTH_REQ}</span></td>
|
||||
<td >
|
||||
<input id='mail_smtpauth_req' name='mail_smtpauth_req' type="checkbox" class="checkbox" value="1" tabindex='1'
|
||||
onclick="notify_setrequired(document.ConfigureSettings);" {$mail_smtpauth_req}>
|
||||
</td>
|
||||
<td width="15%" scope="row"><span id="mail_smtpssl_label">{$APP.LBL_EMAIL_SMTP_SSL_OR_TLS}</span></td>
|
||||
<td width="35%" >
|
||||
<select id="mail_smtpssl" name="mail_smtpssl" tabindex="501" onchange="setDefaultSMTPPort();" >{$MAIL_SSL_OPTIONS}</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="smtp_auth1">
|
||||
<td width="20%" scope="row"><span id="mail_smtpuser_label">{$MOD.LBL_MAIL_SMTPUSER}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" ><input type="text" id="mail_smtpuser" name="mail_smtpuser" size="25" maxlength="255" value="{$mail_smtpuser}" tabindex='1' ></td>
|
||||
<td width="20%" class="mobile-hide"> </td>
|
||||
<td width="30%" class="mobile-hide"> </td>
|
||||
</tr>
|
||||
<tr id="smtp_auth2">
|
||||
<td width="20%" scope="row"><span id="mail_smtppass_label">{$MOD.LBL_MAIL_SMTPPASS}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" >
|
||||
<input type="password" id="mail_smtppass" name="mail_smtppass" size="25" maxlength="255" tabindex='1'>
|
||||
<a href="javascript:void(0)" id='mail_smtppass_link' onClick="SUGAR.util.setEmailPasswordEdit('mail_smtppass')" style="display: none">{$APP.LBL_CHANGE_PASSWORD}</a>
|
||||
</td>
|
||||
<td width="20%" class="mobile-hide"> </td>
|
||||
<td width="30%" class="mobile-hide"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr id="mail_allow_user">
|
||||
<td width="25%" scope="row">
|
||||
|
@ -203,7 +146,7 @@ function change_state(radiobutton) {
|
|||
</td>
|
||||
<td width="30%">
|
||||
<input type='hidden' id="notify_allow_default_outbound_hidden_input" name='notify_allow_default_outbound' value='0'>
|
||||
<input id="notify_allow_default_outbound" name='notify_allow_default_outbound' value="2" tabindex='1' class="checkbox" type="checkbox" {$notify_allow_default_outbound_on}>
|
||||
<input id="notify_allow_default_outbound" name='notify_allow_default_outbound' value="2" tabindex='1' class="checkbox" type="checkbox" style="margin-top: 10px;" {$notify_allow_default_outbound_on}>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="legacy-compose-option" {if isset($legacyEmailConfigEnabled)}style="display:none"{/if}>
|
||||
|
@ -222,13 +165,6 @@ function change_state(radiobutton) {
|
|||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="4" class="mobile-hide"> </tr>
|
||||
<tr>
|
||||
<td width="15%"><input type="button" class="btn btn-info" value="{$APP.LBL_EMAIL_TEST_OUTBOUND_SETTINGS}" onclick="testOutboundSettings();"> </td>
|
||||
<td width="15%" class="mobile-hide"> </td>
|
||||
<td width="40%" class="mobile-hide"> </td>
|
||||
<td width="40%" class="mobile-hide"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -182,8 +182,12 @@ class ViewConfig extends SugarView
|
|||
LoggerManager::getLogger()->warn('EmailMan view display error: mail allow user send is not set for focus');
|
||||
}
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemEmail();
|
||||
|
||||
$this->ss->assign("system_outbound_email_id", $oe->id);
|
||||
$this->ss->assign("system_outbound_email_name", $oe->name);
|
||||
|
||||
$this->ss->assign("mail_smtptype", $mailSmtpType);
|
||||
$this->ss->assign("mail_smtpserver", $mailSmtpServer);
|
||||
$this->ss->assign("mail_smtpport", $mailSmtpPort);
|
||||
$this->ss->assign("mail_smtpuser", $mailSmtpUser);
|
||||
|
@ -277,7 +281,7 @@ class ViewConfig extends SugarView
|
|||
$sugar_config['email_xss'] = getDefaultXssTags();
|
||||
}
|
||||
|
||||
foreach (unserialize(base64_decode($sugar_config['email_xss'])) as $k => $v) {
|
||||
foreach (unserialize(base64_decode($sugar_config['email_xss']), ['allowed_classes' => false]) as $k => $v) {
|
||||
$this->ss->assign($k."Checked", 'CHECKED');
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ if (!$focus->ACLAccess('Delete')) {
|
|||
$focus->mark_deleted($_REQUEST['record']);
|
||||
|
||||
if (isset($_REQUEST['record'])) {
|
||||
$query = "DELETE FROM emailman WHERE marketing_id ='" . $_REQUEST['record'] ."'";
|
||||
$query = "DELETE FROM emailman WHERE marketing_id ='" . $focus->db->quote($_REQUEST['record']) ."'";
|
||||
$focus->db->query($query);
|
||||
}
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ class EmailTemplate extends SugarBean
|
|||
|
||||
public function fill_in_additional_detail_fields()
|
||||
{
|
||||
if (empty($this->body) && !empty($this->body_html)) {
|
||||
if (!empty($this->body_html)) {
|
||||
global $sugar_config;
|
||||
|
||||
$bodyCleanup = $this->body_html;
|
||||
|
|
|
@ -812,7 +812,9 @@ class Email extends Basic
|
|||
$fromaddress,
|
||||
$toaddress,
|
||||
$mail_sendtype = 'smtp',
|
||||
$fromname = ''
|
||||
$fromname = '',
|
||||
$authType = 'no_auth',
|
||||
$externalOAuthConnectionId = ''
|
||||
) {
|
||||
global $current_user, $app_strings;
|
||||
$mod_strings = return_module_language($GLOBALS['current_language'], 'Emails'); //Called from EmailMan as well.
|
||||
|
@ -821,22 +823,14 @@ class Email extends Basic
|
|||
if ($mail->Mailer == 'smtp') {
|
||||
$mail->Host = $mailserver_url;
|
||||
$mail->Port = $port;
|
||||
if (isset($ssltls) && !empty($ssltls)) {
|
||||
$mail->protocol = "ssl://";
|
||||
if ($ssltls == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($ssltls == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} // if
|
||||
} else {
|
||||
$mail->protocol = "tcp://";
|
||||
}
|
||||
if ($smtp_auth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $smtp_username;
|
||||
$mail->Password = $smtppassword;
|
||||
}
|
||||
|
||||
$mail->setSecureProtocol($ssltls ?? false);
|
||||
$mail->initSMTPAuth(
|
||||
$authType ?? '',
|
||||
$externalOAuthConnectionId ?? '',
|
||||
$smtp_username ?? '',
|
||||
$smtppassword ?? ''
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = 'sendmail';
|
||||
}
|
||||
|
@ -2789,18 +2783,14 @@ class Email extends Basic
|
|||
$mail->Mailer = "smtp";
|
||||
$mail->Host = $oe->mail_smtpserver;
|
||||
$mail->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} // if
|
||||
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $oe->mail_smtpuser;
|
||||
$mail->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$mail->setSecureProtocol($oe->mail_smtpssl);
|
||||
$mail->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = "sendmail";
|
||||
}
|
||||
|
@ -2842,18 +2832,14 @@ class Email extends Basic
|
|||
$mail->Mailer = "smtp";
|
||||
$mail->Host = $oe->mail_smtpserver;
|
||||
$mail->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} // if
|
||||
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $oe->mail_smtpuser;
|
||||
$mail->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$mail->setSecureProtocol($oe->mail_smtpssl);
|
||||
$mail->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = "sendmail";
|
||||
}
|
||||
|
@ -3295,15 +3281,12 @@ class Email extends Basic
|
|||
*/
|
||||
public function getSystemDefaultEmail()
|
||||
{
|
||||
$email = array();
|
||||
|
||||
$r1 = $this->db->query('SELECT config.value FROM config WHERE name=\'fromaddress\'');
|
||||
$r2 = $this->db->query('SELECT config.value FROM config WHERE name=\'fromname\'');
|
||||
$a1 = $this->db->fetchByAssoc($r1);
|
||||
$a2 = $this->db->fetchByAssoc($r2);
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemMailerSettings();
|
||||
|
||||
$email['email'] = $a1['value'];
|
||||
$email['name'] = $a2['value'];
|
||||
$email['email'] = $oe->smtp_from_addr ?? '';
|
||||
$email['name'] = $oe->smtp_from_name ?? '';
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
@ -3419,7 +3402,7 @@ class Email extends Basic
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (empty($this->contact_id) && !empty($this->parent_id) && !empty($this->parent_type) && $this->parent_type === 'Contacts' && !empty($this->parent_name)) {
|
||||
$this->contact_id = $this->parent_id;
|
||||
$this->contact_name = $this->parent_name;
|
||||
|
@ -4438,14 +4421,16 @@ eoq;
|
|||
|
||||
// is from address in the request?
|
||||
|
||||
if (!isset($request['from_addr_name']) || !$request['from_addr_name']) {
|
||||
$useDefaultFromAddressName = true;
|
||||
}
|
||||
if (!isset($request['from_addr'])) {
|
||||
if (!isset($request['from_addr_name']) || !$request['from_addr_name']) {
|
||||
$useDefaultFromAddressName = true;
|
||||
}
|
||||
|
||||
// is from name in the request?
|
||||
// is from name in the request?
|
||||
|
||||
if (!isset($request['from_addr_email']) || !$request['from_addr_email']) {
|
||||
$useDefaultFromAddressEmail = true;
|
||||
if (!isset($request['from_addr_email']) || !$request['from_addr_email']) {
|
||||
$useDefaultFromAddressEmail = true;
|
||||
}
|
||||
}
|
||||
|
||||
// so, do we have to use any default data?
|
||||
|
|
|
@ -1561,7 +1561,7 @@ HTML;
|
|||
}
|
||||
if (file_exists($cache)) {
|
||||
include($cache); // profides $cacheFile
|
||||
$metaOut = unserialize($cacheFile['out']);
|
||||
$metaOut = unserialize($cacheFile['out'], ['allowed_classes' => false]);
|
||||
$meta = $metaOut['meta']['email'];
|
||||
if (isset($meta['attachments'])) {
|
||||
$attachmentHtmlData = $meta['attachments'];
|
||||
|
@ -3391,9 +3391,7 @@ eoq;
|
|||
include($cacheFilePath); // provides $cacheFile
|
||||
|
||||
if (isset($cacheFile[$key])) {
|
||||
$ret = unserialize($cacheFile[$key]);
|
||||
|
||||
return $ret;
|
||||
return unserialize($cacheFile[$key], ['allowed_classes' => false]);
|
||||
}
|
||||
} else {
|
||||
$GLOBALS['log']->debug("EMAILUI: cache file not found [ {$cacheFilePath} ] - creating blank cache file");
|
||||
|
|
|
@ -1510,7 +1510,7 @@ eoq;
|
|||
|
||||
foreach ($ie->field_defs as $k => $v) {
|
||||
if ($k == 'stored_options') {
|
||||
$ie->$k = unserialize(base64_decode($ie->$k));
|
||||
$ie->$k = unserialize(base64_decode($ie->$k), ['allowed_classes' => false]);
|
||||
if (isset($ie->stored_options['from_name'])) {
|
||||
$ie->stored_options['from_name'] = from_html($ie->stored_options['from_name']);
|
||||
}
|
||||
|
|
|
@ -498,7 +498,7 @@ class ListViewDataEmails extends ListViewData
|
|||
$ret = $emailHeader['flagged'];
|
||||
break;
|
||||
case 'name':
|
||||
$ret = html_entity_decode((string) $inboundEmail->handleMimeHeaderDecode($emailHeader['subject'] ?? ''));
|
||||
$ret = html_entity_decode(purify_html((string) $inboundEmail->handleMimeHeaderDecode($emailHeader['subject'] ?? '')));
|
||||
break;
|
||||
case 'date_entered':
|
||||
$db = DBManagerFactory::getInstance();
|
||||
|
|
|
@ -42,6 +42,7 @@ if (!defined('sugarEntry') || !sugarEntry) {
|
|||
die('Not A Valid Entry Point');
|
||||
}
|
||||
|
||||
use League\OAuth2\Client\Provider\AbstractProvider;
|
||||
use League\OAuth2\Client\Token\AccessTokenInterface;
|
||||
|
||||
interface ExternalOAuthProviderConnectorInterface
|
||||
|
@ -142,4 +143,12 @@ interface ExternalOAuthProviderConnectorInterface
|
|||
* @return string
|
||||
*/
|
||||
public function getAccessTokenRequestGrant(array $providerConfig): string;
|
||||
|
||||
/**
|
||||
* Get Provider
|
||||
* @param string $requestClientId
|
||||
* @param string $requestClientSecret
|
||||
* @return AbstractProvider|null
|
||||
*/
|
||||
public function getProvider(string $requestClientId, string $requestClientSecret): ?AbstractProvider;
|
||||
}
|
||||
|
|
|
@ -268,6 +268,59 @@ class OAuthAuthorizationService
|
|||
];
|
||||
}
|
||||
|
||||
public function refreshExpiredOAuthToken(string $oAuthConnectionId): void
|
||||
{
|
||||
/** @var ExternalOAuthConnection $oauthConnection */
|
||||
$oauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $oAuthConnectionId);
|
||||
|
||||
$hasExpiredFeedback = $this->hasConnectionTokenExpired($oauthConnection);
|
||||
$refreshToken = $hasExpiredFeedback['refreshToken'] ?? false;
|
||||
if ($refreshToken === true) {
|
||||
$refreshTokenFeedback = $this->refreshConnectionToken($oauthConnection);
|
||||
|
||||
if ($refreshTokenFeedback['success'] === false) {
|
||||
$message = $this->getOAuthRefreshTokenErrorMessage(
|
||||
$refreshTokenFeedback['reLogin'],
|
||||
$oauthConnection,
|
||||
$oAuthConnectionId
|
||||
);
|
||||
displayAdminError($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refersh token error messages
|
||||
* @param $reLogin
|
||||
* @param ExternalOAuthConnection $oauthConnection
|
||||
* @param string $oAuthConnectionId
|
||||
* @return string
|
||||
*/
|
||||
public function getOAuthRefreshTokenErrorMessage(
|
||||
$reLogin,
|
||||
ExternalOAuthConnection $oauthConnection,
|
||||
string $oAuthConnectionId
|
||||
): string {
|
||||
$message = translate('ERR_OAUTH_CONNECTION_ERROR');
|
||||
$linkAction = 'DetailView';
|
||||
|
||||
if ($reLogin === true) {
|
||||
$linkAction = 'EditView';
|
||||
$message = translate('WARN_OAUTH_TOKEN_SESSION_EXPIRED');
|
||||
}
|
||||
|
||||
$oauthConnectionName = $oauthConnection->name;
|
||||
|
||||
$hasAccess = $oauthConnection->ACLAccess('edit') ?? false;
|
||||
if ($hasAccess === true) {
|
||||
$message .= " <a href=\"index.php?module=ExternalOAuthConnection&action=$linkAction&record=$oAuthConnectionId\">$oauthConnectionName</a>.";
|
||||
} else {
|
||||
$message .= $oauthConnectionName . '.';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map token to bean fields array
|
||||
* @param string $providerId
|
||||
|
|
|
@ -73,6 +73,7 @@ class ExternalOAuthProvider extends Basic
|
|||
public $expires_in_mapping;
|
||||
public $refresh_token_mapping;
|
||||
public $token_type_mapping;
|
||||
public $redirect_uri_type;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -322,10 +323,13 @@ class ExternalOAuthProvider extends Basic
|
|||
global $sugar_config;
|
||||
|
||||
$siteUrl = $sugar_config['site_url'] ?? '';
|
||||
|
||||
$siteUrl = str_ireplace('index.php', '', (string) $siteUrl);
|
||||
$siteUrl = rtrim($siteUrl, " \t\n\r\0\x0B\/");
|
||||
|
||||
if ($this->redirect_uri_type === 'pretty_url') {
|
||||
return $siteUrl . '/ep/setExternalOAuthToken';
|
||||
}
|
||||
|
||||
return $siteUrl . '/index.php?entryPoint=setExternalOAuthToken';
|
||||
}
|
||||
|
||||
|
|
196
public/legacy/modules/ExternalOAuthProvider/js/fields.js
Normal file
196
public/legacy/modules/ExternalOAuthProvider/js/fields.js
Normal file
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SUITECRM, SUITECRM DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
var externalOAuthProviderFields = function () {
|
||||
|
||||
var getDefaultFieldGetter = function () {
|
||||
return function (field$) {
|
||||
return (field$ && field$.val()) || '';
|
||||
};
|
||||
};
|
||||
|
||||
var getFunctionFieldGetter = function () {
|
||||
return function (field$) {
|
||||
field$ = field$[0];
|
||||
if (!field$) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return field$.innerText || field$.textContent || '';
|
||||
};
|
||||
};
|
||||
|
||||
var getDefaultFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.val(value);
|
||||
field$.change();
|
||||
};
|
||||
};
|
||||
|
||||
var getFunctionFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
field$ = field$[0];
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.innerText = value || '';
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
fields: {
|
||||
'record': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'name': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'client_id': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'client_secret': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'redirect_uri_span': {
|
||||
type: 'function'
|
||||
},
|
||||
'redirect_uri_type': {
|
||||
type: 'enum'
|
||||
},
|
||||
},
|
||||
|
||||
getters: {
|
||||
default: getDefaultFieldGetter(),
|
||||
varchar: getDefaultFieldGetter(),
|
||||
function: getFunctionFieldGetter(),
|
||||
checkbox: function (field$) {
|
||||
return (field$ && field$.prop('checked')) || false;
|
||||
}
|
||||
},
|
||||
|
||||
setters: {
|
||||
default: getDefaultFieldSetter(),
|
||||
varchar: getDefaultFieldSetter(),
|
||||
function: getFunctionFieldSetter(),
|
||||
checkbox: function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.prop('checked', !!value);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function (field, value) {
|
||||
var field$ = this.getField$(field);
|
||||
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var setter = this.getValueSetter(field);
|
||||
if (!setter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return setter(field$, value);
|
||||
},
|
||||
|
||||
getValue: function (field) {
|
||||
var field$ = this.getField$(field);
|
||||
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var getter = this.getValueGetter(field);
|
||||
|
||||
if (!getter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getter(field$);
|
||||
},
|
||||
|
||||
hide: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.hide();
|
||||
},
|
||||
|
||||
show: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.show();
|
||||
},
|
||||
|
||||
|
||||
getField$: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].getField$) || null;
|
||||
|
||||
if (handler) {
|
||||
return handler(field);
|
||||
}
|
||||
|
||||
return $('#' + field) || null;
|
||||
},
|
||||
|
||||
getFieldCell$: function (field) {
|
||||
return $('[data-field="' + field + '"]') || null;
|
||||
},
|
||||
|
||||
getFieldType: function (field) {
|
||||
return (this.fields[field] && this.fields[field].type) || 'varchar';
|
||||
},
|
||||
|
||||
getValueGetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.getters[type] || this.getters['default'];
|
||||
},
|
||||
|
||||
getValueSetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.setters[type] || this.setters['default'];
|
||||
}
|
||||
|
||||
};
|
||||
}();
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SUITECRM, SUITECRM DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
function toggleRedirectUri(type, url) {
|
||||
var fieldValues = {
|
||||
'query_string': {
|
||||
'uri': 'index.php?entryPoint=setExternalOAuthToken'
|
||||
},
|
||||
'pretty_url': {
|
||||
'uri': 'ep/setExternalOAuthToken'
|
||||
}
|
||||
}
|
||||
|
||||
var match = url.match(/^(.*?)(?:index\.php|ep)(?:\/|\?|$)/);
|
||||
match = match ? match[1] : url;
|
||||
|
||||
var uri = fieldValues[type] ? fieldValues[type].uri : '';
|
||||
|
||||
externalOAuthProviderFields.setValue('redirect_uri_span', match + uri);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
var url = externalOAuthProviderFields.getValue('redirect_uri_span');
|
||||
var type = externalOAuthProviderFields.getValue('redirect_uri_type');
|
||||
toggleRedirectUri(type, url);
|
||||
|
||||
|
||||
externalOAuthProviderFields.getField$('redirect_uri_type').change(function () {
|
||||
url = externalOAuthProviderFields.getValue('redirect_uri_span');
|
||||
type = externalOAuthProviderFields.getValue('redirect_uri_type');
|
||||
toggleRedirectUri(type, url);
|
||||
});
|
||||
});
|
|
@ -76,6 +76,7 @@ $mod_strings = [
|
|||
'LBL_TYPE' => 'Type',
|
||||
'LBL_CONNECTOR' => 'Connector',
|
||||
'LBL_REDIRECT_URI' => 'Redirect URI',
|
||||
'LBL_REDIRECT_URI_TYPE' => 'Redirect URI Type',
|
||||
|
||||
'LBL_CLIENT_ID' => 'Client Id',
|
||||
'LBL_CLIENT_SECRET' => 'Client Secret',
|
||||
|
|
|
@ -95,7 +95,7 @@ $viewdefs[$module_name]['DetailView'] = [
|
|||
],
|
||||
[
|
||||
'redirect_uri',
|
||||
''
|
||||
'redirect_uri_type'
|
||||
],
|
||||
],
|
||||
'lbl_extra' => [
|
||||
|
|
|
@ -68,6 +68,13 @@ $viewdefs['ExternalOAuthProvider'] = [
|
|||
'panelDefault' => 'expanded',
|
||||
],
|
||||
],
|
||||
'javascript' => '
|
||||
<script type="text/javascript">
|
||||
{suite_combinescripts
|
||||
files="modules/ExternalOAuthProvider/js/fields.js,
|
||||
modules/ExternalOAuthProvider/js/redirect_uri_toggle.js"}
|
||||
</script>
|
||||
'
|
||||
],
|
||||
'panels' => [
|
||||
'default' => [
|
||||
|
@ -93,7 +100,7 @@ $viewdefs['ExternalOAuthProvider'] = [
|
|||
],
|
||||
[
|
||||
'redirect_uri',
|
||||
''
|
||||
'redirect_uri_type'
|
||||
],
|
||||
],
|
||||
'lbl_extra' => [
|
||||
|
|
|
@ -127,6 +127,21 @@ $dictionary['ExternalOAuthProvider'] = [
|
|||
'exportable' => false,
|
||||
'unified_search' => false,
|
||||
],
|
||||
'redirect_uri_type' => [
|
||||
'name' => 'redirect_uri_type',
|
||||
'vname' => 'LBL_REDIRECT_URI_TYPE',
|
||||
'type' => 'enum',
|
||||
'default' => 'pretty_url',
|
||||
'options' => 'redirect_uri_type_dom',
|
||||
'len' => 50,
|
||||
'required' => false,
|
||||
'reportable' => false,
|
||||
'massupdate' => false,
|
||||
'inline_edit' => false,
|
||||
'importable' => false,
|
||||
'exportable' => false,
|
||||
'unified_search' => false,
|
||||
],
|
||||
'client_id' => [
|
||||
'name' => 'client_id',
|
||||
'vname' => 'LBL_CLIENT_ID',
|
||||
|
@ -185,6 +200,7 @@ $dictionary['ExternalOAuthProvider'] = [
|
|||
'vname' => 'LBL_AUTHORIZE_URL_OPTIONS',
|
||||
'type' => 'stringmap',
|
||||
'dbType' => 'text',
|
||||
'default' => '{"prompt":"login"}',
|
||||
'show_keys' => true,
|
||||
'required' => false,
|
||||
'reportable' => false,
|
||||
|
|
|
@ -52,7 +52,7 @@ require_once('modules/Import/ImportDuplicateCheck.php');
|
|||
class Importer
|
||||
{
|
||||
/**
|
||||
* @var ImportFieldSanitizer
|
||||
* @var ImportFieldSanitize
|
||||
*/
|
||||
protected $ifs;
|
||||
|
||||
|
@ -62,27 +62,27 @@ class Importer
|
|||
protected $defaultUserCurrency;
|
||||
|
||||
/**
|
||||
* @var importColumns
|
||||
* @var array
|
||||
*/
|
||||
protected $importColumns;
|
||||
|
||||
/**
|
||||
* @var importSource
|
||||
* @var ImportDataSource
|
||||
*/
|
||||
protected $importSource;
|
||||
|
||||
/**
|
||||
* @var $isUpdateOnly
|
||||
* @var bool
|
||||
*/
|
||||
protected $isUpdateOnly;
|
||||
|
||||
/**
|
||||
* @var $bean
|
||||
* @var SugarBean
|
||||
*/
|
||||
protected $bean;
|
||||
|
||||
/**
|
||||
* @var sugarToExternalSourceFieldMap
|
||||
* @var array
|
||||
*/
|
||||
protected $sugarToExternalSourceFieldMap = array();
|
||||
|
||||
|
@ -97,7 +97,7 @@ class Importer
|
|||
$this->bean = $bean;
|
||||
|
||||
// use our own error handler
|
||||
set_error_handler(array('Importer','handleImportErrors'), E_ALL);
|
||||
set_error_handler(array('Importer','handleImportErrors'), E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_WARNING & ~E_NOTICE);
|
||||
|
||||
// Increase the max_execution_time since this step can take awhile
|
||||
ini_set("max_execution_time", max($sugar_config['import_max_execution_time'], 3600));
|
||||
|
|
|
@ -130,7 +130,7 @@ abstract class ImportDataSource implements Iterator
|
|||
* @return void
|
||||
*/
|
||||
abstract public function getHeaderColumns();
|
||||
|
||||
|
||||
/**
|
||||
* Set the source name.
|
||||
*
|
||||
|
@ -197,7 +197,7 @@ abstract class ImportDataSource implements Iterator
|
|||
if ($module == 'Case') {
|
||||
$module = 'aCase';
|
||||
}
|
||||
|
||||
|
||||
$last_import->bean_type = $module;
|
||||
$last_import->bean_id = $id;
|
||||
return $last_import->save();
|
||||
|
@ -228,9 +228,9 @@ abstract class ImportDataSource implements Iterator
|
|||
{
|
||||
global $current_language;
|
||||
$mod_strings = return_module_language($current_language, 'Import');
|
||||
return "<b>{$mod_strings['LBL_ERROR']}</b> $error <br/>".
|
||||
"<b>{$mod_strings['LBL_FIELD_NAME']}</b> $fieldName <br/>" .
|
||||
"<b>{$mod_strings['LBL_VALUE']}</b> $fieldValue <br/>";
|
||||
return "{$mod_strings['LBL_ERROR']}: $error. ".
|
||||
"- {$mod_strings['LBL_FIELD_NAME']}: $fieldName. " .
|
||||
"- {$mod_strings['LBL_VALUE']}: $fieldValue";
|
||||
}
|
||||
public function resetRowErrorCounter()
|
||||
{
|
||||
|
@ -330,7 +330,7 @@ abstract class ImportDataSource implements Iterator
|
|||
//Add the error message to the first column
|
||||
array_unshift($rowData, $errorMessage);
|
||||
fputcsv($fp, $rowData);
|
||||
|
||||
|
||||
fclose($fp);
|
||||
fclose($fpNoErrors);
|
||||
}
|
||||
|
|
|
@ -47,12 +47,11 @@
|
|||
{
|
||||
padding-left: 0px;
|
||||
}
|
||||
div.resultsTable {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
padding-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
div.resultsTable {
|
||||
overflow: auto;
|
||||
padding-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
{/literal}
|
||||
|
||||
|
@ -98,7 +97,7 @@
|
|||
</form>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<table width="100%" id="tabListContainerTable" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td nowrap id="tabListContainerTD">
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
{counter start=0 name="colCounter" print=false assign="colCounter"}
|
||||
{foreach from=$rowData key=col item=params}
|
||||
{strip}
|
||||
<td align='left' valign="top">
|
||||
<td align='left' valign="top" scope="record">
|
||||
{$params}
|
||||
</td>
|
||||
{/strip}
|
||||
|
|
|
@ -128,7 +128,7 @@ class ImportListView
|
|||
$this->ss->assign('navStrings', $navStrings);
|
||||
$this->ss->assign('pageData', $this->generatePaginationData());
|
||||
$this->ss->assign('tableID', $this->tableID);
|
||||
$this->ss->assign('colCount', count($this->headerColumns));
|
||||
$this->ss->assign('colCount', is_countable($this->headerColumns) ? count($this->headerColumns) : 0);
|
||||
$this->ss->assign('APP', $app_strings);
|
||||
$this->ss->assign('rowColor', array('oddListRow', 'evenListRow'));
|
||||
$this->ss->assign('displayColumns', $this->headerColumns);
|
||||
|
|
|
@ -215,7 +215,7 @@ ProcessImport = new function()
|
|||
+ "&import_module={$_REQUEST['import_module']}"
|
||||
+ "&has_header=" + document.getElementById("importstepdup").has_header.value ;
|
||||
if ( ProcessImport.fileCount >= ProcessImport.fileTotal ) {
|
||||
YAHOO.SUGAR.MessageBox.updateProgress(1,'{$mod_strings['LBL_IMPORT_COMPLETED']}');
|
||||
YAHOO.SUGAR.MessageBox.updateProgress(100,'{$mod_strings['LBL_IMPORT_COMPLETED']}');
|
||||
SUGAR.util.hrefURL(locationStr);
|
||||
}
|
||||
else {
|
||||
|
@ -238,7 +238,7 @@ ProcessImport = new function()
|
|||
);
|
||||
var move = 0;
|
||||
if ( this.fileTotal > 0 ) {
|
||||
move = this.fileCount/this.fileTotal;
|
||||
move = (this.fileCount/this.fileTotal) * 100;
|
||||
}
|
||||
YAHOO.SUGAR.MessageBox.updateProgress( move,
|
||||
"{$mod_strings['LBL_IMPORT_RECORDS']} " + ((this.fileCount * this.recordThreshold) + 1)
|
||||
|
|
|
@ -150,7 +150,7 @@ class AOPInboundEmail extends InboundEmail
|
|||
$GLOBALS['log']->debug('InboundEmail created one case with number: '.$c->case_number);
|
||||
$createCaseTemplateId = $this->get_stored_options('create_case_email_template', "");
|
||||
if (!empty($this->stored_options)) {
|
||||
$storedOptions = unserialize(base64_decode($this->stored_options));
|
||||
$storedOptions = unserialize(base64_decode($this->stored_options), ['allowed_classes' => false]);
|
||||
}
|
||||
if (!empty($createCaseTemplateId)) {
|
||||
$fromName = "";
|
||||
|
|
|
@ -1572,7 +1572,7 @@ class InboundEmail extends SugarBean
|
|||
flush();
|
||||
} // while
|
||||
fclose($fh);
|
||||
$diff = unserialize($data);
|
||||
$diff = unserialize($data, ['allowed_classes' => false]);
|
||||
if (!empty($diff)) {
|
||||
if ((is_countable($diff) ? count($diff) : 0) > 50) {
|
||||
$newDiff = array_slice($diff, 50, is_countable($diff) ? count($diff) : 0, true);
|
||||
|
@ -2035,7 +2035,7 @@ class InboundEmail extends SugarBean
|
|||
flush();
|
||||
} // while
|
||||
fclose($fh);
|
||||
$results = unserialize($data);
|
||||
$results = unserialize($data, ['allowed_classes' => false]);
|
||||
} // if
|
||||
} // if
|
||||
if (!$cacheDataExists) {
|
||||
|
@ -2964,7 +2964,7 @@ class InboundEmail extends SugarBean
|
|||
|
||||
$focusUser = BeanFactory::newBean('Users');
|
||||
$focusUser->retrieve($groupId);
|
||||
$mailerId = (isset($_REQUEST['outbound_email'])) ? $_REQUEST['outbound_email'] : "";
|
||||
$mailerId = (isset($_REQUEST['outbound_email'])) ? $this->db->quote($_REQUEST['outbound_email']) : "";
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
if ($mailerId != "") {
|
||||
|
@ -4144,14 +4144,14 @@ class InboundEmail extends SugarBean
|
|||
$emailMessage = $this->mailParser->parse($emailBody, false)->getTextContent();
|
||||
$emailMessage = $this->handleInlineImages($emailBody, $emailMessage);
|
||||
$emailMessage = $this->customGetMessageText($emailMessage);
|
||||
return SugarCleaner::cleanHtml($emailMessage, false);
|
||||
return html_entity_decode(purify_html(SugarCleaner::cleanHtml($emailMessage, false)));
|
||||
}
|
||||
|
||||
$emailMessage = $this->mailParser->parse($emailBody, false)->getHtmlContent();
|
||||
$emailMessage = $this->handleInlineImages($emailBody, $emailMessage);
|
||||
$emailMessage = $this->customGetMessageText($emailMessage);
|
||||
$emailMessage = $this->customGetMessageText($emailMessage) ?? '';
|
||||
|
||||
return SugarCleaner::cleanHtml($emailMessage, $clean_email);
|
||||
return html_entity_decode(purify_html(SugarCleaner::cleanHtml($emailMessage, $clean_email)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5495,7 +5495,7 @@ class InboundEmail extends SugarBean
|
|||
//// ASSIGN APPROPRIATE ATTRIBUTES TO NEW EMAIL OBJECT
|
||||
// handle UTF-8/charset encoding in the ***headers***
|
||||
|
||||
$email->name = $this->handleMimeHeaderDecode($header->subject);
|
||||
$email->name = purify_html($this->handleMimeHeaderDecode($parsedFullHeader->subject));
|
||||
$email->type = 'inbound';
|
||||
if (!empty($unixHeaderDate)) {
|
||||
$email->date_sent_received = $timedate->asUser($unixHeaderDate);
|
||||
|
@ -5713,7 +5713,7 @@ class InboundEmail extends SugarBean
|
|||
$fullHeader = $this->getImap()->fetchHeader($uid, FT_UID);
|
||||
$parsedFullHeader = $this->getImap()->rfc822ParseHeaders($fullHeader);
|
||||
|
||||
$email->name = $this->handleMimeHeaderDecode($parsedFullHeader->subject);
|
||||
$email->name = purify_html($this->handleMimeHeaderDecode($parsedFullHeader->subject));
|
||||
$email->type = 'inbound';
|
||||
|
||||
if (isset($request['metadata']['viewdefs'])) {
|
||||
|
@ -7509,7 +7509,7 @@ class InboundEmail extends SugarBean
|
|||
include($cache); // profides $cacheFile
|
||||
/** @var $cacheFile array */
|
||||
|
||||
$metaOut = unserialize($cacheFile['out']);
|
||||
$metaOut = unserialize($cacheFile['out'], ['allowed_classes' => false]);
|
||||
$meta = $metaOut['meta']['email'];
|
||||
$email = BeanFactory::newBean('Emails');
|
||||
|
||||
|
@ -8667,38 +8667,6 @@ eoq;
|
|||
return 'imap2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refersh token error messages
|
||||
* @param $reLogin
|
||||
* @param ExternalOAuthConnection $oauthConnection
|
||||
* @param string $oAuthConnectionId
|
||||
* @return string
|
||||
*/
|
||||
protected function getOAuthRefreshTokenErrorMessage(
|
||||
$reLogin,
|
||||
ExternalOAuthConnection $oauthConnection,
|
||||
string $oAuthConnectionId
|
||||
): string {
|
||||
$message = translate('ERR_IMAP_OAUTH_CONNECTION_ERROR', 'InboundEmail');
|
||||
$linkAction = 'DetailView';
|
||||
|
||||
if ($reLogin === true) {
|
||||
$linkAction = 'EditView';
|
||||
$message = translate('WARN_OAUTH_TOKEN_SESSION_EXPIRED', 'InboundEmail');
|
||||
}
|
||||
|
||||
$oauthConnectionName = $oauthConnection->name;
|
||||
|
||||
$hasAccess = $oauthConnection->ACLAccess('edit') ?? false;
|
||||
if ($hasAccess === true) {
|
||||
$message .= " <a href=\"index.php?module=ExternalOAuthConnection&action=$linkAction&record=$oAuthConnectionId\">$oauthConnectionName</a>.";
|
||||
} else {
|
||||
$message .= $oauthConnectionName . '.';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OAuthToken. Refresh if needed
|
||||
* @param string $oAuthConnectionId
|
||||
|
@ -8709,29 +8677,11 @@ eoq;
|
|||
require_once __DIR__ . '/../ExternalOAuthConnection/services/OAuthAuthorizationService.php';
|
||||
$oAuth = new OAuthAuthorizationService();
|
||||
|
||||
$oAuth->refreshExpiredOAuthToken($oAuthConnectionId);
|
||||
|
||||
/** @var ExternalOAuthConnection $oauthConnection */
|
||||
$oauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $oAuthConnectionId);
|
||||
$password = $oauthConnection->access_token;
|
||||
|
||||
$hasExpiredFeedback = $oAuth->hasConnectionTokenExpired($oauthConnection);
|
||||
$refreshToken = $hasExpiredFeedback['refreshToken'] ?? false;
|
||||
if ($refreshToken === true) {
|
||||
$refreshTokenFeedback = $oAuth->refreshConnectionToken($oauthConnection);
|
||||
|
||||
if ($refreshTokenFeedback['success'] === false) {
|
||||
$message = $this->getOAuthRefreshTokenErrorMessage(
|
||||
$refreshTokenFeedback['reLogin'],
|
||||
$oauthConnection,
|
||||
$oAuthConnectionId
|
||||
);
|
||||
displayAdminError($message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $oauthConnection->access_token;
|
||||
}
|
||||
|
||||
return $password;
|
||||
return $oauthConnection->access_token;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -167,7 +167,12 @@ if ($type === 'bounce') {
|
|||
if (!empty($_REQUEST['external_oauth_connection_id'])) {
|
||||
$externalOauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $_REQUEST['external_oauth_connection_id']);
|
||||
|
||||
if ($externalOauthConnection->type !== $focus->type) {
|
||||
$focusType = $focus->type ?? '';
|
||||
if ($focusType === 'bounce') {
|
||||
$focusType = 'group';
|
||||
}
|
||||
|
||||
if ($externalOauthConnection->type !== $focusType) {
|
||||
SugarApplication::appendErrorMessage($mod_strings['LBL_TYPE_DIFFERENT']);
|
||||
SugarApplication::redirect('index.php?module=InboundEmail&action=EditView&is_personal=1&type=personal');
|
||||
return;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
function authTypetoggleFields(type) {
|
||||
function authTypeToggleFields(type) {
|
||||
|
||||
var fieldsPerType = {
|
||||
'basic': {
|
||||
|
@ -81,10 +81,10 @@ function authTypetoggleFields(type) {
|
|||
|
||||
$(document).ready(function () {
|
||||
var type = inboundEmailFields.getValue('auth_type');
|
||||
authTypetoggleFields(type);
|
||||
authTypeToggleFields(type);
|
||||
|
||||
inboundEmailFields.getField$('auth_type').change(function () {
|
||||
type = inboundEmailFields.getValue('auth_type');
|
||||
authTypetoggleFields(type);
|
||||
authTypeToggleFields(type);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ if (!defined('sugarEntry') || !sugarEntry) {
|
|||
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
|
||||
*
|
||||
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2011 - 2018 SalesAgility Ltd.
|
||||
* Copyright (C) 2011 - 2024 SalesAgility Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
|
@ -119,17 +119,19 @@ class StandardField extends DynamicField
|
|||
$this->baseField = get_widget($field->type) ;
|
||||
foreach ($field->vardef_map as $property => $fmd_col) {
|
||||
if ($property == "action" || $property == "label_value" || $property == "label"
|
||||
|| ((substr((string) $property, 0, 3) == 'ext' && strlen((string) $property) == 4))
|
||||
|| ((str_starts_with((string)$property, 'ext') && strlen((string) $property) == 4))
|
||||
// possible bug here... $property is often the same as $fmd_col, but not always. Maybe we should also add:
|
||||
// || ((str_starts_with((string)$fmd_col, 'ext') && strlen((string) $fmd_col) == 4))
|
||||
// ... but a thorough analysis of the consequences of this would be required.
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bug 37043 - Avoid writing out vardef defintions that are the default value.
|
||||
|
||||
// Avoid writing out vardef definitions that are the default value, when possible.
|
||||
// Since isDefaultvalue() is quite limited, and doesn't handle all cases well,
|
||||
// sometimes we won't detect defaults and will store them anyway.
|
||||
if (isset($newDef[$property]) &&
|
||||
(
|
||||
(!isset($currdef[$property]) && !$this->isDefaultValue($property, $newDef[$property], $this->baseField))
|
||||
|| (isset($currdef[$property]) && $currdef[$property] != $newDef[$property])
|
||||
)
|
||||
!$this->isDefaultValue($property, $newDef[$property], $this->baseField)
|
||||
) {
|
||||
$this->custom_def[$property] =
|
||||
is_string($newDef[$property]) ? htmlspecialchars_decode($newDef[$property], ENT_QUOTES) : $newDef[$property];
|
||||
|
|
|
@ -262,7 +262,7 @@ class ActivitiesRelationship extends OneToManyRelationship
|
|||
'order' => 20 ,
|
||||
'sort_order' => 'desc' ,
|
||||
'sort_by' => 'date_modified' ,
|
||||
'title_key' => 'LBL_HISTORY' ,
|
||||
'title_key' => 'LBL_HISTORY_SUBPANEL_TITLE' ,
|
||||
'type' => 'collection' ,
|
||||
'subpanel_name' => 'history' , //this values is not associated with a physical file.
|
||||
'module' => 'History' ,
|
||||
|
|
|
@ -461,7 +461,7 @@ abstract class AbstractMetaDataImplementation
|
|||
// BEGIN ASSERTIONS
|
||||
if ($type != MB_BASEMETADATALOCATION && $type != MB_HISTORYMETADATALOCATION) {
|
||||
// just warn rather than die
|
||||
$GLOBALS ['log']->warning(
|
||||
$GLOBALS ['log']->warn(
|
||||
"UndeployedMetaDataImplementation->getFileName(): view type $type is not recognized"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -78,8 +78,7 @@ class TabController
|
|||
$trimmed_tabs = trim($tabs);
|
||||
//make sure serialized string is not empty
|
||||
if (!empty($trimmed_tabs)) {
|
||||
$tabs = base64_decode($tabs);
|
||||
$tabs = unserialize($tabs);
|
||||
$tabs = unserialize(base64_decode($tabs), ['allowed_classes' => false]);
|
||||
//Ensure modules saved in the prefences exist.
|
||||
foreach ($tabs as $id => $tab) {
|
||||
if (!in_array($tab, $moduleList)) {
|
||||
|
|
|
@ -66,6 +66,13 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
*/
|
||||
public $mail_smtpuser;
|
||||
|
||||
public $mail_smtpauth_req;
|
||||
public $mail_smtpssl;
|
||||
public $mail_smtpport;
|
||||
public $mail_smtpserver;
|
||||
public $mail_smtptype;
|
||||
public $mail_sendtype;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
@ -86,6 +93,9 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
*/
|
||||
public $reply_to_name;
|
||||
|
||||
public $auth_type = 'no_auth'; // 'no_auth', 'basic', 'oauth'
|
||||
public $external_oauth_connection_id = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
@ -113,11 +123,34 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
}
|
||||
$this->mail_smtppass = $this->mail_smtppass ? blowfishEncode(blowfishGetKey('OutBoundEmail'), $this->mail_smtppass) : null;
|
||||
|
||||
if ($this->auth_type === 'basic') {
|
||||
$this->mail_smtpauth_req = 1;
|
||||
$this->external_oauth_connection_id = '';
|
||||
}
|
||||
|
||||
if ($this->auth_type === 'no_auth') {
|
||||
$this->mail_smtppass = '';
|
||||
$this->mail_smtpauth_req = 0;
|
||||
$this->external_oauth_connection_id = '';
|
||||
}
|
||||
|
||||
if ($this->auth_type === 'oauth') {
|
||||
$this->mail_smtppass = '';
|
||||
$this->mail_smtpauth_req = 0;
|
||||
}
|
||||
|
||||
$this->smtp_from_name = trim($this->smtp_from_name);
|
||||
$this->smtp_from_addr = trim($this->smtp_from_addr);
|
||||
$this->mail_smtpserver = trim($this->mail_smtpserver);
|
||||
$this->mail_smtpuser = trim($this->mail_smtpuser);
|
||||
|
||||
if ($this->type === 'system') {
|
||||
/** @var Administration $admin */
|
||||
$admin = BeanFactory::newBean('Administration');
|
||||
$admin->saveSetting('notify', 'fromname', $this->smtp_from_name);
|
||||
$admin->saveSetting('notify', 'fromaddress', $this->smtp_from_addr);
|
||||
}
|
||||
|
||||
$results = parent::save($check_notify);
|
||||
return $results;
|
||||
}
|
||||
|
@ -134,6 +167,10 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
return null;
|
||||
}
|
||||
|
||||
if (isTrue($this->mail_smtpauth_req) && $this->auth_type === 'no_auth') {
|
||||
$this->auth_type = 'basic';
|
||||
}
|
||||
|
||||
$this->mail_smtppass = $this->mail_smtppass ? blowfishDecode(blowfishGetKey('OutBoundEmail'), $this->mail_smtppass) : null;
|
||||
return $results;
|
||||
}
|
||||
|
@ -262,7 +299,9 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
{
|
||||
global $current_user;
|
||||
|
||||
$isNotAllowAction = $this->isNotAllowedAction($view);
|
||||
$view = $view ?? '';
|
||||
|
||||
$isNotAllowAction = $this->isNotAllowedAction($view ?? '');
|
||||
if ($isNotAllowAction === true) {
|
||||
return false;
|
||||
}
|
||||
|
@ -406,6 +445,7 @@ HTML;
|
|||
$adminNotifyFromAddress = $admin->settings['notify_fromaddress'];
|
||||
isValidEmailAddress($adminNotifyFromAddress);
|
||||
$adminNotifyFromName = $admin->settings['notify_fromname'];
|
||||
$record = $_REQUEST['record'] ?? '';
|
||||
$html = <<<HTML
|
||||
<input id="sendTestOutboundEmailSettingsBtn" type="button" class="button" value="{$APP['LBL_EMAIL_TEST_OUTBOUND_SETTINGS']}" onclick="testOutboundSettings();">
|
||||
<script type="text/javascript" src="cache/include/javascript/sugar_grp_yui_widgets.js"></script>
|
||||
|
@ -431,6 +471,15 @@ HTML;
|
|||
};
|
||||
|
||||
function testOutboundSettingsDialog() {
|
||||
|
||||
var notifyFromAddress = document.getElementById('smtp_from_addr') && document.getElementById('smtp_from_addr').value;
|
||||
var notifyFromName = document.getElementById('smtp_from_name') && document.getElementById('smtp_from_name').value;
|
||||
|
||||
if (!notifyFromAddress || !notifyFromName) {
|
||||
overlay("{$APP['ERR_INVALID_REQUIRED_FIELDS']}", "{$APP['LBL_EMAIL_SETTINGS_FROM_ADDR_NOT_SET']}", 'alert');
|
||||
return;
|
||||
}
|
||||
|
||||
// lazy load dialogue
|
||||
if(!EmailMan.testOutboundDialog) {
|
||||
EmailMan.testOutboundDialog = new YAHOO.widget.Dialog("testOutboundDialog", {
|
||||
|
@ -507,7 +556,9 @@ HTML;
|
|||
var smtpServer = document.getElementById('mail_smtpserver').value;
|
||||
var smtpPort = document.getElementById('mail_smtpport').value;
|
||||
var smtpssl = document.getElementById('mail_smtpssl').value;
|
||||
var mailsmtpauthreq = document.getElementById('mail_smtpauth_req');
|
||||
var authType = document.getElementById('auth_type').value || 'no_auth';
|
||||
var externalOauthConnectionId = document.getElementById('external_oauth_connection_id').value || '';
|
||||
var smtpPass = trim(document.getElementById('mail_smtppass').value);
|
||||
var mail_sendtype = 'SMTP';
|
||||
var adminNotifyFromAddress = document.getElementById('smtp_from_addr').value ? document.getElementById('smtp_from_addr').value :'$adminNotifyFromName';
|
||||
var adminNotifyFromName = document.getElementById('smtp_from_name').value ? document.getElementById('smtp_from_name').value : '$adminNotifyFromAddress';
|
||||
|
@ -516,9 +567,12 @@ HTML;
|
|||
'mail_sendtype=' + mail_sendtype + '&' +
|
||||
'mail_smtpserver=' + smtpServer + "&" +
|
||||
"mail_smtpport=" + smtpPort + "&mail_smtpssl=" + smtpssl + "&" +
|
||||
"mail_smtpauth_req=" + mailsmtpauthreq.checked + "&" +
|
||||
"mail_auth_type=" + authType + "&" +
|
||||
"mail_external_oauth_connection_id=" + externalOauthConnectionId + "&" +
|
||||
"mail_smtpauth_req=" + (authType === 'basic' ? 1 : 0) + "&" +
|
||||
"mail_smtpuser=" + trim(document.getElementById('mail_smtpuser').value) + "&" +
|
||||
"mail_smtppass=" + trim(document.getElementById('mail_smtppass').value) + "&" +
|
||||
"mail_smtppass=" + smtpPass + "&" +
|
||||
"record=" + '$record' + "&" +
|
||||
"outboundtest_to_address=" + toAddress + '&' +
|
||||
'outboundtest_from_address=' + adminNotifyFromAddress + '&' +
|
||||
'mail_from_name=' + adminNotifyFromName;
|
||||
|
|
|
@ -51,6 +51,32 @@ class OutboundEmailAccountsController extends SugarController
|
|||
$this->bean->type = $type;
|
||||
}
|
||||
|
||||
if (empty($this->bean) && $type === 'system' && !is_admin($GLOBALS['current_user'])) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'noaccess';
|
||||
return;
|
||||
}
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemEmail();
|
||||
if (empty($this->bean->id) && $type === 'system' && $oe !== null) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'errors';
|
||||
$this->errors = [
|
||||
translate('LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS', 'OutboundEmailAccounts'),
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'system' && $oe !== null && $oe->id !== $this->bean->id) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'errors';
|
||||
$this->errors = [
|
||||
translate('LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS', 'OutboundEmailAccounts'),
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($_REQUEST['record']) && $type === 'user') {
|
||||
$this->hasAccess = true;
|
||||
return;
|
||||
|
@ -62,7 +88,7 @@ class OutboundEmailAccountsController extends SugarController
|
|||
}
|
||||
|
||||
public function action_save() {
|
||||
global $current_user;
|
||||
global $current_user, $mod_strings;
|
||||
$isNewRecord = (empty($this->bean->id) || $this->bean->new_with_id);
|
||||
|
||||
$this->bean->mail_sendtype = 'SMTP';
|
||||
|
@ -84,6 +110,14 @@ class OutboundEmailAccountsController extends SugarController
|
|||
}
|
||||
}
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemEmail();
|
||||
$type = $this->bean->type;
|
||||
|
||||
if ($type === 'user'){
|
||||
$type = 'personal';
|
||||
}
|
||||
|
||||
if ($isNewRecord && empty($this->bean->user_id)) {
|
||||
$this->bean->user_id = $current_user->id;
|
||||
$this->bean->assigned_user_id = $current_user->id;
|
||||
|
@ -93,6 +127,34 @@ class OutboundEmailAccountsController extends SugarController
|
|||
$this->bean->assigned_user_id = $this->bean->user_id;
|
||||
}
|
||||
|
||||
$authType = $_REQUEST['auth_type'] ?? '';
|
||||
|
||||
$oauth = null;
|
||||
if ($authType === 'oauth' || ($_REQUEST['auth_type'] ?? '') === 'oauth') {
|
||||
$oauth = BeanFactory::getBean('ExternalOAuthConnection', $_REQUEST['external_oauth_connection_id']);
|
||||
}
|
||||
|
||||
if ($type === 'system' && $oe !== null && $oe->id !== $this->bean->id) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'errors';
|
||||
$this->errors = [
|
||||
translate('LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS', 'OutboundEmailAccounts'),
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'system' && $oauth !== null && $oauth->type !== 'group') {
|
||||
SugarApplication::appendErrorMessage($mod_strings['LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_IS_NOT_GROUP']);
|
||||
SugarApplication::redirect('index.php?module=OutboundEmailAccounts&action=DetailView&record=' . $this->bean->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type !== 'system' && $oauth !== null && $oauth->type !== $type) {
|
||||
SugarApplication::appendErrorMessage($mod_strings['LBL_ERROR_OUTBOUND_EMAIL_CONNECTION_TYPE_MISMATCH']);
|
||||
SugarApplication::redirect('index.php?module=OutboundEmailAccounts&action=DetailView&record=' . $this->bean->id);
|
||||
return;
|
||||
}
|
||||
|
||||
parent::action_save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SUITECRM, SUITECRM DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
function authTypeToggleFields(type) {
|
||||
|
||||
var fieldsPerType = {
|
||||
'basic': {
|
||||
'mail_smtppass': true,
|
||||
'external_oauth_connection_name': false,
|
||||
},
|
||||
'no_auth': {
|
||||
'mail_smtppass': false,
|
||||
'external_oauth_connection_name': false,
|
||||
},
|
||||
'oauth': {
|
||||
'mail_smtppass': false,
|
||||
'external_oauth_connection_name': true,
|
||||
},
|
||||
};
|
||||
|
||||
var fieldType = {
|
||||
'mail_smtppass': 'password',
|
||||
'external_oauth_connection_name': 'relate',
|
||||
};
|
||||
|
||||
var fieldDisplay = fieldsPerType[type] || fieldsPerType.personal;
|
||||
|
||||
Object.keys(fieldDisplay).forEach(function (fieldKey) {
|
||||
var display = fieldDisplay[fieldKey];
|
||||
var method = 'show';
|
||||
var required = true;
|
||||
|
||||
if (!display) {
|
||||
method = 'hide';
|
||||
outboundEmailFields.setValue(fieldKey, '');
|
||||
required = false;
|
||||
}
|
||||
|
||||
var isValue = outboundEmailFields.getData(fieldKey, 'is-value-set');
|
||||
if (isValue === true) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
outboundEmailFields.setRequired(fieldKey, fieldType[fieldKey], 'EditView', required);
|
||||
outboundEmailFields[method](fieldKey);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
var type = outboundEmailFields.getValue('auth_type');
|
||||
authTypeToggleFields(type);
|
||||
|
||||
outboundEmailFields.getField$('auth_type').change(function () {
|
||||
type = outboundEmailFields.getValue('auth_type');
|
||||
authTypeToggleFields(type);
|
||||
});
|
||||
});
|
|
@ -38,144 +38,256 @@
|
|||
*/
|
||||
var outboundEmailFields = function () {
|
||||
|
||||
var getDefaultFieldGetter = function () {
|
||||
return function (field$) {
|
||||
return (field$ && field$.val()) || '';
|
||||
var requiredLabelTemplate = '<span class="required">*</span>';
|
||||
var validationMessageTemplate = '<div class="required validation-message">Missing required field: $FIELD_NAME</div>';
|
||||
|
||||
var getValidationDefinition = function (formName, field) {
|
||||
if (validate[formName]) {
|
||||
for (i = 0; i < validate[formName].length; i++) {
|
||||
if (validate[formName][i][nameIndex] == field) {
|
||||
return validate[formName][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
};
|
||||
|
||||
var getDefaultFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
var configureValidation = function (formName, field, required) {
|
||||
|
||||
field$.val(value);
|
||||
field$.change();
|
||||
var definition = getValidationDefinition(formName, field);
|
||||
|
||||
if (!definition) {
|
||||
return;
|
||||
}
|
||||
var isRequired = true;
|
||||
|
||||
if (!required) {
|
||||
isRequired = false;
|
||||
}
|
||||
|
||||
definition[requiredIndex] = isRequired;
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
fields: {
|
||||
'record': {
|
||||
type: 'varchar',
|
||||
var addRequiredIndicator = function ($label) {
|
||||
var $indicator = $label.find('.required');
|
||||
|
||||
if ($indicator.length < 1) {
|
||||
$label.append($(requiredLabelTemplate));
|
||||
}
|
||||
};
|
||||
|
||||
var removeRequiredIndicator = function ($label) {
|
||||
var $indicator = $label.find('.required');
|
||||
|
||||
if ($indicator.length > 0) {
|
||||
$indicator.remove();
|
||||
}
|
||||
};
|
||||
|
||||
var getDefaultFieldGetter = function () {
|
||||
return function (field$) {
|
||||
return (field$ && field$.val()) || '';
|
||||
};
|
||||
};
|
||||
|
||||
var getDefaultFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.val(value);
|
||||
field$.change();
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
fields: {
|
||||
'record': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'mail_smtpssl': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtppass': {
|
||||
type: 'varchar',
|
||||
},
|
||||
'owner_name': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'type': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpport': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpauth_req': {
|
||||
type: 'checkbox'
|
||||
},
|
||||
'auth_type': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'external_oauth_connection_name': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'external_oauth_connection_id': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
getters: {
|
||||
default: getDefaultFieldGetter(),
|
||||
varchar: getDefaultFieldGetter(),
|
||||
checkbox: function (field$) {
|
||||
return (field$ && field$.prop('checked')) || false;
|
||||
}
|
||||
},
|
||||
|
||||
setters: {
|
||||
default: getDefaultFieldSetter(),
|
||||
varchar: getDefaultFieldSetter(),
|
||||
checkbox: function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.prop('checked', !!value);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function (field, value) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var setter = this.getValueSetter(field);
|
||||
if (!setter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return setter(field$, value);
|
||||
},
|
||||
|
||||
getValue: function (field) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var getter = this.getValueGetter(field);
|
||||
if (!getter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getter(field$);
|
||||
},
|
||||
|
||||
getData: function (field, dataKey) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return field$.data(dataKey);
|
||||
},
|
||||
|
||||
hide: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.hide();
|
||||
},
|
||||
|
||||
show: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.show();
|
||||
},
|
||||
|
||||
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'mail_smtpssl': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'owner_name': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'type': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpport': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpauth_req': {
|
||||
type: 'checkbox'
|
||||
},
|
||||
},
|
||||
var handler = (this.fields[field] && this.fields[field].getField$) || null;
|
||||
|
||||
getters: {
|
||||
default: getDefaultFieldGetter(),
|
||||
varchar: getDefaultFieldGetter(),
|
||||
checkbox: function (field$) {
|
||||
return (field$ && field$.prop('checked')) || false;
|
||||
}
|
||||
},
|
||||
if (handler) {
|
||||
return handler(field);
|
||||
}
|
||||
|
||||
setters: {
|
||||
default: getDefaultFieldSetter(),
|
||||
varchar: getDefaultFieldSetter(),
|
||||
checkbox: function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
return $('#' + field) || null;
|
||||
},
|
||||
|
||||
field$.prop('checked', !!value);
|
||||
}
|
||||
},
|
||||
getFieldCell$: function (field) {
|
||||
return $('[data-field="' + field + '"]') || null;
|
||||
},
|
||||
|
||||
setValue: function (field, value) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
getFieldType: function (field) {
|
||||
return (this.fields[field] && this.fields[field].type) || 'varchar';
|
||||
},
|
||||
|
||||
var setter = this.getValueSetter(field);
|
||||
if (!setter) {
|
||||
return null;
|
||||
}
|
||||
getValueGetter: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].getter) || null;
|
||||
|
||||
return setter(field$, value);
|
||||
},
|
||||
if (handler) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
getValue: function (field) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
var type = this.getFieldType(field);
|
||||
return this.getters[type] || this.getters['default'];
|
||||
},
|
||||
|
||||
var getter = this.getValueGetter(field);
|
||||
if (!getter) {
|
||||
return null;
|
||||
}
|
||||
getValueSetter: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].setter) || null;
|
||||
|
||||
return getter(field$);
|
||||
},
|
||||
if (handler) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
hide: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
var type = this.getFieldType(field);
|
||||
return this.setters[type] || this.setters['default'];
|
||||
},
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
setRequired: function (field, fieldType, formName, required) {
|
||||
|
||||
field$.hide();
|
||||
},
|
||||
var $editView = $('#EditView');
|
||||
if (!$editView || !$editView.length) {
|
||||
return;
|
||||
}
|
||||
configureValidation(this.formName, this.name, required);
|
||||
|
||||
show: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
this.setRequiredIndicator(field, required);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
if (required) {
|
||||
addToValidate(formName, field, fieldType, true, SUGAR.language.get('OutboundEmailAccounts', "LBL_" + field.toUpperCase()));
|
||||
} else {
|
||||
removeFromValidate(formName, field);
|
||||
}
|
||||
|
||||
field$.show();
|
||||
},
|
||||
},
|
||||
|
||||
setRequiredIndicator: function (field, required) {
|
||||
var $label = this.getFieldCell$(field).find('.label');
|
||||
if (required) {
|
||||
addRequiredIndicator($label);
|
||||
} else {
|
||||
removeRequiredIndicator($label);
|
||||
}
|
||||
},
|
||||
|
||||
getField$: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].getField$) || null;
|
||||
|
||||
if (handler) {
|
||||
return handler(field);
|
||||
}
|
||||
|
||||
return $('#' + field) || null;
|
||||
},
|
||||
|
||||
getFieldCell$: function (field) {
|
||||
return $('[data-field="' + field + '"]') || null;
|
||||
},
|
||||
|
||||
getFieldType: function (field) {
|
||||
return (this.fields[field] && this.fields[field].type) || 'varchar';
|
||||
},
|
||||
|
||||
getValueGetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.getters[type] || this.getters['default'];
|
||||
},
|
||||
|
||||
getValueSetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.setters[type] || this.setters['default'];
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
}();
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* SugarCRM Community Edition is a customer relationship management program developed by
|
||||
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
|
||||
*
|
||||
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2011 - 2022 SalesAgility Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
|
||||
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along with
|
||||
* this program; if not, see http://www.gnu.org/licenses or write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA.
|
||||
*
|
||||
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
|
||||
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "Powered by
|
||||
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
|
||||
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
|
||||
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
|
||||
*/
|
||||
function toggleAuthFields(authEnabled) {
|
||||
var status = 'disabled';
|
||||
if (authEnabled) {
|
||||
status = 'enabled';
|
||||
}
|
||||
|
||||
var fieldsPerStatus = {
|
||||
'enabled': {
|
||||
'mail_smtppass': true,
|
||||
},
|
||||
'disabled': {
|
||||
'mail_smtppass': false,
|
||||
},
|
||||
};
|
||||
|
||||
var fieldDisplay = fieldsPerStatus[status] || fieldsPerStatus.disabled;
|
||||
|
||||
Object.keys(fieldDisplay).forEach(function (fieldKey) {
|
||||
var display = fieldDisplay[fieldKey];
|
||||
var method = 'show';
|
||||
if(!display) {
|
||||
method = 'hide';
|
||||
}
|
||||
|
||||
outboundEmailFields[method](fieldKey);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
var authEnabled = outboundEmailFields.getValue('mail_smtpauth_req');
|
||||
toggleAuthFields(authEnabled);
|
||||
|
||||
$('#mail_smtpauth_req').change(function () {
|
||||
var authEnabled = outboundEmailFields.getValue('mail_smtpauth_req');
|
||||
toggleAuthFields(authEnabled);
|
||||
});
|
||||
});
|
||||
|
|
@ -118,5 +118,14 @@ $mod_strings = array(
|
|||
'LBL_OWNER' => 'Owner',
|
||||
'LBL_OWNER_NAME' => 'Owner',
|
||||
|
||||
'LNK_EXTERNAL_OAUTH_CONNECTIONS' => 'External OAuth Connections'
|
||||
'LBL_AUTH_TYPE' => 'Auth Type',
|
||||
|
||||
'LBL_EXTERNAL_OAUTH_CONNECTION' => 'External OAuth Connection',
|
||||
'LBL_EXTERNAL_OAUTH_CONNECTION_ID' => 'External OAuth Connection id',
|
||||
'LBL_EXTERNAL_OAUTH_CONNECTION_NAME' => 'External OAuth Connection',
|
||||
'LNK_EXTERNAL_OAUTH_CONNECTIONS' => 'External OAuth Connections',
|
||||
|
||||
'LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS' => 'System Outbound Email Account already exists. Please remove it before creating a new one.',
|
||||
'LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_IS_NOT_GROUP' => 'When configuring the System Outbound account using OAuth, you must select a Group-Type External Oauth Connection',
|
||||
'LBL_ERROR_OUTBOUND_EMAIL_CONNECTION_TYPE_MISMATCH' => 'When configuring the Outbound account using OAuth, you must select a External Oauth Connection the same type as the Outbound Email Account (Group or Personal)',
|
||||
);
|
||||
|
|
|
@ -37,7 +37,7 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
files="modules/OutboundEmailAccounts/js/fields.js,
|
||||
modules/OutboundEmailAccounts/js/owner_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/panel_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/smtp_auth_toggle.js"}
|
||||
modules/OutboundEmailAccounts/js/auth_type_fields_toggle.js"}
|
||||
</script>
|
||||
',
|
||||
],
|
||||
|
@ -57,17 +57,21 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
],
|
||||
'lbl_connection_configuration' => [
|
||||
[
|
||||
'mail_smtpserver',
|
||||
'mail_smtpauth_req',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
'auth_type',
|
||||
'mail_smtpuser',
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
'mail_smtpserver',
|
||||
'external_oauth_connection_name',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
'',
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
''
|
||||
],
|
||||
],
|
||||
'lbl_outbound_configuration' => [
|
||||
[
|
||||
|
|
|
@ -40,7 +40,7 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
modules/OutboundEmailAccounts/js/ssl_port_set.js,
|
||||
modules/OutboundEmailAccounts/js/panel_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/owner_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/smtp_auth_toggle.js"}
|
||||
modules/OutboundEmailAccounts/js/auth_type_fields_toggle.js"}
|
||||
</script>
|
||||
',
|
||||
],
|
||||
|
@ -60,17 +60,26 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
],
|
||||
'lbl_connection_configuration' => [
|
||||
[
|
||||
'mail_smtpserver',
|
||||
'mail_smtpauth_req',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
'auth_type',
|
||||
'mail_smtpuser',
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
'mail_smtpserver',
|
||||
'mail_smtppass',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
[
|
||||
'name' => 'external_oauth_connection_name',
|
||||
'displayParams' => [
|
||||
'initial_filter' => '{if $fields.type.value === "system"}&type="+"group"+"{/if}',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
'',
|
||||
],
|
||||
[
|
||||
[
|
||||
'name' => 'sent_test_email_btn',
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue