From c4e7cc95110fbf1f8748bfa253c098e2a1d8c0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20Cesar=20Laura=20Avenda=C3=B1o?= Date: Fri, 26 Nov 2021 15:58:35 +0000 Subject: [PATCH 1/9] PMCORE-3467 --- gulliver/system/class.bootstrap.php | 11 + .../engine/methods/login/authentication.php | 7 +- .../methods/login/authenticationSso.php | 4 +- workflow/engine/methods/login/login.php | 37 +- workflow/engine/methods/login/sysLogin.php | 38 +- .../src/ProcessMaker/BusinessModel/Light.php | 4 +- .../engine/src/ProcessMaker/Core/System.php | 47 ++ .../ProcessMaker/Services/OAuth2/Server.php | 4 +- workflow/public_html/bootstrap.php | 736 ------------------ workflow/public_html/pmGmail/sso.php | 3 +- workflow/public_html/sysGeneric.php | 14 +- 11 files changed, 96 insertions(+), 809 deletions(-) delete mode 100644 workflow/public_html/bootstrap.php diff --git a/gulliver/system/class.bootstrap.php b/gulliver/system/class.bootstrap.php index f2250c7c9..a462dba73 100644 --- a/gulliver/system/class.bootstrap.php +++ b/gulliver/system/class.bootstrap.php @@ -2788,4 +2788,15 @@ class Bootstrap ]; self::registerMonolog($channel, $level, $message, $context); } + + /** + * Build the options for a cookie, according to the system configuration and values optionally sent to this method + * + * @param array $options + * @return array + */ + public static function buildCookieOptions(array $options = []) + { + return System::buildCookieOptions($options); + } } diff --git a/workflow/engine/methods/login/authentication.php b/workflow/engine/methods/login/authentication.php index 12e72498b..bce846d57 100644 --- a/workflow/engine/methods/login/authentication.php +++ b/workflow/engine/methods/login/authentication.php @@ -15,8 +15,9 @@ try { $urlLogin = (substr(SYS_SKIN, 0, 2) !== 'ux')? 'login' : '../main/login'; } + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60)]); if (!$RBAC->singleSignOn) { - setcookie("singleSignOn", '0', time() + (24 * 60 * 60), '/', '', G::is_https()); + setcookie('singleSignOn', '0', $cookieOptions); if (!isset($_POST['form']) ) { G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error'); G::header('Location: login'); @@ -181,7 +182,7 @@ try { EnterpriseClass::enterpriseSystemUpdate($loginInfo); initUserSession($uid, $usr); } else { - setcookie("singleSignOn", '1', time() + (24 * 60 * 60), '/', '', G::is_https()); + setcookie('singleSignOn', '1', $cookieOptions); $uid = $RBAC->userObj->fields['USR_UID']; $usr = $RBAC->userObj->fields['USR_USERNAME']; initUserSession($uid, $usr); @@ -416,7 +417,7 @@ try { $configS = System::getSystemConfiguration('', '', config("system.workspace")); $activeSession = isset($configS['session_block']) ? !(int)$configS['session_block']:true; if ($activeSession){ - setcookie("PM-TabPrimary", 101010010, time() + (24 * 60 * 60), '/', '', G::is_https()); + setcookie('PM-TabPrimary', 101010010, $cookieOptions); } // Update the User's last login date diff --git a/workflow/engine/methods/login/authenticationSso.php b/workflow/engine/methods/login/authenticationSso.php index e1750c3f8..b4237b2db 100644 --- a/workflow/engine/methods/login/authenticationSso.php +++ b/workflow/engine/methods/login/authenticationSso.php @@ -81,8 +81,8 @@ try { } } /*----------------------------------********---------------------------------*/ - - setcookie('singleSignOn', '1', time() + (24 * 60 * 60), '/', '', G::is_https()); + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60)]); + setcookie('singleSignOn', '1', $cookieOptions); initUserSession( $_SESSION['__USER_LOGGED_SSO__'], diff --git a/workflow/engine/methods/login/login.php b/workflow/engine/methods/login/login.php index fe11e77c7..0fc9612a2 100644 --- a/workflow/engine/methods/login/login.php +++ b/workflow/engine/methods/login/login.php @@ -1,27 +1,4 @@ . - * - * For more information, contact Colosa Inc, 2566 Le Jeune Rd., - * Coral Gables, FL, 33134, USA, or email info@colosa.com. - * - */ use ProcessMaker\Core\System; use ProcessMaker\Plugins\PluginRegistry; @@ -182,7 +159,11 @@ if (isset($_SESSION['USER_LOGGED'])) { session_start(); session_regenerate_id(); -setcookie("workspaceSkin", SYS_SKIN, time() + (24 * 60 * 60), "/sys" . config("system.workspace"), null, G::is_https(), true); +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'httponly' => true]); +setcookie(session_name(), session_id(), $cookieOptions); + +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'path' => '/sys' . config('system.workspace'), 'httponly' => true]); +setcookie('workspaceSkin', SYS_SKIN, $cookieOptions); if (strlen($msg) > 0) { $_SESSION['G_MESSAGE'] = $msg; @@ -319,14 +300,16 @@ $flagForgotPassword = isset($oConf->aConfig['login_enableForgotPassword']) ? $oConf->aConfig['login_enableForgotPassword'] : 'off'; -setcookie('PM-Warning', trim(G::LoadTranslation('ID_BLOCKER_MSG'), '*'), time() + (24 * 60 * 60), SYS_URI, '', G::is_https()); +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'path' => SYS_URI]); +setcookie('PM-Warning', trim(G::LoadTranslation('ID_BLOCKER_MSG'), '*'), $cookieOptions); $configS = System::getSystemConfiguration('', '', config("system.workspace")); $activeSession = isset($configS['session_block']) ? !(int)$configS['session_block'] : true; +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60)]); if ($activeSession) { - setcookie("PM-TabPrimary", 101010010, time() + (24 * 60 * 60), '/', '', G::is_https()); + setcookie('PM-TabPrimary', 101010010, $cookieOptions); } else { - setcookie("PM-TabPrimary", uniqid(), time() + (24 * 60 * 60), '/', '', G::is_https()); + setcookie('PM-TabPrimary', uniqid(), $cookieOptions); } $oHeadPublisher->addScriptCode("var flagForgotPassword = '$flagForgotPassword';"); diff --git a/workflow/engine/methods/login/sysLogin.php b/workflow/engine/methods/login/sysLogin.php index a51dd038e..59416d622 100644 --- a/workflow/engine/methods/login/sysLogin.php +++ b/workflow/engine/methods/login/sysLogin.php @@ -1,28 +1,5 @@ . - * - * For more information, contact Colosa Inc, 2566 Le Jeune Rd., - * Coral Gables, FL, 33134, USA, or email info@colosa.com. - * - */ -/*----------------------------------********---------------------------------*/ + //Browser Compatibility $browserSupported = G::checkBrowserCompatibility(); if ($browserSupported==false) { @@ -50,11 +27,14 @@ if (!empty($_SESSION['G_MESSAGE_TYPE'])) { } //Initialize session - @session_destroy(); session_start(); session_regenerate_id(); +//Set options for PHP session cookie +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'httponly' => true]); +setcookie(session_name(), session_id(), $cookieOptions); + //Restore session variables $_SESSION = array_merge($_SESSION, $arraySession); @@ -169,8 +149,12 @@ switch (WS_IN_LOGIN) { $fileLogin = 'login/sysLogin'; break; } -setcookie("PM-Warning", trim(G::LoadTranslation('ID_BLOCKER_MSG'), '*'), time() + (24 * 60 * 60), SYS_CURRENT_URI, '', G::is_https()); -setcookie("PM-TabPrimary", uniqid(), time() + (24 * 60 * 60), '/', '', G::is_https()); +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'path' => SYS_CURRENT_URI]); +setcookie('PM-Warning', trim(G::LoadTranslation('ID_BLOCKER_MSG'), '*'), $cookieOptions); + +$cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60)]); +setcookie('PM-TabPrimary', uniqid(), $cookieOptions); + $oHeadPublisher = headPublisher::getSingleton(); $oHeadPublisher->addScriptFile('/jscore/src/PM.js'); $oHeadPublisher->addScriptFile('/jscore/src/Sessions.js'); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Light.php b/workflow/engine/src/ProcessMaker/BusinessModel/Light.php index b6cdbf47a..9d67e883c 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Light.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Light.php @@ -874,8 +874,8 @@ class Light session_start(); session_regenerate_id(); - setcookie("workspaceSkin", SYS_SKIN, time() + (24 * 60 * 60), "/sys" . config("system.workspace"), null, G::is_https(), - true); + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'path' => '/sys' . config('system.workspace'), 'httponly' => true]); + setcookie('workspaceSkin', SYS_SKIN, $cookieOptions); if (strlen($msg) > 0) { $_SESSION['G_MESSAGE'] = $msg; diff --git a/workflow/engine/src/ProcessMaker/Core/System.php b/workflow/engine/src/ProcessMaker/Core/System.php index 949936ec2..a30cbefd5 100644 --- a/workflow/engine/src/ProcessMaker/Core/System.php +++ b/workflow/engine/src/ProcessMaker/Core/System.php @@ -86,6 +86,21 @@ class System 'disable_task_manager_routing_async' => '0', 'on_one_server_enable' => 0, 'at_risk_delegation_max_time' => '0.2', + 'samesite_cookie_setting' => '' + ]; + + public static $cookieDefaultOptions = [ + 'expires' => 0, + 'path' => '/', + 'domain' => '', + 'secure' => false, + 'httponly' => false, + 'samesite' => '' + ]; + + public static $cookieSameSiteValues = [ + 'Lax', + 'Strict' ]; /** @@ -1252,6 +1267,13 @@ class System $config['at_risk_delegation_max_time'] = self::$defaultConfig['at_risk_delegation_max_time']; } + $value = ucfirst(strtolower($config['samesite_cookie_setting'])); + if (in_array($value, self::$cookieSameSiteValues)) { + $config['samesite_cookie_setting'] = $value; + } else { + $config['samesite_cookie_setting'] = ''; + } + return $config; } @@ -1778,4 +1800,29 @@ class System $parseDsn["pass"] = urldecode($parseDsn["pass"]); return $parseDsn; } + + /** + * Build the options for a cookie, according to the system configuration and values optionally sent to this method + * + * @param array $options + * @return array + */ + public static function buildCookieOptions(array $options = []) + { + // Get system values + $cookieOptions = self::$cookieDefaultOptions; + $systemConfiguration = self::getSystemConfiguration(); + + // Always set "secure" option according to the server protocol + $cookieOptions['secure'] = G::is_https(); + + // Set the "samesite" option according to the system configuration + $cookieOptions['samesite'] = $systemConfiguration['samesite_cookie_setting']; + + // Overrides the cookie options with the values sent to the method + $cookieOptions = array_merge($cookieOptions, $options); + + // Return the cookie options + return $cookieOptions; + } } diff --git a/workflow/engine/src/ProcessMaker/Services/OAuth2/Server.php b/workflow/engine/src/ProcessMaker/Services/OAuth2/Server.php index f0c256dfe..5ea9ebffd 100644 --- a/workflow/engine/src/ProcessMaker/Services/OAuth2/Server.php +++ b/workflow/engine/src/ProcessMaker/Services/OAuth2/Server.php @@ -1,6 +1,7 @@ getSessionName(), $_COOKIE[$session->getSessionName()], time() + $lifetime, "/", null, false, true); + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + $lifetime, 'secure' => false, 'httponly' => true]); + setcookie($session->getSessionName(), $_COOKIE[$session->getSessionName()], $cookieOptions); } } diff --git a/workflow/public_html/bootstrap.php b/workflow/public_html/bootstrap.php deleted file mode 100644 index cf58c3128..000000000 --- a/workflow/public_html/bootstrap.php +++ /dev/null @@ -1,736 +0,0 @@ -validateInput($config['display_errors']); -$config['error_reporting'] = $filter->validateInput($config['error_reporting']); -$config['wsdl_cache'] = $filter->validateInput($config['wsdl_cache'], 'int'); -$config['time_zone'] = $filter->validateInput($config['time_zone']); -// Do not change any of these settings directly, use env.ini instead -ini_set('display_errors', $filter->validateInput($config['display_errors'])); -ini_set('error_reporting', $filter->validateInput($config['error_reporting'])); -ini_set('short_open_tag', 'On'); -ini_set('default_charset', "UTF-8"); -ini_set('soap.wsdl_cache_enabled', $config['wsdl_cache']); -ini_set('date.timezone', - (isset($_SESSION['__SYSTEM_UTC_TIME_ZONE__']) && $_SESSION['__SYSTEM_UTC_TIME_ZONE__']) ? 'UTC' : $config['time_zone']); //Set Time Zone - -define('DEBUG_SQL_LOG', $config['debug_sql']); -define('DEBUG_TIME_LOG', $config['debug_time']); -define('DEBUG_CALENDAR_LOG', $config['debug_calendar']); -define('MEMCACHED_ENABLED', $config['memcached']); -define('MEMCACHED_SERVER', $config['memcached_server']); -define('TIME_ZONE', ini_get('date.timezone')); - -// IIS Compatibility, SERVER_ADDR doesn't exist on that env, so we need to define it. -$_SERVER['SERVER_ADDR'] = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['SERVER_NAME']; - -//to do: make different environments. sys - -define('ERROR_SHOW_SOURCE_CODE', - true); // enable ERROR_SHOW_SOURCE_CODE to display the source code for any WARNING OR NOTICE -//define ( 'ERROR_LOG_NOTICE_ERROR', true ); //enable ERROR_LOG_NOTICE_ERROR to log Notices messages in default apache log - -//check if it is a installation instance -if (!defined('PATH_C')) { - // is a intallation instance, so we need to define PATH_C and PATH_LANGUAGECONT constants temporarily - define('PATH_C', (rtrim(G::sys_get_temp_dir(), PATH_SEP) . PATH_SEP)); - define('PATH_LANGUAGECONT', PATH_HOME . 'engine/content/languages/'); -} - -// defining Virtual URLs -$virtualURITable = []; -$virtualURITable['/plugin/(*)'] = 'plugin'; -$virtualURITable['/(sys*)/(*.js)'] = 'jsMethod'; -$virtualURITable['/js/(*)'] = PATH_GULLIVER_HOME . 'js/'; -$virtualURITable['/jscore/(*)'] = PATH_CORE . 'js/'; - -if (defined('PATH_C')) { - $virtualURITable['/jsform/(*.js)'] = PATH_C . 'xmlform/'; - $virtualURITable['/extjs/(*)'] = PATH_C . 'ExtJs/'; -} - -$virtualURITable['/htmlarea/(*)'] = PATH_THIRDPARTY . 'htmlarea/'; -$virtualURITable['/sys[a-zA-Z][a-zA-Z0-9]{0,}()/'] = 'sysNamed'; -$virtualURITable['/(sys*)'] = false; -$virtualURITable['/errors/(*)'] = PATH_GULLIVER_HOME . 'methods/errors/'; -$virtualURITable['/gulliver/(*)'] = PATH_GULLIVER_HOME . 'methods/'; -$virtualURITable['/controls/(*)'] = PATH_GULLIVER_HOME . 'methods/controls/'; -$virtualURITable['/html2ps_pdf/(*)'] = PATH_THIRDPARTY . 'html2ps_pdf/'; -$virtualURITable['/images/'] = 'errorFile'; -$virtualURITable['/skins/'] = 'errorFile'; -$virtualURITable['/files/'] = 'errorFile'; -$virtualURITable['/[a-zA-Z][a-zA-Z0-9]{0,}()'] = 'sysUnnamed'; -$virtualURITable['/rest/(*)'] = 'rest-service'; -$virtualURITable['/update/(*)'] = PATH_GULLIVER_HOME . 'methods/update/'; -$virtualURITable['/(*)'] = PATH_HTML; - -$isRestRequest = false; - -// Verify if we need to redirect or stream the file, if G:VirtualURI returns true means we are going to redirect the page -if (G::virtualURI($_SERVER['REQUEST_URI'], $virtualURITable, $realPath)) { - // review if the file requested belongs to public_html plugin - if (substr($realPath, 0, 6) == 'plugin') { - // Another way to get the path of Plugin public_html and stream the correspondent file, By JHL Jul 14, 08 - // TODO: $pathsQuery will be used? - $pathsQuery = ''; - // Get the query side - // Did we use this variable $pathsQuery for something?? - $forQuery = explode("?", $realPath); - if (isset($forQuery[1])) { - $pathsQuery = $forQuery[1]; - } - - //Get that path in array - $paths = explode(PATH_SEP, $forQuery[0]); - //remove the "plugin" word from - $paths[0] = substr($paths[0], 6); - //Get the Plugin Folder, always the first element - $pluginFolder = array_shift($paths); - //The other parts are the realpath into public_html (no matter how many elements) - $filePath = implode(PATH_SEP, $paths); - $pluginFilename = PATH_PLUGINS . $pluginFolder . PATH_SEP . 'public_html' . PATH_SEP . $filePath; - - if (file_exists($pluginFilename)) { - G::streamFile($pluginFilename); - } - die; - } - - $requestUriArray = explode("/", $_SERVER['REQUEST_URI']); - - if ((isset($requestUriArray[1])) && ($requestUriArray[1] == 'skin')) { - // This will allow to public images of Custom Skins, By JHL Feb 28, 11 - $pathsQuery = ""; - // Get the query side - // This way we remove garbage - $forQuery = explode("?", $realPath); - if (isset($forQuery[1])) { - $pathsQuery = $forQuery[1]; - } - - //Get that path in array - $paths = explode(PATH_SEP, $forQuery[0]); - $fileToBeStreamed = str_replace("/skin/", PATH_CUSTOM_SKINS, $_SERVER['REQUEST_URI']); - - if (file_exists($fileToBeStreamed)) { - G::streamFile($fileToBeStreamed); - } - die; - } - switch ($realPath) { - case 'sysUnnamed' : - require_once('sysUnnamed.php'); - die; - break; - case 'sysNamed' : - header('location : ' . $_SERVER['REQUEST_URI'] . '/' . SYS_LANG . '/classic/login/login'); - die; - break; - case 'jsMethod' : - G::parseURI(getenv("REQUEST_URI")); - $filename = PATH_METHODS . SYS_COLLECTION . '/' . SYS_TARGET . '.js'; - G::streamFile($filename); - die; - break; - case 'errorFile': - header("location: /errors/error404.php?url=" . urlencode($_SERVER['REQUEST_URI'])); - if (DEBUG_TIME_LOG) { - G::logTimeByPage(); - } //log this page - die; - break; - default : - if (substr($realPath, 0, 12) == 'rest-service') { - $isRestRequest = true; - } else { - $realPath = explode('?', $realPath); - $realPath[0] .= strpos(basename($realPath[0]), '.') === false ? '.php' : ''; - G::streamFile($realPath[0]); - die; - } - } -}//virtual URI parser - -// the request correspond to valid php page, now parse the URI -G::parseURI(getenv("REQUEST_URI"), $isRestRequest); - -$arrayUpdating = G::isPMUnderUpdating(); -if ($arrayUpdating['action']) { - if ($arrayUpdating['workspace'] == "true" || $arrayUpdating['workspace'] == SYS_TEMP) { - header("location: /update/updating.php"); - if (DEBUG_TIME_LOG) { - G::logTimeByPage(); - } - die; - } -} - -// verify if index.html exists -if (!file_exists(PATH_HTML . 'index.html')) { // if not, create it from template - file_put_contents( - PATH_HTML . 'index.html', - G::parseTemplate(PATH_TPL . "index.html", - array("lang" => ((defined("SYS_LANG") && SYS_LANG != "") ? SYS_LANG : "en"), "skin" => SYS_SKIN)) - ); -} - -define('SYS_URI', '/sys' . SYS_TEMP . '/' . SYS_LANG . '/' . SYS_SKIN . '/'); - -// defining the serverConf singleton -if (defined('PATH_DATA') && file_exists(PATH_DATA)) { - //Instance Server Configuration Singleton - $oServerConf = ServerConf::getSingleton(); -} - -// Call Gulliver Classes - - -// Create headPublisher singleton - -$oHeadPublisher = headPublisher::getSingleton(); - -//Load filter class - -$filter = new InputFilter(); - -// Installer, redirect to install if we don't have a valid shared data folder -if (!defined('PATH_DATA') || !file_exists(PATH_DATA)) { - - // new installer, extjs based - define('PATH_DATA', PATH_C); - require_once ( PATH_CONTROLLERS . 'InstallerModule.php' ); - $controller = InstallerModule::class; - - // if the method name is empty set default to index method - if (strpos(SYS_TARGET, '/') !== false) { - list($controller, $controllerAction) = explode('/', SYS_TARGET); - } else { - $controllerAction = SYS_TARGET; - } - - $controllerAction = ($controllerAction != '' && $controllerAction != 'login') ? $controllerAction : 'index'; - - // create the installer controller and call its method - if (is_callable([InstallerModule::class, $controllerAction])) { - $installer = new $controller(); - $installer->setHttpRequestData($_REQUEST); - $installer->call($controllerAction); - } - else { - $_SESSION['phpFileNotFound'] = $_SERVER['REQUEST_URI']; - header ("location: /errors/error404.php?url=" . urlencode($_SERVER['REQUEST_URI'])); - } - die; -} - -// Load Language Translation -G::LoadTranslationObject(defined('SYS_LANG') ? SYS_LANG : "en"); - -// look for a disabled workspace -if ($oServerConf->isWSDisabled(SYS_TEMP)) { - $aMessage['MESSAGE'] = G::LoadTranslation('ID_DISB_WORKSPACE'); - $G_PUBLISH = new Publisher; - $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage); - G::RenderPage('publish'); - die; -} - -// database and workspace definition -// if SYS_TEMP exists, the URL has a workspace, now we need to verify if exists their db.php file -if (defined('SYS_TEMP') && SYS_TEMP != '') { - //this is the default, the workspace db.php file is in /shared/workflow/sites/SYS_SYS - if (file_exists(PATH_DB . SYS_TEMP . '/db.php')) { - $pathFile = $filter->validateInput(PATH_DB . SYS_TEMP . '/db.php', 'path'); - require_once($pathFile); - define('SYS_SYS', SYS_TEMP); - - // defining constant for workspace shared directory - define('PATH_WORKSPACE', PATH_DB . config("system.workspace") . PATH_SEP); - // including workspace shared classes -> particularlly for pmTables - set_include_path(get_include_path() . PATH_SEPARATOR . PATH_WORKSPACE); - } else { - G::SendTemporalMessage('ID_NOT_WORKSPACE', "error"); - G::header('location: /sys/' . SYS_LANG . '/' . SYS_SKIN . '/main/sysLogin?errno=2'); - die; - } -} else { //when we are in global pages, outside any valid workspace - if (SYS_TARGET === 'newSite') { - $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . "/" . SYS_TARGET . '.php'; - $phpFile = $filter->validateInput($phpFile, 'path'); - require_once($phpFile); - die(); - } else { - if (SYS_TARGET == "dbInfo") { //Show dbInfo when no SYS_SYS - $pathFile = PATH_METHODS . 'login/dbInfo.php'; - $pathFile = $filter->validateInput($pathFile, 'path'); - require_once($pathFile); - } else { - - if (substr(SYS_SKIN, 0, - 2) === 'ux' && SYS_TARGET != 'sysLoginVerify') { // new ux sysLogin - extjs based form - $pathFile = $filter->validateInput(PATH_CONTROLLERS . 'main.php', 'path'); - require_once $pathFile; - $controllerClass = 'Main'; - $controllerAction = SYS_TARGET == 'sysLoginVerify' ? SYS_TARGET : 'sysLogin'; - //if the method exists - if (is_callable(Array($controllerClass, $controllerAction))) { - $controller = new $controllerClass(); - $controller->setHttpRequestData($_REQUEST); - $controller->call($controllerAction); - } - } else { // classic sysLogin interface - $pathFile = PATH_METHODS . 'login/sysLogin.php'; - $pathFile = $filter->validateInput($pathFile, 'path'); - require_once($pathFile); - die(); - } - } - if (DEBUG_TIME_LOG) { - G::logTimeByPage(); - } //log this page - die(); - } -} - -// PM Paths DATA -define('PATH_DATA_SITE', PATH_DATA . 'sites/' . config("system.workspace") . '/'); -define('PATH_DOCUMENT', PATH_DATA_SITE . 'files/'); -define('PATH_DATA_MAILTEMPLATES', PATH_DATA_SITE . 'mailTemplates/'); -define('PATH_DATA_PUBLIC', PATH_DATA_SITE . 'public/'); -define('PATH_DATA_REPORTS', PATH_DATA_SITE . 'reports/'); -define('PATH_DYNAFORM', PATH_DATA_SITE . 'xmlForms/'); -define('PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE . 'usersFiles' . PATH_SEP); -define('PATH_IMAGES_ENVIRONMENT_USERS', PATH_DATA_SITE . 'usersPhotographies' . PATH_SEP); -define('SERVER_NAME', $_SERVER ['SERVER_NAME']); -define('SERVER_PORT', $_SERVER ['SERVER_PORT']); - -// create memcached singleton -$memcache = PMmemcached::getSingleton(config("system.workspace")); - -// verify configuration for rest service -if ($isRestRequest) { - // disable until confirm that rest is enabled & configured on rest-config.ini file - $isRestRequest = false; - $confFile = ''; - $restApiClassPath = ''; - - // try load and getting rest configuration - if (file_exists(PATH_DATA_SITE . 'rest-config.ini')) { - $confFile = PATH_DATA_SITE . 'rest-config.ini'; - $restApiClassPath = PATH_DATA_SITE; - } elseif (file_exists(PATH_CONFIG . 'rest-config.ini')) { - $confFile = PATH_CONFIG . 'rest-config.ini'; - } - if (!empty($confFile) && $restConfig = @parse_ini_file($confFile, true)) { - if (array_key_exists('enable_service', $restConfig)) { - if ($restConfig['enable_service'] == 'true' || $restConfig['enable_service'] == '1') { - $isRestRequest = true; // rest service enabled - } - } - } -} - -//here we are loading all plugins registered -//the singleton has a list of enabled plugins -$oPluginRegistry = PluginRegistry::loadSingleton(); - -// setup propel definitions and logging -require_once("propel/Propel.php"); -require_once("creole/Creole.php"); - -if (defined('DEBUG_SQL_LOG') && DEBUG_SQL_LOG) { - define('PM_PID', mt_rand(1, 999999)); - require_once 'Log.php'; - - // register debug connection decorator driver - Creole::registerDriver('*', 'creole.contrib.DebugConnection'); - - // initialize Propel with converted config file - Propel::init(PATH_CORE . "config/databases.php"); - - // unified log file for all databases - $logFile = PATH_DATA . 'log' . PATH_SEP . 'propel.log'; - $logger = Log::singleton('file', $logFile, 'wf ' . config("system.workspace"), null, PEAR_LOG_INFO); - Propel::setLogger($logger); - // log file for workflow database - $con = Propel::getConnection('workflow'); - if ($con instanceof DebugConnection) { - $con->setLogger($logger); - } - // log file for rbac database - $con = Propel::getConnection('rbac'); - - if ($con instanceof DebugConnection) { - $con->setLogger($logger); - } - - // log file for report database - $con = Propel::getConnection('rp'); - if ($con instanceof DebugConnection) { - $con->setLogger($logger); - } -} else { - Propel::init(PATH_CORE . "config/databases.php"); -} - -Creole::registerDriver('dbarray', 'creole.contrib.DBArrayConnection'); - -// Session Initializations -ini_set('session.auto_start', '1'); - -// The register_globals feature has been DEPRECATED as of PHP 5.3.0. default value Off. -// ini_set( 'register_globals', 'Off' ); -//session_start(); -ob_start(); - -// Rebuild the base Workflow translations if not exists -if (!is_file(PATH_LANGUAGECONT . 'translation.en')) { - require_once("classes/model/Translation.php"); - $fields = Translation::generateFileTranslation('en'); -} - -// TODO: Verify if the language set into url is defined in translations env. -if (SYS_LANG != 'en' && !is_file(PATH_LANGUAGECONT . 'translation.' . SYS_LANG)) { - require_once("classes/model/Translation.php"); - $fields = Translation::generateFileTranslation(SYS_LANG); -} - -// Setup plugins -$oPluginRegistry->setupPlugins(); //get and setup enabled plugins -$avoidChangedWorkspaceValidation = false; - -// Load custom Classes and Model from Plugins. -G::LoadAllPluginModelClasses(); - -// jump to php file in methods directory -$collectionPlugin = ''; -if ($oPluginRegistry->isRegisteredFolder(SYS_COLLECTION)) { - $phpFile = PATH_PLUGINS . SYS_COLLECTION . PATH_SEP . SYS_TARGET . '.php'; - $targetPlugin = explode('/', SYS_TARGET); - $collectionPlugin = $targetPlugin[0]; - $avoidChangedWorkspaceValidation = true; -} else { - $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . PATH_SEP . SYS_TARGET . '.php'; -} - -// services is a special folder, -if (SYS_COLLECTION == 'services') { - $avoidChangedWorkspaceValidation = true; - $targetPlugin = explode('/', SYS_TARGET); - - if ($targetPlugin[0] == 'webdav') { - $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . PATH_SEP . 'webdav.php'; - } -} - -if (SYS_COLLECTION == 'login' && SYS_TARGET == 'login') { - $avoidChangedWorkspaceValidation = true; -} - -//the index.php file, this new feature will allow automatically redirects to valid php file inside any methods folder -/* DEPRECATED -if ( SYS_TARGET == '' ) { - $phpFile = str_replace ( '.php', 'index.php', $phpFile ); - $phpFile = include ( $phpFile ); -}*/ -$bWE = false; -$isControllerCall = false; -if (substr(SYS_COLLECTION, 0, 8) === 'gulliver') { - $phpFile = PATH_GULLIVER_HOME . 'methods/' . substr(SYS_COLLECTION, 8) . SYS_TARGET . '.php'; -} else { - //when the file is part of the public directory of any PROCESS, this a ProcessMaker feature - if (preg_match('/^[0-9][[:alnum:]]+$/', SYS_COLLECTION) == 1) { //the pattern is /sysSYS/LANG/SKIN/PRO_UID/file - $auxPart = explode('/', $_SERVER['REQUEST_URI']); - $aAux = explode('?', $auxPart[count($auxPart) - 1]); - //$extPart = explode ( '.' , $auxPart[ count($auxPart)-1] ); - $extPart = explode('.', $aAux[0]); - $queryPart = isset($aAux[1]) ? $aAux[1] : ""; - $extension = $extPart[count($extPart) - 1]; - $phpFile = PATH_DATA_SITE . 'public' . PATH_SEP . SYS_COLLECTION . PATH_SEP . urldecode($auxPart[count($auxPart) - 1]); - $aAux = explode('?', $phpFile); - $phpFile = $aAux[0]; - - if ($extension != 'php') { - G::streamFile($phpFile); - die; - } - - $avoidChangedWorkspaceValidation = true; - $bWE = true; - //$phpFile = PATH_DATA_SITE . 'public' . PATH_SEP . SYS_COLLECTION . PATH_SEP . $auxPart[ count($auxPart)-1]; - } - - //erik: verify if it is a Controller Class or httpProxyController Class - if (is_file(PATH_CONTROLLERS . SYS_COLLECTION . '.php')) { - $pathFile = $filter->validateInput(PATH_CONTROLLERS . SYS_COLLECTION . '.php', 'path'); - require_once $pathFile; - $controllerClass = SYS_COLLECTION; - //if the method name is empty set default to index method - $controllerAction = SYS_TARGET != '' ? SYS_TARGET : 'index'; - //if the method exists - if (is_callable(Array($controllerClass, $controllerAction))) { - $isControllerCall = true; - } - } - - if (!$isControllerCall && !file_exists($phpFile) && !$isRestRequest) { - $_SESSION['phpFileNotFound'] = $_SERVER['REQUEST_URI']; - header("location: /errors/error404.php?url=" . urlencode($_SERVER['REQUEST_URI'])); - die; - } -} - -//redirect to login, if user changed the workspace in the URL -if (!$avoidChangedWorkspaceValidation && isset($_SESSION['WORKSPACE']) && $_SESSION['WORKSPACE'] != config("system.workspace")) { - $_SESSION['WORKSPACE'] = config("system.workspace"); - G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', "error"); - // verify if the current skin is a 'ux' variant - $urlPart = substr(SYS_SKIN, 0, 2) == 'ux' && SYS_SKIN != 'uxs' ? '/main/login' : '/login/login'; - - header('Location: /sys' . config("system.workspace") . '/' . SYS_LANG . '/' . SYS_SKIN . $urlPart); - die; -} - -// enable rbac -$RBAC = RBAC::getSingleton(PATH_DATA, session_id()); -$RBAC->sSystem = 'PROCESSMAKER'; - -// define and send Headers for all pages -if (!defined('EXECUTE_BY_CRON')) { - header("Expires: " . gmdate("D, d M Y H:i:s", mktime(0, 0, 0, date('m'), date('d') - 1, date('Y'))) . " GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - - // get the language direction from ServerConf - define('SYS_LANG_DIRECTION', $oServerConf->getLanDirection()); - - if ((isset($_SESSION['USER_LOGGED'])) && (!(isset($_GET['sid'])))) { - if (PHP_VERSION < 5.2) { - setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly'); - } else { - setcookie(session_name(), session_id(), time() + $timelife, '/', null, false, true); - } - $RBAC->initRBAC(); - //using optimization with memcache, the user data will be in memcache 8 hours, or until session id goes invalid - $memKey = 'rbacSession' . session_id(); - if (($RBAC->aUserInfo = $memcache->get($memKey)) === false) { - $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); - $memcache->set($memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS); - } - } else { - // this is the blank list to allow execute scripts with no login (without session started) - $noLoginFiles = $noLoginFolders = []; - $noLoginFiles[] = 'login'; - $noLoginFiles[] = 'authentication'; - $noLoginFiles[] = 'login_Ajax'; - $noLoginFiles[] = 'dbInfo'; - $noLoginFiles[] = 'sysLoginVerify'; - $noLoginFiles[] = 'processes_Ajax'; - $noLoginFiles[] = 'showLogoFile'; - $noLoginFiles[] = 'forgotPassword'; - $noLoginFiles[] = 'retrivePassword'; - $noLoginFiles[] = 'genericAjax'; - - $noLoginFolders[] = 'services'; - $noLoginFolders[] = 'tracker'; - $noLoginFolders[] = 'installer'; - - // This sentence is used when you lost the Session - if (!in_array(SYS_TARGET, $noLoginFiles) - && !in_array(SYS_COLLECTION, $noLoginFolders) - && $bWE != true && $collectionPlugin != 'services' - && !$isRestRequest - ) { - $bRedirect = true; - - if (isset($_GET['sid'])) { - $oSessions = new Sessions(); - if ($aSession = $oSessions->verifySession($_GET['sid'])) { - require_once 'classes/model/Users.php'; - $oUser = new Users(); - $aUser = $oUser->load($aSession['USR_UID']); - initUserSession($aUser['USR_UID'], $aUser['USR_USERNAME']); - $bRedirect = false; - if (PHP_VERSION < 5.2) { - setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly'); - } else { - setcookie(session_name(), session_id(), time() + $timelife, '/', null, false, true); - } - $RBAC->initRBAC(); - $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); - $memKey = 'rbacSession' . session_id(); - $memcache->set($memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS); - } - } - - if ((isset($_SESSION['USER_LOGGED'])) && (!(isset($_GET['sid'])))) { - if (PHP_VERSION < 5.2) { - setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly'); - } else { - setcookie(session_name(), session_id(), time() + $timelife, '/', null, false, true); - } - $RBAC->initRBAC(); - //using optimization with memcache, the user data will be in memcache 8 hours, or until session id goes invalid - $memKey = 'rbacSession' . session_id(); - if (($RBAC->aUserInfo = $memcache->get($memKey)) === false) { - $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); - $memcache->set($memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS); - } - } else { - // this is the blank list to allow execute scripts with no login (without session started) - $noLoginFiles = $noLoginFolders = []; - $noLoginFiles[] = 'login'; - $noLoginFiles[] = 'authentication'; - $noLoginFiles[] = 'login_Ajax'; - $noLoginFiles[] = 'dbInfo'; - $noLoginFiles[] = 'sysLoginVerify'; - $noLoginFiles[] = 'processes_Ajax'; - $noLoginFiles[] = 'showLogoFile'; - $noLoginFiles[] = 'forgotPassword'; - $noLoginFiles[] = 'retrivePassword'; - $noLoginFiles[] = 'genericAjax'; - - $noLoginFolders[] = 'services'; - $noLoginFolders[] = 'tracker'; - $noLoginFolders[] = 'installer'; - - // This sentence is used when you lost the Session - if (!in_array(SYS_TARGET, $noLoginFiles) - && !in_array(SYS_COLLECTION, $noLoginFolders) - && $bWE != true && $collectionPlugin != 'services' - && !$isRestRequest - ) { - $bRedirect = true; - - if (isset($_GET['sid'])) { - $oSessions = new Sessions(); - if ($aSession = $oSessions->verifySession($_GET['sid'])) { - require_once 'classes/model/Users.php'; - $oUser = new Users(); - $aUser = $oUser->load($aSession['USR_UID']); - $_SESSION['USER_LOGGED'] = $aUser['USR_UID']; - $_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME']; - $bRedirect = false; - if (PHP_VERSION < 5.2) { - setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly'); - } else { - setcookie(session_name(), session_id(), time() + $timelife, '/', null, false, true); - } - $RBAC->initRBAC(); - $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); - $memKey = 'rbacSession' . session_id(); - $memcache->set($memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS); - } - } - - if ($bRedirect) { - if (substr(SYS_SKIN, 0, - 2) == 'ux' && SYS_SKIN != 'uxs' - ) { // verify if the current skin is a 'ux' variant - $loginUrl = 'main/login'; - } else { - if (strpos($_SERVER['REQUEST_URI'], - '/home') !== false - ) { //verify is it is using the uxs skin for simplified interface - $loginUrl = 'home/login'; - } else { - $loginUrl = 'login/login'; // just set up the classic login - } - } - - if (empty($_POST)) { - header('location: ' . SYS_URI . $loginUrl . '?u=' . urlencode($_SERVER['REQUEST_URI'])); - - } else { - if ($isControllerCall) { - header("HTTP/1.0 302 session lost in controller"); - } else { - header('location: ' . SYS_URI . $loginUrl); - } - } - die(); - } - } - } - $_SESSION['phpLastFileFound'] = $_SERVER['REQUEST_URI']; - - /** - * New feature for Gulliver framework to support Controllers & HttpProxyController classes handling - * - * @author Erik Amaru Ortiz - */ - if ($isControllerCall) { //Instance the Controller object and call the request method - $controller = new $controllerClass(); - $controller->setHttpRequestData($_REQUEST); - $controller->call($controllerAction); - } elseif ($isRestRequest) { - G::dispatchRestService(SYS_TARGET, $restConfig, $restApiClassPath); - } else { - require_once $filter->validateInput($phpFile, 'path'); - } - - if (defined('SKIP_HEADERS')) { - header("Expires: " . gmdate("D, d M Y H:i:s", - mktime(0, 0, 0, date('m'), date('d'), date('Y') + 1)) . " GMT"); - header('Cache-Control: public'); - header('Pragma: '); - } - - ob_end_flush(); - if (DEBUG_TIME_LOG) { - G::logTimeByPage(); //log this page - } - } - } -} diff --git a/workflow/public_html/pmGmail/sso.php b/workflow/public_html/pmGmail/sso.php index f98d5cde1..a30aa2fa9 100644 --- a/workflow/public_html/pmGmail/sso.php +++ b/workflow/public_html/pmGmail/sso.php @@ -98,7 +98,8 @@ if (!isset($_SESSION['USER_LOGGED']) || $_SESSION['USER_LOGGED'] != $decodedResp session_start(); session_regenerate_id(); - setcookie("workspaceSkin", $enviroment, time() + (24 * 60 * 60), "/sys" . $enviroment, null, G::is_https(), true); + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + (24 * 60 * 60), 'path' => '/sys' . $enviroment, 'httponly' => true]); + setcookie('workspaceSkin', $enviroment, $cookieOptions); $_SESSION = array(); $_SESSION['__EE_INSTALLATION__'] = 2; diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php index 1aa362f65..8634cde18 100644 --- a/workflow/public_html/sysGeneric.php +++ b/workflow/public_html/sysGeneric.php @@ -944,11 +944,8 @@ if (!defined('EXECUTE_BY_CRON')) { (!(preg_match("/safari/i", $_SERVER ['HTTP_USER_AGENT']) == 1 && preg_match("/chrome/i", $_SERVER ['HTTP_USER_AGENT']) == 0) || $config['safari_cookie_lifetime'] == 1)) { - if (PHP_VERSION < 5.2) { - setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly'); - } else { - setcookie(session_name(), session_id(), time() + $timelife, '/', null, G::is_https(), true); - } + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + $timelife, 'httponly' => true]); + setcookie(session_name(), session_id(), $cookieOptions); } $RBAC->initRBAC(); //using optimization with memcache, the user data will be in memcache 8 hours, or until session id goes invalid @@ -1024,11 +1021,8 @@ if (!defined('EXECUTE_BY_CRON')) { (!(preg_match("/safari/i", $_SERVER ['HTTP_USER_AGENT']) == 1 && preg_match("/chrome/i", $_SERVER ['HTTP_USER_AGENT']) == 0) || $config['safari_cookie_lifetime'] == 1)) { - if (PHP_VERSION < 5.2) { - setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly'); - } else { - setcookie(session_name(), session_id(), time() + $timelife, '/', null, G::is_https(), true); - } + $cookieOptions = Bootstrap::buildCookieOptions(['expires' => time() + $timelife, 'httponly' => true]); + setcookie(session_name(), session_id(), $cookieOptions); } $RBAC->initRBAC(); $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); From e4484ec1dde7b50a54d1399daa8f1512183a2022 Mon Sep 17 00:00:00 2001 From: Fabio Guachalla Date: Fri, 26 Nov 2021 11:31:48 -0400 Subject: [PATCH 2/9] PMCORE-3509:In version 3.7.0 the inbox the send by field displays the undefined username after a script task Correction Style --- .../assets/js/admin/Modals/ModalPreview.vue | 58 +++++++-------- .../components/vuetable/CurrentUserCell.vue | 15 +++- .../js/home/CustomCaseList/CustomCaseList.vue | 73 +++++++------------ resources/assets/js/home/Inbox/Inbox.vue | 64 +++++++--------- resources/assets/js/home/Paused/Paused.vue | 68 +++++++---------- .../assets/js/home/Unassigned/Unassigned.vue | 66 +++++++---------- 6 files changed, 147 insertions(+), 197 deletions(-) diff --git a/resources/assets/js/admin/Modals/ModalPreview.vue b/resources/assets/js/admin/Modals/ModalPreview.vue index 1013426a7..b08f2b58b 100644 --- a/resources/assets/js/admin/Modals/ModalPreview.vue +++ b/resources/assets/js/admin/Modals/ModalPreview.vue @@ -29,12 +29,7 @@
- - +
{{ props.row.USERNAME_DISPLAY_FORMAT }} @@ -110,8 +105,7 @@ export default { DRAFT: this.$i18n.t("ID_IN_DRAFT"), PAUSED: this.$i18n.t("ID_PAUSED"), UNASSIGNED: this.$i18n.t("ID_UNASSIGNED"), - }, - showUserTooltip: true + } } }, mounted() { @@ -256,29 +250,31 @@ export default { formatUser(data) { var dataFormat = [], userDataFormat; - if (data.user_tooltip && !_.isEmpty(data.user_tooltip)) { - this.showUserTooltip = true; - userDataFormat = utils.userNameDisplayFormat({ - userName: data.user_tooltip.usr_firstname, - firstName: data.user_tooltip.usr_lastname, - lastName: data.user_tooltip.usr_username, - format: window.config.FORMATS.format || null - }); - dataFormat.push({ - USERNAME_DISPLAY_FORMAT: userDataFormat, - EMAIL: data.user_tooltip.usr_email, - POSITION: data.user_tooltip.usr_position, - AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER_AJAX + - window.config.SYS_URI + - `users/users_ViewPhotoGrid?pUID=${data.user_tooltip.usr_id}` : "", - UNASSIGNED: userDataFormat !== "" ? true : false - }); - } else if (data.dummy_task && !_.isEmpty(data.dummy_task)) { - this.showUserTooltip = false; - dataFormat = data.dummy_task.type + ': ' + data.dummy_task.name; - } else { - this.showUserTooltip = false; - dataFormat = this.$i18n.t("ID_ANONYMOUS_USER"); + switch (data.key_name) { + case 'user_tooltip': + userDataFormat = utils.userNameDisplayFormat({ + userName: data.user_tooltip.usr_firstname, + firstName: data.user_tooltip.usr_lastname, + lastName: data.user_tooltip.usr_username, + format: window.config.FORMATS.format || null + }); + dataFormat.push({ + USERNAME_DISPLAY_FORMAT: userDataFormat, + EMAIL: data.user_tooltip.usr_email, + POSITION: data.user_tooltip.usr_position, + AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER_AJAX + + window.config.SYS_URI + + `users/users_ViewPhotoGrid?pUID=${data.user_tooltip.usr_id}` : "", + UNASSIGNED: userDataFormat !== "" ? true : false, + SHOW_TOOLTIP: true + }); + break; + case 'dummy_task': + dataFormat = data.dummy_task.type + ': ' + data.dummy_task.name; + break; + default: + dataFormat = ""; + break; } return dataFormat; } diff --git a/resources/assets/js/components/vuetable/CurrentUserCell.vue b/resources/assets/js/components/vuetable/CurrentUserCell.vue index e4fc4e264..0a64b14fc 100644 --- a/resources/assets/js/components/vuetable/CurrentUserCell.vue +++ b/resources/assets/js/components/vuetable/CurrentUserCell.vue @@ -1,5 +1,5 @@