diff --git a/.htaccess b/.htaccess index c6dda8429..4eaa9138a 100644 --- a/.htaccess +++ b/.htaccess @@ -2,3 +2,8 @@ IndexIgnore * Options -Indexes + +# Security headers (requires mod_headers; AllowOverride FileInfo or All). + + Header always set Referrer-Policy "strict-origin-when-cross-origin" + diff --git a/ajax/deleteActivity.php b/ajax/deleteActivity.php index 180fc6946..785dddda5 100755 --- a/ajax/deleteActivity.php +++ b/ajax/deleteActivity.php @@ -32,6 +32,12 @@ $interface = new SecureAJAXInterface(); +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + if (!$interface->isRequiredIDValid('activityID')) { $interface->outputXMLErrorPage(-1, 'Invalid activity ID.'); @@ -40,7 +46,7 @@ $siteID = $interface->getSiteID(); -$activityID = $_REQUEST['activityID']; +$activityID = $_POST['activityID']; /* Delete the activity entry. */ $activityEntries = new ActivityEntries($siteID); diff --git a/ajax/editActivity.php b/ajax/editActivity.php index 91e7a5835..7f186ad09 100755 --- a/ajax/editActivity.php +++ b/ajax/editActivity.php @@ -35,6 +35,12 @@ $interface = new SecureAJAXInterface(); +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + if (!$interface->isRequiredIDValid('activityID')) { $interface->outputXMLErrorPage(-1, 'Invalid activity ID.'); @@ -53,7 +59,7 @@ die(); } -if (!isset($_REQUEST['notes'])) +if (!isset($_POST['notes'])) { $interface->outputXMLErrorPage(-1, 'Invalid notes.'); die(); @@ -61,16 +67,16 @@ $siteID = $interface->getSiteID(); -$activityID = $_REQUEST['activityID']; -$type = $_REQUEST['type']; -$jobOrderID = $_REQUEST['jobOrderID']; +$activityID = $_POST['activityID']; +$type = $_POST['type']; +$jobOrderID = $_POST['jobOrderID']; /* Decode and trim the activity notes from the company. */ -$activityNote = trim(urldecode($_REQUEST['notes'])); -$activityDate = trim(urldecode($_REQUEST['date'])); -$activityHour = trim(urldecode($_REQUEST['hour'])); -$activityMinute = trim(urldecode($_REQUEST['minute'])); -$activityAMPM = trim(urldecode($_REQUEST['ampm'])); +$activityNote = trim(urldecode($_POST['notes'])); +$activityDate = trim(urldecode($_POST['date'])); +$activityHour = trim(urldecode($_POST['hour'])); +$activityMinute = trim(urldecode($_POST['minute'])); +$activityAMPM = trim(urldecode($_POST['ampm'])); if (!DateUtility::validate('-', $activityDate, DATE_FORMAT_MMDDYY)) { diff --git a/ajax/getPipelineJobOrder.php b/ajax/getPipelineJobOrder.php index d415f5bd6..9e959021d 100755 --- a/ajax/getPipelineJobOrder.php +++ b/ajax/getPipelineJobOrder.php @@ -305,11 +305,14 @@ function printSortLink($field, $delimiter = "'", $changeDirection = true) - getAccessLevel('pipelines.removeFromPipeline') >= ACCESS_LEVEL_DELETE): ?> - - remove - - + getAccessLevel('pipelines.removeFromPipeline') >= ACCESS_LEVEL_DELETE): ?> +
+ + + + +
+ diff --git a/ajax/setCandidateJobOrderRating.php b/ajax/setCandidateJobOrderRating.php index 19236e202..2d545c964 100755 --- a/ajax/setCandidateJobOrderRating.php +++ b/ajax/setCandidateJobOrderRating.php @@ -32,6 +32,12 @@ $interface = new SecureAJAXInterface(); +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + if ($_SESSION['CATS']->getAccessLevel('pipelines.editRating') < ACCESS_LEVEL_EDIT) { $interface->outputXMLErrorPage(-1, ERROR_NO_PERMISSION); @@ -45,7 +51,7 @@ } if (!$interface->isRequiredIDValid('rating', true, true) || - $_REQUEST['rating'] < -6 || $_REQUEST['rating'] > 5) + $_POST['rating'] < -6 || $_POST['rating'] > 5) { $interface->outputXMLErrorPage(-1, 'Invalid rating.'); die(); @@ -53,8 +59,8 @@ $siteID = $interface->getSiteID(); -$candidateJobOrderID = $_REQUEST['candidateJobOrderID']; -$rating = $_REQUEST['rating']; +$candidateJobOrderID = $_POST['candidateJobOrderID']; +$rating = $_POST['rating']; $pipelines = new Pipelines($siteID); $pipelines->updateRatingValue($candidateJobOrderID, $rating); diff --git a/ajax/setColumnWidth.php b/ajax/setColumnWidth.php index f4efbe03b..ca2bc7ce9 100755 --- a/ajax/setColumnWidth.php +++ b/ajax/setColumnWidth.php @@ -29,9 +29,21 @@ $interface = new SecureAJAXInterface(); -$instance = $_REQUEST['instance']; -$columnName = $_REQUEST['columnName']; -$columnWidth = $_REQUEST['columnWidth']; +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + +if (!isset($_POST['instance']) || !isset($_POST['columnName']) || !isset($_POST['columnWidth'])) +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + +$instance = $_POST['instance']; +$columnName = $_POST['columnName']; +$columnWidth = $_POST['columnWidth']; $columnPreferences = $_SESSION['CATS']->getColumnPreferences($instance); diff --git a/ajax/testEmailSettings.php b/ajax/testEmailSettings.php index 5845e4b53..f93751b80 100755 --- a/ajax/testEmailSettings.php +++ b/ajax/testEmailSettings.php @@ -32,10 +32,16 @@ $interface = new SecureAJAXInterface(); +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + $siteID = $interface->getSiteID(); -if (!isset($_REQUEST['testEmailAddress']) || - empty($_REQUEST['testEmailAddress'])) +if (!isset($_POST['testEmailAddress']) || + empty($_POST['testEmailAddress'])) { $interface->outputXMLErrorPage( -1, 'Invalid test e-mail address.' @@ -44,8 +50,8 @@ die(); } -if (!isset($_REQUEST['fromAddress']) || - empty($_REQUEST['fromAddress'])) +if (!isset($_POST['fromAddress']) || + empty($_POST['fromAddress'])) { $interface->outputXMLErrorPage( -1, 'Invalid from e-mail address.' @@ -54,8 +60,8 @@ die(); } -$testEmailAddress = $_REQUEST['testEmailAddress']; -$fromAddress = $_REQUEST['fromAddress']; +$testEmailAddress = $_POST['testEmailAddress']; +$fromAddress = $_POST['fromAddress']; /* Is the test e-mail address specified valid? */ // FIXME: Validate properly. diff --git a/index.php b/index.php index e35a864f3..ad6b13ba7 100644 --- a/index.php +++ b/index.php @@ -172,6 +172,32 @@ function stripslashes_deep($value) } } +if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST' && + $_SESSION['CATS']->isLoggedIn() && + (!isset($careerPage) || !$careerPage) && + (!isset($_GET['showCareerPortal']) || $_GET['showCareerPortal'] != '1') && + (!isset($rssPage) || !$rssPage) && + (!isset($xmlPage) || !$xmlPage)) +{ + $module = isset($_GET['m']) ? $_GET['m'] : ''; + + if ($module == '' || $module == 'logout' || + ModuleUtility::moduleRequiresAuthentication($module)) + { + $token = null; + + if (isset($_POST['csrfToken'])) + { + $token = $_POST['csrfToken']; + } + + if (!$_SESSION['CATS']->isCSRFTokenValid($token)) + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, null, 'Invalid request.'); + } + } +} + /* Check to see if we are supposed to display the career page. */ if (((isset($careerPage) && $careerPage) || (isset($_GET['showCareerPortal']) && $_GET['showCareerPortal'] == '1'))) @@ -219,6 +245,11 @@ function stripslashes_deep($value) { if ($_GET['m'] == 'logout') { + if ($_SERVER['REQUEST_METHOD'] !== 'POST') + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, null, 'Invalid request.'); + } + /* There isn't really a logout module. It's just a few lines. */ $unixName = $_SESSION['CATS']->getUnixName(); @@ -233,12 +264,20 @@ function stripslashes_deep($value) $URI .= '&s=' . $unixName; } - if (isset($_GET['message'])) + if (isset($_POST['message'])) + { + $URI .= '&message=' . urlencode($_POST['message']); + } + else if (isset($_GET['message'])) { $URI .= '&message=' . urlencode($_GET['message']); } - if (isset($_GET['messageSuccess'])) + if (isset($_POST['messageSuccess'])) + { + $URI .= '&messageSuccess=' . urlencode($_POST['messageSuccess']); + } + else if (isset($_GET['messageSuccess'])) { $URI .= '&messageSuccess=' . urlencode($_GET['messageSuccess']); } diff --git a/js/lib.js b/js/lib.js index cb80e2e59..4ab3884f6 100755 --- a/js/lib.js +++ b/js/lib.js @@ -342,6 +342,20 @@ function AJAX_getPOSTSessionID(sessionCookie) function AJAX_POST(http, url, POSTData, callBack, timeout, sessionCookie, silentTimeout) { + if (POSTData == null) + { + POSTData = ''; + } + + if (typeof CATSCsrfToken != 'undefined' && CATSCsrfToken !== null && + CATSCsrfToken !== '') + { + if (POSTData.indexOf('csrfToken=') == -1) + { + POSTData += '&csrfToken=' + encodeURIComponent(CATSCsrfToken); + } + } + /* Add a random hash to the POST data to keep IE from caching it. */ POSTData += AJAX_getRandomPOSTHash(); diff --git a/js/lists.js b/js/lists.js index 09edc620c..50157f3a0 100755 --- a/js/lists.js +++ b/js/lists.js @@ -205,7 +205,34 @@ function deleteListFromListView(savedListID, numberEntries) return; } - document.location.href = CATSIndexName + '?m=lists&a=deleteStaticList&savedListID=' + savedListID; + var form = document.createElement('form'); + form.method = 'post'; + form.action = CATSIndexName + '?m=lists&a=deleteStaticList'; + + var postback = document.createElement('input'); + postback.type = 'hidden'; + postback.name = 'postback'; + postback.value = 'postback'; + form.appendChild(postback); + + var savedListInput = document.createElement('input'); + savedListInput.type = 'hidden'; + savedListInput.name = 'savedListID'; + savedListInput.value = savedListID; + form.appendChild(savedListInput); + + if (typeof CATSCsrfToken != 'undefined' && CATSCsrfToken !== null && + CATSCsrfToken !== '') + { + var csrfToken = document.createElement('input'); + csrfToken.type = 'hidden'; + csrfToken.name = 'csrfToken'; + csrfToken.value = CATSCsrfToken; + form.appendChild(csrfToken); + } + + document.body.appendChild(form); + form.submit(); } function deleteListRow(savedListID, sessionCookie, numberEntries) @@ -350,4 +377,3 @@ function addItemsToList(sessionCookie, dataItemType) false ); } - diff --git a/js/quickAction.js b/js/quickAction.js index 5156ad009..75a825010 100755 --- a/js/quickAction.js +++ b/js/quickAction.js @@ -121,3 +121,72 @@ function showQuickActionAddToPipeline(menuDataItemId) /* Create a popup window for adding this candidate to the job order / pipeline */ showPopWin(CATSIndexName + '?m=candidates&a=considerForJobSearch&candidateID=' + menuDataItemId, 750, 390, null); }; + +function quickActionPostFromUrl(url, confirmMessage) +{ + if (confirmMessage && !confirm(confirmMessage)) + { + return false; + } + + var parts = url.split('?'); + var action = parts[0]; + var query = (parts.length > 1) ? parts[1] : ''; + var params = {}; + var actionParams = []; + + if (query.length > 0) + { + var pairs = query.split('&'); + for (var i = 0; i < pairs.length; i++) + { + if (pairs[i] === '') + { + continue; + } + + var keyValue = pairs[i].split('='); + var key = decodeURIComponent(keyValue[0].replace(/\+/g, ' ')); + var value = keyValue.length > 1 ? decodeURIComponent(keyValue[1].replace(/\+/g, ' ')) : ''; + + if (key === 'm' || key === 'a') + { + actionParams.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + } + else + { + params[key] = value; + } + } + } + + params.postback = 'postback'; + + if (typeof CATSCsrfToken != 'undefined' && CATSCsrfToken !== null && + CATSCsrfToken !== '' && typeof params.csrfToken == 'undefined') + { + params.csrfToken = CATSCsrfToken; + } + + var form = document.createElement('form'); + form.method = 'post'; + form.action = action + (actionParams.length ? ('?' + actionParams.join('&')) : ''); + + for (var name in params) + { + if (!params.hasOwnProperty(name)) + { + continue; + } + + var input = document.createElement('input'); + input.type = 'hidden'; + input.name = name; + input.value = params[name]; + form.appendChild(input); + } + + document.body.appendChild(form); + form.submit(); + return false; +} diff --git a/js/wizardIntro.js b/js/wizardIntro.js index f7c620e87..769ab26f9 100755 --- a/js/wizardIntro.js +++ b/js/wizardIntro.js @@ -60,7 +60,7 @@ function deleteUser(id) { failAction = 'alert("Unable to delete that user.");'; userActionSuccess = 'cancelAddUser(); loadPage("current");'; - userAction('DeleteUser&userID=' + id); + userActionPost('DeleteUser', 'userID=' + id); } function keyGood() @@ -253,3 +253,67 @@ function userAction(action) ajaxObj.open("GET",url,true); ajaxObj.send(null); } + +function userActionPost(action, postData) +{ + var ajaxObj; + var url = '?m=settings&a=ajax_wizard' + action; + var payload = 'postback=postback&' + postData; + + if (typeof CATSCsrfToken != 'undefined' && CATSCsrfToken !== null && + CATSCsrfToken !== '' && payload.indexOf('csrfToken=') == -1) + { + payload += '&csrfToken=' + encodeURIComponent(CATSCsrfToken); + } + + try + { + // Firefox, Opera 8.0+, Safari + ajaxObj = new XMLHttpRequest(); + } + catch (e) + { + // Internet Explorer + try + { + ajaxObj = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + ajaxObj = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e) + { + alert("Your browser does not support AJAX!"); + return false; + } + } + } + ajaxObj.onreadystatechange = function() + { + if (ajaxObj.readyState == 4) + { + if (ajaxObj.responseText == 'Ok') + { + if (userActionSuccess != '') eval(userActionSuccess); + } + else + { + if (failAction != '') + { + eval(failAction); + } + else + { + alert(ajaxObj.responseText); + } + } + } + } + + ajaxObj.open("POST", url, true); + ajaxObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + ajaxObj.send(payload); +} diff --git a/lib/AJAXInterface.php b/lib/AJAXInterface.php index daf5fddf8..4dc50abc6 100755 --- a/lib/AJAXInterface.php +++ b/lib/AJAXInterface.php @@ -215,6 +215,22 @@ public function __construct() die(); } + if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') + { + $token = null; + + if (isset($_POST['csrfToken'])) + { + $token = $_POST['csrfToken']; + } + + if (!$_SESSION['CATS']->isCSRFTokenValid($token)) + { + $this->outputXMLErrorPage(-1, 'Invalid request.'); + die(); + } + } + /* Grab the current user's site ID. */ $this->_siteID = $_SESSION['CATS']->getSiteID(); diff --git a/lib/DataGrid.php b/lib/DataGrid.php index c79b94a26..43dfa2104 100755 --- a/lib/DataGrid.php +++ b/lib/DataGrid.php @@ -2009,6 +2009,80 @@ public function getInnerActionAreaItem($actionTitle, $actionURL, $allowAll = tru return $html; } + + /** + * Returns HTML to render a POST action under the action menu. + * + * @param string action title + * @param string action URL + * @param boolean (true) action can be applied to all items across every page + * @return string generated HTML + */ + public function getInnerActionAreaItemPost($actionTitle, $actionURL, $allowAll = true) + { + //TODO: If nothing is selected, display an error popup. + + $newParameterArraySelected = $this->_parameters; + $newParameterArraySelected['rangeStart'] = 0; + $newParameterArraySelected['maxResults'] = 100000000; + $newParameterArraySelected['exportIDs'] = ''; + $newParameterArraySelected['noSaveParameters'] = true; + + $newParameterArrayAll = $this->_parameters; + $newParameterArrayAll['rangeStart'] = 0; + $newParameterArrayAll['maxResults'] = 100000000; + $newParameterArrayAll['noSaveParameters'] = true; + + $instanceHash = md5($this->_instanceName); + $selectedParams = $allowAll ? serialize($newParameterArraySelected) : json_encode($newParameterArraySelected); + $allParams = serialize($newParameterArrayAll); + + $actionSeparator = (strpos($actionURL, '?') !== false) ? '&' : '?'; + $selectedURL = $actionURL + . $actionSeparator . 'i=' . urlencode($this->_instanceName) + . '&p=' . urlencode($selectedParams) + . '&dynamicArgument' . $instanceHash . '='; + $allURL = $actionURL + . $actionSeparator . 'i=' . urlencode($this->_instanceName) + . '&p=' . urlencode($allParams); + + $selectedURL = str_replace(array('\\', '\''), array('\\\\', '\\\''), $selectedURL); + $allURL = str_replace(array('\\', '\''), array('\\\\', '\\\''), $allURL); + + $selectedPostJS = sprintf( + "var url='%s' + urlEncode(serializeArray(exportArray%s));" + . "return quickActionPostFromUrl(url);", + $selectedURL, + $instanceHash + ); + + $allPostJS = sprintf( + "return quickActionPostFromUrl('%s');", + $allURL + ); + + if ($allowAll) + { + $html = sprintf( + '
%s
Selected | All
', + htmlspecialchars($actionTitle), + $instanceHash, + $selectedPostJS, + $allPostJS + ); + } + else + { + $html = sprintf( + '
%s
Selected
', + htmlspecialchars($actionTitle), + $instanceHash, + $selectedPostJS + ); + } + + return $html; + } /** * Returns HTML to render an action under the action menu which generates diff --git a/lib/Session.php b/lib/Session.php index 96ab845c7..483ebd30d 100755 --- a/lib/Session.php +++ b/lib/Session.php @@ -896,11 +896,26 @@ public function processLogin($username, $password, $addToHistory = true) // $domain = 'example.com'; // Adjust as needed $secure = true; // Adjust based on your environment $httponly = true; - $samesite = 'Strict'; + $samesite = 'Lax'; // Fixed setcookie call - define domain variable and remove invalid path format $domain = ''; // Use empty string for current domain - setcookie('session_cookie', $cookieValue, $expires, $path, $domain, $secure, $httponly); + // TODO: Drop PHP < 7.3 fallback and always use setcookie() options array once legacy PHP is no longer supported. + if (PHP_VERSION_ID >= 70300) + { + setcookie('session_cookie', $cookieValue, array( + 'expires' => $expires, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httponly, + 'samesite' => $samesite + )); + } + else + { + setcookie('session_cookie', $cookieValue, $expires, $path, $domain, $secure, $httponly); + } // Update the user session in the database $sql = sprintf( @@ -1174,6 +1189,56 @@ public function retrieveValueByName($name) return $this->_storedValues[$name]; } + /** + * Returns the current session CSRF token. If no token exists yet, + * a new token is generated and stored. + * + * @return string CSRF token + */ + public function getCSRFToken() + { + $token = $this->retrieveValueByName('csrfToken'); + + if (!is_string($token) || $token === '') + { + $token = $this->rotateCSRFToken(); + } + + return $token; + } + + /** + * Generates a new CSRF token and stores it in the session. + * + * @return string new CSRF token + */ + public function rotateCSRFToken() + { + $token = bin2hex(random_bytes(32)); + + $this->storeValueByName('csrfToken', $token); + + return $token; + } + + /** + * Validates a CSRF token against the current session token. + * + * @param string token + * @return boolean valid token + */ + public function isCSRFTokenValid($token) + { + $storedToken = $this->retrieveValueByName('csrfToken'); + + if (!is_string($storedToken) || $storedToken === '' || !is_string($token)) + { + return false; + } + + return hash_equals($storedToken, $token); + } + /** * Returns a column layout. Only called by the datagrid class. * Column layouts are loaded into the session from the database when the user logs in. diff --git a/lib/TemplateUtility.php b/lib/TemplateUtility.php index 40c526f2f..957d7518f 100755 --- a/lib/TemplateUtility.php +++ b/lib/TemplateUtility.php @@ -151,9 +151,17 @@ public static function printHeaderBlock($showTopRight = true) } } - echo ''; + echo '
'; + if (isset($_SESSION['CATS']) && $_SESSION['CATS']->isLoggedIn()) + { + $csrfToken = htmlspecialchars($_SESSION['CATS']->getCSRFToken(), ENT_QUOTES, 'UTF-8'); + echo ''; + } + echo '', "\n"; + echo '
', "\n"; echo '', "\n"; // End top-right action block @@ -417,16 +425,24 @@ public static function printSavedSearch($savedSearchRS) if (count($savedSearchSaved) >= RECENT_SEARCH_MAX_ITEMS) { - echo ''; + $openTag = ''; + $closeTag = ''; } else { - echo ''; + $openTag = '
' + . '' + . '' + . '' + . '
'; } - echo '
 ', "\n"; + echo $openTag, + '', + $closeTag, + ' ', "\n"; $escapedURL = htmlspecialchars($savedSearchRow['URL']); @@ -481,9 +497,12 @@ public static function printSavedSearch($savedSearchRS) } $escapedURL = '/'.$escapedURL; - echo '', - ' '; + echo '
', + '', + '', + '', + '
 '; echo '', "\n"; echo '', "\n"; echo '', "\n"; + if (isset($_SESSION['CATS']) && $_SESSION['CATS']->isLoggedIn()) + { + $csrfToken = $_SESSION['CATS']->getCSRFToken(); + echo '', "\n"; + echo '', "\n"; + } $headIncludes[] = 'main.css'; diff --git a/main.css b/main.css index b806329e8..7af638d50 100755 --- a/main.css +++ b/main.css @@ -424,7 +424,8 @@ p.noteUnsized color: #666666; } -p.warning +p.warning, +div.warning { background-image: url('images/orange_gradient.jpg'); background-repeat: repeat-x; @@ -776,6 +777,29 @@ p.freeformbottom border: 1px solid #a4a4a4; } +button.linkButton +{ + background: none; + border: none; + padding: 0; + margin: 0; + cursor: pointer; + display: inline; + color: #00008b; + text-decoration: none; + font: normal normal normal 12px/130% Arial, Tahoma, sans-serif; +} + +button.linkButton:hover +{ + text-decoration: underline; +} + +button.linkButton.jobLinkHot +{ + color: #ff0000; +} + .buttonCalendar { height: 20px; diff --git a/modules/calendar/CalendarUI.js b/modules/calendar/CalendarUI.js index 5d0755844..765e37a21 100755 --- a/modules/calendar/CalendarUI.js +++ b/modules/calendar/CalendarUI.js @@ -424,8 +424,34 @@ function confirmDeleteEntry() return; } - document.location = getCurrentCalendarUrl() + '&a=deleteEvent&eventID=' - + document.getElementById('eventIDEdit').value; + var form = document.createElement('form'); + form.method = 'post'; + form.action = getCurrentCalendarUrl() + '&a=deleteEvent'; + + var postback = document.createElement('input'); + postback.type = 'hidden'; + postback.name = 'postback'; + postback.value = 'postback'; + form.appendChild(postback); + + var eventID = document.createElement('input'); + eventID.type = 'hidden'; + eventID.name = 'eventID'; + eventID.value = document.getElementById('eventIDEdit').value; + form.appendChild(eventID); + + if (typeof CATSCsrfToken != 'undefined' && CATSCsrfToken !== null && + CATSCsrfToken !== '') + { + var csrfToken = document.createElement('input'); + csrfToken.type = 'hidden'; + csrfToken.name = 'csrfToken'; + csrfToken.value = CATSCsrfToken; + form.appendChild(csrfToken); + } + + document.body.appendChild(form); + form.submit(); } /* Hides all the main window views (month, week, day, etc). */ diff --git a/modules/calendar/CalendarUI.php b/modules/calendar/CalendarUI.php index 234a38d00..24fe19448 100755 --- a/modules/calendar/CalendarUI.php +++ b/modules/calendar/CalendarUI.php @@ -77,7 +77,14 @@ public function handleRequest() break; case 'deleteEvent': - $this->onDeleteEvent(); + if ($this->isPostBack()) + { + $this->onDeleteEvent(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'showCalendar': @@ -692,12 +699,12 @@ private function onDeleteEvent() } /* Bail out if we don't have a valid event ID. */ - if (!$this->isRequiredIDValid('eventID', $_GET)) + if (!$this->isRequiredIDValid('eventID', $_POST)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid event ID.'); } - $eventID = $_GET['eventID']; + $eventID = $_POST['eventID']; if (!eval(Hooks::get('CALENDAR_DELETE_PRE'))) return; diff --git a/modules/candidates/CandidatesUI.php b/modules/candidates/CandidatesUI.php index 7b7d13aef..971045048 100755 --- a/modules/candidates/CandidatesUI.php +++ b/modules/candidates/CandidatesUI.php @@ -125,13 +125,20 @@ public function handleRequest() break; - case 'delete': - if ($this->getUserAccessLevel('candidates.delete') < ACCESS_LEVEL_DELETE) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->onDelete(); - break; + case 'delete': + if ($this->getUserAccessLevel('candidates.delete') < ACCESS_LEVEL_DELETE) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->onDelete(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; case 'search': if ($this->getUserAccessLevel('candidates.search') < ACCESS_LEVEL_READ) @@ -180,13 +187,20 @@ public function handleRequest() * Add candidate to pipeline after selecting a job order for which * to consider a candidate (in the modal window). */ - case 'addToPipeline': - if ($this->getUserAccessLevel('pipelines.addToPipeline') < ACCESS_LEVEL_EDIT) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->onAddToPipeline(); - break; + case 'addToPipeline': + if ($this->getUserAccessLevel('pipelines.addToPipeline') < ACCESS_LEVEL_EDIT) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->onAddToPipeline(); + } + else + { + CommonErrors::fatalModal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; case 'addCandidateTags': if ($this->getUserAccessLevel('candidates.addCandidateTags') < ACCESS_LEVEL_EDIT ) @@ -221,13 +235,20 @@ public function handleRequest() break; /* Remove a candidate from a pipeline. */ - case 'removeFromPipeline': - if ($this->getUserAccessLevel('pipelines.removeFromPipeline') < ACCESS_LEVEL_DELETE) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->onRemoveFromPipeline(); - break; + case 'removeFromPipeline': + if ($this->getUserAccessLevel('pipelines.removeFromPipeline') < ACCESS_LEVEL_DELETE) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->onRemoveFromPipeline(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; case 'addEditImage': if ($this->getUserAccessLevel('candidates.addEditImage') < ACCESS_LEVEL_EDIT) @@ -266,22 +287,36 @@ public function handleRequest() break; /* Administrators can hide a candidate from a site with this action. */ - case 'administrativeHideShow': - if ($this->getUserAccessLevel('candidates.hidden') < ACCESS_LEVEL_MULTI_SA) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->administrativeHideShow(); - break; + case 'administrativeHideShow': + if ($this->getUserAccessLevel('candidates.hidden') < ACCESS_LEVEL_MULTI_SA) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->administrativeHideShow(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; /* Delete a candidate attachment */ - case 'deleteAttachment': - if ($this->getUserAccessLevel('candidates.deleteAttachment') < ACCESS_LEVEL_DELETE) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->onDeleteAttachment(); - break; + case 'deleteAttachment': + if ($this->getUserAccessLevel('candidates.deleteAttachment') < ACCESS_LEVEL_DELETE) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->onDeleteAttachment(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; /* Hot List Page */ /* FIXME: function savedList() missing @@ -331,30 +366,51 @@ public function handleRequest() $this->mergeDuplicates(); break; - case 'mergeInfo': - if ($this->getUserAccessLevel('candidates.duplicates') < ACCESS_LEVEL_SA) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->mergeDuplicatesInfo(); - break; + case 'mergeInfo': + if ($this->getUserAccessLevel('candidates.duplicates') < ACCESS_LEVEL_SA) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->mergeDuplicatesInfo(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; /* Remove duplicity warning from a new candidate */ - case 'removeDuplicity': - if ($this->getUserAccessLevel('candidates.duplicates') < ACCESS_LEVEL_SA) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->removeDuplicity(); - break; - - case 'addDuplicates': - if ($this->getUserAccessLevel('candidates.duplicates') < ACCESS_LEVEL_SA) - { - CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); - } - $this->addDuplicates(); - break; + case 'removeDuplicity': + if ($this->getUserAccessLevel('candidates.duplicates') < ACCESS_LEVEL_SA) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->removeDuplicity(); + } + else + { + CommonErrors::fatalModal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; + + case 'addDuplicates': + if ($this->getUserAccessLevel('candidates.duplicates') < ACCESS_LEVEL_SA) + { + CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + if ($this->isPostBack()) + { + $this->addDuplicates(); + } + else + { + CommonErrors::fatalModal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; /* Main candidates page. */ case 'listByView': @@ -388,11 +444,42 @@ public function publicAddCandidate($isModal, $transferURI, $moduleDirectory) CommonErrors::fatalModal(COMMONERROR_RECORDERROR, $this, 'Failed to add candidate.'); } - $transferURI = str_replace( - '__CANDIDATE_ID__', $candidateID, $transferURI - ); - CATSUtility::transferRelativeURI($transferURI); - } + $transferURI = str_replace( + '__CANDIDATE_ID__', $candidateID, $transferURI + ); + + if (strpos($transferURI, 'a=addToPipeline') !== false) + { + parse_str($transferURI, $params); + $action = CATSUtility::getIndexName(); + if (isset($params['m']) && isset($params['a'])) + { + $action .= '?m=' . urlencode($params['m']) . '&a=' . urlencode($params['a']); + unset($params['m']); + unset($params['a']); + } + + echo ''; + echo '
'; + echo ''; + if (isset($_SESSION['CATS'])) + { + echo ''; + } + foreach ($params as $key => $value) + { + echo ''; + } + echo '
'; + echo ''; + echo ''; + return; + } + + CATSUtility::transferRelativeURI($transferURI); + } /* @@ -1404,15 +1491,15 @@ private function onEdit() /* * Called by handleRequest() to process deleting a candidate. */ - private function onDelete() - { - /* Bail out if we don't have a valid candidate ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) - { - CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); - } - - $candidateID = $_GET['candidateID']; + private function onDelete() + { + /* Bail out if we don't have a valid candidate ID. */ + if (!$this->isRequiredIDValid('candidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + + $candidateID = $_POST['candidateID']; if (!eval(Hooks::get('CANDIDATE_DELETE'))) return; @@ -1558,33 +1645,33 @@ private function considerForJobSearch($candidateIDArray = array()) * Called by handleRequest() to process adding a candidate to a pipeline * in the modal dialog. */ - private function onAddToPipeline() - { - /* Bail out if we don't have a valid job order ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); - } - - if (isset($_GET['candidateID'])) - { - /* Bail out if we don't have a valid candidate ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); - } - - $candidateIDArray = array($_GET['candidateID']); - } - else - { - if (!isset($_REQUEST['candidateIDArrayStored']) || !$this->isRequiredIDValid('candidateIDArrayStored', $_REQUEST, true)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidateIDArrayStored parameter.'); - return; - } - - $candidateIDArray = $_SESSION['CATS']->retrieveData($_REQUEST['candidateIDArrayStored']); + private function onAddToPipeline() + { + /* Bail out if we don't have a valid job order ID. */ + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); + } + + if (isset($_POST['candidateID'])) + { + /* Bail out if we don't have a valid candidate ID. */ + if (!$this->isRequiredIDValid('candidateID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + + $candidateIDArray = array($_POST['candidateID']); + } + else + { + if (!isset($_POST['candidateIDArrayStored']) || !$this->isRequiredIDValid('candidateIDArrayStored', $_POST, true)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidateIDArrayStored parameter.'); + return; + } + + $candidateIDArray = $_SESSION['CATS']->retrieveData($_POST['candidateIDArrayStored']); if (!is_array($candidateIDArray)) { @@ -1606,7 +1693,7 @@ private function onAddToPipeline() } - $jobOrderID = $_GET['jobOrderID']; + $jobOrderID = $_POST['jobOrderID']; if (!eval(Hooks::get('CANDIDATE_ADD_TO_PIPELINE_PRE'))) return; @@ -1855,22 +1942,22 @@ private function onAddActivityChangeStatus() * Called by handleRequest() to process removing a candidate from the * pipeline for a job order. */ - private function onRemoveFromPipeline() - { - /* Bail out if we don't have a valid candidate ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) - { - CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); - } - - /* Bail out if we don't have a valid job order ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) - { - CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); - } - - $candidateID = $_GET['candidateID']; - $jobOrderID = $_GET['jobOrderID']; + private function onRemoveFromPipeline() + { + /* Bail out if we don't have a valid candidate ID. */ + if (!$this->isRequiredIDValid('candidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + + /* Bail out if we don't have a valid job order ID. */ + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); + } + + $candidateID = $_POST['candidateID']; + $jobOrderID = $_POST['jobOrderID']; if (!eval(Hooks::get('CANDIDATE_REMOVE_FROM_PIPELINE_PRE'))) return; @@ -2360,22 +2447,22 @@ private function onCreateAttachment() /* * Called by handleRequest() to process deleting an attachment. */ - private function onDeleteAttachment() - { - /* Bail out if we don't have a valid attachment ID. */ - if (!$this->isRequiredIDValid('attachmentID', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); - } - - /* Bail out if we don't have a valid candidate ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); - } - - $candidateID = $_GET['candidateID']; - $attachmentID = $_GET['attachmentID']; + private function onDeleteAttachment() + { + /* Bail out if we don't have a valid attachment ID. */ + if (!$this->isRequiredIDValid('attachmentID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); + } + + /* Bail out if we don't have a valid candidate ID. */ + if (!$this->isRequiredIDValid('candidateID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + + $candidateID = $_POST['candidateID']; + $attachmentID = $_POST['attachmentID']; if (!eval(Hooks::get('CANDIDATE_ON_DELETE_ATTACHMENT_PRE'))) return; @@ -2391,24 +2478,24 @@ private function onDeleteAttachment() //TODO: Document me. //Only accessable by MSA users - hides this job order from everybody by - private function administrativeHideShow() - { - /* Bail out if we don't have a valid joborder ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) - { - CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid Job Order ID.'); - } - - /* Bail out if we don't have a valid status ID. */ - if (!$this->isRequiredIDValid('state', $_GET, true)) - { - CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid state ID.'); - } - - $candidateID = $_GET['candidateID']; - - // FIXME: Checkbox? - $state = (boolean) $_GET['state']; + private function administrativeHideShow() + { + /* Bail out if we don't have a valid joborder ID. */ + if (!$this->isRequiredIDValid('candidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid Job Order ID.'); + } + + /* Bail out if we don't have a valid status ID. */ + if (!$this->isRequiredIDValid('state', $_POST, true)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid state ID.'); + } + + $candidateID = $_POST['candidateID']; + + // FIXME: Checkbox? + $state = (boolean) $_POST['state']; $candidates = new Candidates($this->_siteID); $candidates->administrativeHideShow($candidateID, $state); @@ -3477,11 +3564,20 @@ private function findDuplicateCandidateSearch() $this->_template->display('./modules/candidates/LinkDuplicity.tpl'); } - private function mergeDuplicates() - { - $candidates = new Candidates($this->_siteID); - $oldCandidateID = $_GET['oldCandidateID']; - $newCandidateID = $_GET['newCandidateID']; + private function mergeDuplicates() + { + if (!$this->isRequiredIDValid('oldCandidateID', $_GET)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + if (!$this->isRequiredIDValid('newCandidateID', $_GET)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + + $candidates = new Candidates($this->_siteID); + $oldCandidateID = $_GET['oldCandidateID']; + $newCandidateID = $_GET['newCandidateID']; $rsOld = $candidates->getWithDuplicity($oldCandidateID); $rsNew = $candidates->getWithDuplicity($newCandidateID); @@ -3494,12 +3590,21 @@ private function mergeDuplicates() $this->_template->display('./modules/candidates/Merge.tpl'); } - private function mergeDuplicatesInfo() - { - $candidates = new Candidates($this->_siteID); - $params = array(); - $params['firstName'] = $_POST['firstName']; - $params['middleName'] = $_POST['middleName']; + private function mergeDuplicatesInfo() + { + $candidates = new Candidates($this->_siteID); + if (!$this->isRequiredIDValid('oldCandidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + if (!$this->isRequiredIDValid('newCandidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + + $params = array(); + $params['firstName'] = $_POST['firstName']; + $params['middleName'] = $_POST['middleName']; $params['lastName'] = $_POST['lastName']; if(isset($_POST['email'])) { @@ -3512,37 +3617,54 @@ private function mergeDuplicatesInfo() $params['phoneCell'] = $_POST['phoneCell']; $params['phoneWork'] = $_POST['phoneWork']; $params['phoneHome'] = $_POST['phoneHome']; - $params['address'] = $_POST['address']; - $params['website'] = $_POST['website']; - $params['oldCandidateID'] = $_POST['oldCandidateID']; - $params['newCandidateID'] = $_POST['newCandidateID']; - - $candidates->mergeDuplicates($params, $candidates->getWithDuplicity($params['newCandidateID'])); - $this->_template->assign('isFinishedMode', true); - $this->_template->display('./modules/candidates/Merge.tpl'); - } + $params['address'] = $_POST['address']; + $params['website'] = $_POST['website']; + $params['oldCandidateID'] = $_POST['oldCandidateID']; + $params['newCandidateID'] = $_POST['newCandidateID']; + + $candidates->mergeDuplicates($params, $candidates->getWithDuplicity($params['newCandidateID'])); + CATSUtility::transferRelativeURI( + 'm=candidates&a=show&candidateID=' . $params['oldCandidateID'] + ); + } - private function removeDuplicity() - { - $candidates = new Candidates($this->_siteID); - $oldCandidateID = $_GET['oldCandidateID']; - $newCandidateID = $_GET['newCandidateID']; - $candidates->removeDuplicity($oldCandidateID, $newCandidateID); - $url = CATSUtility::getIndexName()."?m=candidates"; - header("Location: " . $url); /* Redirect browser */ - exit(); - } + private function removeDuplicity() + { + $candidates = new Candidates($this->_siteID); + if (!$this->isRequiredIDValid('oldCandidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + if (!$this->isRequiredIDValid('newCandidateID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + $oldCandidateID = $_POST['oldCandidateID']; + $newCandidateID = $_POST['newCandidateID']; + $candidates->removeDuplicity($oldCandidateID, $newCandidateID); + $url = CATSUtility::getIndexName()."?m=candidates"; + header("Location: " . $url); /* Redirect browser */ + exit(); + } - private function addDuplicates() - { - $candidates = new Candidates($this->_siteID); - $oldCandidateID = $_GET['candidateID']; - $newCandidateID = $_GET['duplicateCandidateID']; - $candidates->addDuplicates($newCandidateID, $oldCandidateID); - $this->_template->assign('isFinishedMode', true); - $this->_template->display('./modules/candidates/LinkDuplicity.tpl'); - } + private function addDuplicates() + { + $candidates = new Candidates($this->_siteID); + if (!$this->isRequiredIDValid('candidateID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + if (!$this->isRequiredIDValid('duplicateCandidateID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); + } + $oldCandidateID = $_POST['candidateID']; + $newCandidateID = $_POST['duplicateCandidateID']; + $candidates->addDuplicates($newCandidateID, $oldCandidateID); + $this->_template->assign('isFinishedMode', true); + $this->_template->display('./modules/candidates/LinkDuplicity.tpl'); + } } ?> diff --git a/modules/candidates/ConsiderSearchModal.tpl b/modules/candidates/ConsiderSearchModal.tpl index cc0150418..82317b95b 100755 --- a/modules/candidates/ConsiderSearchModal.tpl +++ b/modules/candidates/ConsiderSearchModal.tpl @@ -72,9 +72,14 @@ _($data['jobID']); ?> -
- _($data['title']); ?> - +
+ + + + +
_($data['title']); ?> @@ -122,9 +127,14 @@ _($data['jobID']); ?> - - _($data['title']); ?> - +
+ + + + +
_($data['title']); ?> diff --git a/modules/candidates/LinkDuplicity.tpl b/modules/candidates/LinkDuplicity.tpl index 39d031519..f29dff9d6 100644 --- a/modules/candidates/LinkDuplicity.tpl +++ b/modules/candidates/LinkDuplicity.tpl @@ -63,18 +63,28 @@ - - _($data['firstName']); ?> - +
+ + + + +
_($data['firstName']); ?> - - _($data['lastName']); ?> - +
+ + + + +
_($data['lastName']); ?> @@ -116,18 +126,28 @@ - - _($data['firstName']); ?> - +
+ + + + +
_($data['firstName']); ?> - - _($data['lastName']); ?> - +
+ + + + +
_($data['lastName']); ?> diff --git a/modules/candidates/Merge.tpl b/modules/candidates/Merge.tpl index bebb5bd44..37d3ec413 100644 --- a/modules/candidates/Merge.tpl +++ b/modules/candidates/Merge.tpl @@ -16,8 +16,9 @@ - oldCandidateID; ?> /> - newCandidateID; ?> /> + + + diff --git a/modules/candidates/Show.tpl b/modules/candidates/Show.tpl index 92ca84f4e..f419fa3ac 100755 --- a/modules/candidates/Show.tpl +++ b/modules/candidates/Show.tpl @@ -43,7 +43,15 @@ use OpenCATS\UI\CandidateDuplicateQuickActionMenu;

Candidate Details

data['isAdminHidden'] == 1): ?> -

This Candidate is hidden. Only CATS Administrators can view it or search for it. To make it visible by the site users, click Here.

+
+ This Candidate is hidden. Only CATS Administrators can view it or search for it. To make it visible by the site users, click + + + + + + +
Original candidate 
@@ -225,9 +233,12 @@ use OpenCATS\UI\CandidateDuplicateQuickActionMenu; @@ -429,9 +443,13 @@ use OpenCATS\UI\CandidateDuplicateQuickActionMenu;      getUserAccessLevel('candidates.delete') >= ACCESS_LEVEL_DELETE): ?> - - delete Delete - + + + + +      privledgedUser): ?> @@ -442,13 +460,23 @@ use OpenCATS\UI\CandidateDuplicateQuickActionMenu; getUserAccessLevel('candidates.administrativeHideShow') >= ACCESS_LEVEL_MULTI_SA): ?> data['isAdminHidden'] == 1): ?> - - delete Administrative Show - + + + + + + - - delete Administrative Hide - + + + + + +      @@ -531,9 +559,12 @@ use OpenCATS\UI\CandidateDuplicateQuickActionMenu; getUserAccessLevel('pipelines.removeFromPipeline') >= ACCESS_LEVEL_DELETE): ?> - - - + + + + + + diff --git a/modules/candidates/dataGrids.php b/modules/candidates/dataGrids.php index 8570619a9..17f58a642 100755 --- a/modules/candidates/dataGrids.php +++ b/modules/candidates/dataGrids.php @@ -118,7 +118,7 @@ public function getInnerActionArea() // - Mass set rank (depends on each candidate having their own personal rank - are we going to do this?) $html = ''; - $html .= $this->getInnerActionAreaItem('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_CANDIDATE.'&savedListID='.$this->getMiscArgument(), false); + $html .= $this->getInnerActionAreaItemPost('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_CANDIDATE.'&savedListID='.$this->getMiscArgument(), false); $html .= $this->getInnerActionAreaItemPopup('Add To Job Order', CATSUtility::getIndexName().'?m=candidates&a=considerForJobSearch', 750, 460); if(MAIL_MAILER != 0 && $_SESSION['CATS']->getAccessLevel('candidates.emailCandidates') >= ACCESS_LEVEL_SA) { @@ -133,4 +133,4 @@ public function getInnerActionArea() } -?> \ No newline at end of file +?> diff --git a/modules/candidates/quickAction-duplicates.js b/modules/candidates/quickAction-duplicates.js index 4e6221496..da9a40faa 100644 --- a/modules/candidates/quickAction-duplicates.js +++ b/modules/candidates/quickAction-duplicates.js @@ -13,7 +13,10 @@ quickAction.CandidateDuplicateMenu.prototype.getOptions = function() { return [ new quickAction.LinkMenuOption("Merge", this.urlDecode(this.mergeUrl), 0), - new quickAction.LinkMenuOption("Remove duplicity warning", this.urlDecode(this.removeUrl), 1) + new quickAction.MenuOption( + "Remove duplicity warning", + "return quickActionPostFromUrl('" + this.urlDecode(this.removeUrl) + "', 'Are you sure?');" + ) ]; } return null; diff --git a/modules/careers/CareersUI.php b/modules/careers/CareersUI.php index f47c92fb9..f02ad3e39 100755 --- a/modules/careers/CareersUI.php +++ b/modules/careers/CareersUI.php @@ -132,6 +132,11 @@ private function careersPage() switch ($pa) { case 'logout': + if ($_SERVER['REQUEST_METHOD'] !== 'POST') + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + if ($isRegistrationEnabled) { // Remove the saved information cookie @@ -246,18 +251,24 @@ private function careersPage() ); $content = str_replace('', '', $content); + $attachmentIDValue = $latestAttachment ? $latestAttachment : -1; $content = sprintf( '
', - CATSUtility::getIndexName(), - $latestAttachment ? $latestAttachment : -1 - ) . $content . '' + . 'action="%s?m=careers&p=onRegisteredCandidateProfile">', + CATSUtility::getIndexName() + ) . '' + . $content . '' . (isset($_GET[$id='isPostBack']) && !strcmp($_GET[$id], 'yes') ? '' : ''); $template['Content'] = $content; } else if ($p == 'onRegisteredCandidateProfile' && $isRegistrationEnabled) { + if ($_SERVER['REQUEST_METHOD'] !== 'POST') + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + // Get information about the candidate from the cookie $fields = $this->getCookieFields($siteID); $candidate = $this->ProcessCandidateRegistration($siteID, $template['Content - Candidate Registration'], $fields, true); @@ -288,8 +299,16 @@ private function careersPage() } // Get the attachment to replace (if exists) - $attachmentID = isset($_GET[$id='attachmentID']) ? $_GET[$id] : -1; - $attachmentID = $attachmentID != -1 ? $attachmentID : false; + $attachmentID = false; + if (isset($_POST['attachmentID'])) + { + if (!$this->isOptionalIDValid('attachmentID', $_POST)) + { + CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); + } + + $attachmentID = $_POST['attachmentID'] != '-1' ? $_POST['attachmentID'] : false; + } $attachmentsLib = new Attachments($siteID); $candidatesLib = new Candidates($siteID); diff --git a/modules/companies/CompaniesUI.php b/modules/companies/CompaniesUI.php index 59c5f6435..471056d57 100755 --- a/modules/companies/CompaniesUI.php +++ b/modules/companies/CompaniesUI.php @@ -125,7 +125,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onDelete(); + if ($this->isPostBack()) + { + $this->onDelete(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'search': @@ -171,7 +178,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onDeleteAttachment(); + if ($this->isPostBack()) + { + $this->onDeleteAttachment(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; /* Main companies page. */ @@ -869,13 +883,13 @@ private function onEdit() private function onDelete() { /* Bail out if we don't have a valid company ID. */ - if (!$this->isRequiredIDValid('companyID', $_GET)) + if (!$this->isRequiredIDValid('companyID', $_POST)) { $this->listByView('Invalid company ID.'); return; } - $companyID = $_GET['companyID']; + $companyID = $_POST['companyID']; $companies = new Companies($this->_siteID); $rs = $companies->get($companyID); @@ -1130,19 +1144,19 @@ private function onCreateAttachment() private function onDeleteAttachment() { /* Bail out if we don't have a valid attachment ID. */ - if (!$this->isRequiredIDValid('attachmentID', $_GET)) + if (!$this->isRequiredIDValid('attachmentID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); } /* Bail out if we don't have a valid joborder ID. */ - if (!$this->isRequiredIDValid('companyID', $_GET)) + if (!$this->isRequiredIDValid('companyID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid company ID.'); } - $companyID = $_GET['companyID']; - $attachmentID = $_GET['attachmentID']; + $companyID = $_POST['companyID']; + $attachmentID = $_POST['attachmentID']; if (!eval(Hooks::get('CLIENTS_ON_DELETE_ATTACHMENT_PRE'))) return; diff --git a/modules/companies/Show.tpl b/modules/companies/Show.tpl index ff6100d6a..72b9d4b3b 100755 --- a/modules/companies/Show.tpl +++ b/modules/companies/Show.tpl @@ -175,9 +175,12 @@ use OpenCATS\UI\QuickActionMenu;
@@ -224,9 +227,13 @@ use OpenCATS\UI\QuickActionMenu;      getUserAccessLevel('companies.delete') >= ACCESS_LEVEL_DELETE && $this->data['defaultCompany'] != 1): ?> - - delete Delete - + + + + +      privledgedUser): ?> diff --git a/modules/companies/dataGrids.php b/modules/companies/dataGrids.php index f370bdd5e..f269ccc42 100644 --- a/modules/companies/dataGrids.php +++ b/modules/companies/dataGrids.php @@ -140,7 +140,7 @@ public function getInnerActionArea() // - Mass set rank (depends on each candidate having their own personal rank - are we going to do this?) $html = ''; - $html .= $this->getInnerActionAreaItem('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_COMPANY.'&savedListID='.$this->getMiscArgument(), false); + $html .= $this->getInnerActionAreaItemPost('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_COMPANY.'&savedListID='.$this->getMiscArgument(), false); $html .= $this->getInnerActionAreaItem('Export', CATSUtility::getIndexName().'?m=export&a=exportByDataGrid'); $html .= parent::getInnerActionArea(); @@ -149,4 +149,4 @@ public function getInnerActionArea() } } -?> \ No newline at end of file +?> diff --git a/modules/contacts/ContactsUI.php b/modules/contacts/ContactsUI.php index c7a9bf28d..ebfbb9260 100755 --- a/modules/contacts/ContactsUI.php +++ b/modules/contacts/ContactsUI.php @@ -127,7 +127,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onDelete(); + if ($this->isPostBack()) + { + $this->onDelete(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'search': @@ -866,12 +873,12 @@ private function onDelete() { /* Bail out if we don't have a valid contact ID. */ - if (!$this->isRequiredIDValid('contactID', $_GET)) + if (!$this->isRequiredIDValid('contactID', $_POST)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.'); } - $contactID = $_GET['contactID']; + $contactID = $_POST['contactID']; if (!eval(Hooks::get('CONTACTS_DELETE_PRE'))) return; diff --git a/modules/contacts/Show.tpl b/modules/contacts/Show.tpl index 603b3c354..5aa87bbd2 100755 --- a/modules/contacts/Show.tpl +++ b/modules/contacts/Show.tpl @@ -206,9 +206,13 @@ use OpenCATS\UI\QuickActionMenu;      getUserAccessLevel('contacts.delete') >= ACCESS_LEVEL_DELETE): ?> - - delete Delete - + + + + +      privledgedUser): ?> diff --git a/modules/contacts/dataGrids.php b/modules/contacts/dataGrids.php index b841c2570..0cb7c2498 100644 --- a/modules/contacts/dataGrids.php +++ b/modules/contacts/dataGrids.php @@ -133,7 +133,7 @@ public function getInnerActionArea() { $html = ''; - $html .= $this->getInnerActionAreaItem('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_CONTACT.'&savedListID='.$this->getMiscArgument(), false); + $html .= $this->getInnerActionAreaItemPost('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_CONTACT.'&savedListID='.$this->getMiscArgument(), false); $html .= $this->getInnerActionAreaItem('Export', CATSUtility::getIndexName().'?m=export&a=exportByDataGrid'); $html .= parent::getInnerActionArea(); @@ -143,4 +143,4 @@ public function getInnerActionArea() } } -?> \ No newline at end of file +?> diff --git a/modules/home/HomeUI.php b/modules/home/HomeUI.php index d544fc66f..687c7ae2c 100755 --- a/modules/home/HomeUI.php +++ b/modules/home/HomeUI.php @@ -63,13 +63,27 @@ public function handleRequest() case 'deleteSavedSearch': include_once(LEGACY_ROOT . '/lib/Search.php'); - $this->deleteSavedSearch(); + if ($this->isPostBack()) + { + $this->deleteSavedSearch(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'addSavedSearch': include_once(LEGACY_ROOT . '/lib/Search.php'); - $this->addSavedSearch(); + if ($this->isPostBack()) + { + $this->addSavedSearch(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; /* FIXME: undefined function getAttachment() @@ -140,18 +154,18 @@ private function home() private function deleteSavedSearch() { - if (!isset($_GET['searchID'])) + if (!isset($_POST['searchID'])) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'No search ID specified.'); } - if (!isset($_GET['currentURL'])) + if (!isset($_POST['currentURL'])) { CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'No current URL specified.'); } - $searchID = $_GET['searchID']; - $currentURL = $_GET['currentURL']; + $searchID = $_POST['searchID']; + $currentURL = $_POST['currentURL']; if (!eval(Hooks::get('HOME_DELETE_SAVED_SEARCH_PRE'))) return; @@ -165,18 +179,18 @@ private function deleteSavedSearch() private function addSavedSearch() { - if (!isset($_GET['searchID'])) + if (!isset($_POST['searchID'])) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'No search ID specified.'); } - if (!isset($_GET['currentURL'])) + if (!isset($_POST['currentURL'])) { CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'No current URL specified.'); } - $searchID = $_GET['searchID']; - $currentURL = $_GET['currentURL']; + $searchID = $_POST['searchID']; + $currentURL = $_POST['currentURL']; if (!eval(Hooks::get('HOME_ADD_SAVED_SEARCH_PRE'))) return; diff --git a/modules/import/Import1.tpl b/modules/import/Import1.tpl index 57d5a46d1..6dafcf7e8 100755 --- a/modules/import/Import1.tpl +++ b/modules/import/Import1.tpl @@ -104,10 +104,16 @@
isPopup): ?> getUserAccessLevel('candidates.deleteAttachment') >= ACCESS_LEVEL_DELETE): ?> - - - +
+ + + + +
     @@ -380,9 +391,12 @@ use OpenCATS\UI\CandidateDuplicateQuickActionMenu;
isPopup): ?> getUserAccessLevel('candidates.deleteAttachment') >= ACCESS_LEVEL_DELETE): ?> - - - +
+ + + + +
_($attachmentsData['dateCreated']) ?> getUserAccessLevel('companies.deleteAttachment') >= ACCESS_LEVEL_DELETE): ?> - - - +
+ + + + +
- +
+ + +
- +
+ + +
diff --git a/modules/import/ImportCommits.tpl b/modules/import/ImportCommits.tpl index a3121dda9..f60bfc3fd 100755 --- a/modules/import/ImportCommits.tpl +++ b/modules/import/ImportCommits.tpl @@ -38,8 +38,16 @@ data as $data): ?> Import # - entries added to database.
- - +
+ + + +
+
+ + + +


@@ -59,8 +67,16 @@ - - +
+ + + +
+
+ + + +
diff --git a/modules/import/ImportRecent.tpl b/modules/import/ImportRecent.tpl index 24b1ab345..d1b94959a 100755 --- a/modules/import/ImportRecent.tpl +++ b/modules/import/ImportRecent.tpl @@ -38,7 +38,11 @@ data as $data): ?> Import # - entries added to database.
- +
+ + + +


@@ -58,7 +62,11 @@ - +
+ + + +
diff --git a/modules/import/ImportUI.php b/modules/import/ImportUI.php index 97c2e6149..6d6a5e7b7 100755 --- a/modules/import/ImportUI.php +++ b/modules/import/ImportUI.php @@ -67,7 +67,14 @@ public function handleRequest() switch ($action) { case 'revert': - $this->revert(); + if ($this->isPostBack()) + { + $this->revert(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'viewerrors': @@ -107,11 +114,25 @@ public function handleRequest() break; case 'importBulkResumes': - $this->importBulkResumes(); + if ($this->isPostBack()) + { + $this->importBulkResumes(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'deleteBulkResumes': - $this->deleteBulkResumes(); + if ($this->isPostBack()) + { + $this->deleteBulkResumes(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'import': @@ -133,13 +154,13 @@ public function handleRequest() */ private function revert() { - if (!$this->isRequiredIDValid('importID', $_GET)) + if (!$this->isRequiredIDValid('importID', $_POST)) { $this->import(); return; } - $importID = $_GET['importID']; + $importID = $_POST['importID']; $import = new Import($this->_siteID); $tableName = $import->get($importID); diff --git a/modules/import/ajax/processMassImportItem.php b/modules/import/ajax/processMassImportItem.php index 7d2fb6f79..fe5a67193 100755 --- a/modules/import/ajax/processMassImportItem.php +++ b/modules/import/ajax/processMassImportItem.php @@ -32,6 +32,11 @@ $interface = new SecureAJAXInterface(); +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + die('Invalid request.'); +} + if (!isset($_SESSION['CATS']->massImportFiles) || !isset($_SESSION['CATS']->massImportDirectory)) { diff --git a/modules/install/ajax/attachmentsReindex.php b/modules/install/ajax/attachmentsReindex.php index e25e2bd58..a23c97412 100755 --- a/modules/install/ajax/attachmentsReindex.php +++ b/modules/install/ajax/attachmentsReindex.php @@ -25,6 +25,24 @@ * */ +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + header('Content-Type: text/html; charset=UTF-8'); + + $actionURL = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); + + echo '', + 'OpenCATS Attachment Reindex', + '

This maintenance action must be triggered via POST.

', + '

This starts the attachment reindex process.

', + '
', + '', + '', + '
', + ''; + die(); +} + include_once('./config.php'); include_once(LEGACY_ROOT . '/lib/DatabaseConnection.php'); include_once(LEGACY_ROOT . '/lib/ModuleUtility.php'); diff --git a/modules/install/ajax/attachmentsToThreeDirectory.php b/modules/install/ajax/attachmentsToThreeDirectory.php index b56902158..11329abb6 100755 --- a/modules/install/ajax/attachmentsToThreeDirectory.php +++ b/modules/install/ajax/attachmentsToThreeDirectory.php @@ -27,6 +27,24 @@ * $Id: attachmentsToThreeDirectory.php 2336 2007-04-14 22:01:51Z will $ */ +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + header('Content-Type: text/html; charset=UTF-8'); + + $actionURL = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); + + echo '', + 'OpenCATS Attachment Migration', + '

This maintenance action must be triggered via POST.

', + '

This starts the attachment migration to the three-directory layout.

', + '
', + '', + '', + '
', + ''; + die(); +} + include_once('./config.php'); include_once(LEGACY_ROOT . '/lib/DatabaseConnection.php'); diff --git a/modules/install/ajax/maint.php b/modules/install/ajax/maint.php index 020d99e6b..3a3fba924 100755 --- a/modules/install/ajax/maint.php +++ b/modules/install/ajax/maint.php @@ -27,6 +27,24 @@ * $Id: maint.php 3346 2007-10-29 22:40:53Z brian $ */ +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + header('Content-Type: text/html; charset=UTF-8'); + + $actionURL = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); + + echo '', + 'OpenCATS Maintenance', + '

This maintenance action must be triggered via POST.

', + '

This page starts maintenance mode and related installer tasks.

', + '
', + '', + '', + '
', + ''; + die(); +} + if (file_exists('./modules.cache')) { @unlink('./modules.cache'); diff --git a/modules/install/ajax/ui.php b/modules/install/ajax/ui.php index 53db04e79..957fbdae6 100755 --- a/modules/install/ajax/ui.php +++ b/modules/install/ajax/ui.php @@ -42,6 +42,13 @@ } @ini_set('memory_limit', '192M'); +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + die('Invalid request.'); +} + +$_REQUEST = $_POST; + if (file_exists('modules.cache')) @unlink('modules.cache'); if (!isset($_REQUEST['a']) || empty($_REQUEST['a'])) diff --git a/modules/joborders/ConsiderSearchModal.tpl b/modules/joborders/ConsiderSearchModal.tpl index 160bb7329..c5cad4193 100755 --- a/modules/joborders/ConsiderSearchModal.tpl +++ b/modules/joborders/ConsiderSearchModal.tpl @@ -70,15 +70,25 @@ - - _($data['firstName']); ?> - +
+ + + + +
  - - _($data['lastName']); ?> - +
+ + + + +
  @@ -109,4 +119,3 @@ - diff --git a/modules/joborders/JobOrdersUI.php b/modules/joborders/JobOrdersUI.php index ce7ae0f02..56288972b 100755 --- a/modules/joborders/JobOrdersUI.php +++ b/modules/joborders/JobOrdersUI.php @@ -150,7 +150,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onDelete(); + if ($this->isPostBack()) + { + $this->onDelete(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; case 'search': @@ -219,7 +226,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onAddToPipeline(); + if ($this->isPostBack()) + { + $this->onAddToPipeline(); + } + else + { + CommonErrors::fatalModal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; /* @@ -247,7 +261,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onRemoveFromPipeline(); + if ($this->isPostBack()) + { + $this->onRemoveFromPipeline(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; /* Add an attachment */ @@ -276,7 +297,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->onDeleteAttachment(); + if ($this->isPostBack()) + { + $this->onDeleteAttachment(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; /* FIXME: function setCandidateJobOrder() does not exist @@ -294,7 +322,14 @@ public function handleRequest() { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } - $this->administrativeHideShow(); + if ($this->isPostBack()) + { + $this->administrativeHideShow(); + } + else + { + CommonErrors::fatal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } break; /* Main job orders page. */ @@ -1145,12 +1180,12 @@ private function onEdit() private function onDelete() { /* Bail out if we don't have a valid job order ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); } - $jobOrderID = $_GET['jobOrderID']; + $jobOrderID = $_POST['jobOrderID']; if (!eval(Hooks::get('JO_ON_DELETE_PRE'))) return; @@ -1271,19 +1306,19 @@ private function onConsiderCandidateSearch() private function onAddToPipeline() { /* Bail out if we don't have a valid job order ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); } /* Bail out if we don't have a valid candidate ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) + if (!$this->isRequiredIDValid('candidateID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); } - $jobOrderID = $_GET['jobOrderID']; - $candidateID = $_GET['candidateID']; + $jobOrderID = $_POST['jobOrderID']; + $candidateID = $_POST['candidateID']; if (!eval(Hooks::get('JO_ON_ADD_PIPELINE'))) return; @@ -1562,19 +1597,19 @@ private function onRemoveFromPipeline() { /* Bail out if we don't have a valid candidate ID. */ - if (!$this->isRequiredIDValid('candidateID', $_GET)) + if (!$this->isRequiredIDValid('candidateID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); } /* Bail out if we don't have a valid job order ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); } - $candidateID = $_GET['candidateID']; - $jobOrderID = $_GET['jobOrderID']; + $candidateID = $_POST['candidateID']; + $jobOrderID = $_POST['jobOrderID']; if (!eval(Hooks::get('JO_ON_REMOVE_PIPELINE'))) return; @@ -1821,19 +1856,19 @@ private function onCreateAttachment() private function onDeleteAttachment() { /* Bail out if we don't have a valid attachment ID. */ - if (!$this->isRequiredIDValid('attachmentID', $_GET)) + if (!$this->isRequiredIDValid('attachmentID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); } /* Bail out if we don't have a valid joborder ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid Job Order ID.'); } - $jobOrderID = $_GET['jobOrderID']; - $attachmentID = $_GET['attachmentID']; + $jobOrderID = $_POST['jobOrderID']; + $attachmentID = $_POST['attachmentID']; if (!eval(Hooks::get('JO_ON_DELETE_ATTACHMENT_PRE'))) return; @@ -1852,21 +1887,21 @@ private function onDeleteAttachment() private function administrativeHideShow() { /* Bail out if we don't have a valid joborder ID. */ - if (!$this->isRequiredIDValid('jobOrderID', $_GET)) + if (!$this->isRequiredIDValid('jobOrderID', $_POST)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid Job Order ID.'); } /* Bail out if we don't have a valid status ID. */ - if (!$this->isRequiredIDValid('state', $_GET, true)) + if (!$this->isRequiredIDValid('state', $_POST, true)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid state ID.'); } - $jobOrderID = $_GET['jobOrderID']; + $jobOrderID = $_POST['jobOrderID']; // FIXME: Checkbox? - (boolean) $state = $_GET['state']; + $state = (boolean) $_POST['state']; $joborders = new JobOrders($this->_siteID); $joborders->administrativeHideShow($jobOrderID, $state); diff --git a/modules/joborders/Show.tpl b/modules/joborders/Show.tpl index 3e566aabc..79230c065 100755 --- a/modules/joborders/Show.tpl +++ b/modules/joborders/Show.tpl @@ -25,7 +25,15 @@ use OpenCATS\UI\QuickActionMenu;

Job Order Details

data['isAdminHidden'] == 1): ?> -

This Job Order is hidden. Only CATS Administrators can view it or search for it. To make it visible by the site users, click Here.

+
+ This Job Order is hidden. Only CATS Administrators can view it or search for it. To make it visible by the site users, click +
+ + + + +
+
frozen)): ?> @@ -252,9 +260,12 @@ use OpenCATS\UI\QuickActionMenu; isPopup): ?> getUserAccessLevel('joborders.deleteAttachment') >= ACCESS_LEVEL_DELETE): ?> - - - +
+ + + + +
@@ -327,20 +338,34 @@ use OpenCATS\UI\QuickActionMenu;      getUserAccessLevel('joborders.delete') >= ACCESS_LEVEL_DELETE): ?> - - delete Delete - +      getUserAccessLevel('joborders.hidden') >= ACCESS_LEVEL_MULTI_SA): ?> data['isAdminHidden'] == 1): ?> - - delete Administrative Show - +
+ + + + +
- - delete Administrative Hide - +
+ + + + +
     diff --git a/modules/joborders/dataGrids.php b/modules/joborders/dataGrids.php index 55bf1ed21..13b14f3e2 100644 --- a/modules/joborders/dataGrids.php +++ b/modules/joborders/dataGrids.php @@ -143,7 +143,7 @@ public function getInnerActionArea() { $html = ''; - $html .= $this->getInnerActionAreaItem('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_JOBORDER.'&savedListID='.$this->getMiscArgument(), false); + $html .= $this->getInnerActionAreaItemPost('Remove From This List', CATSUtility::getIndexName().'?m=lists&a=removeFromListDatagrid&dataItemType='.DATA_ITEM_JOBORDER.'&savedListID='.$this->getMiscArgument(), false); $html .= $this->getInnerActionAreaItem('Export', CATSUtility::getIndexName().'?m=export&a=exportByDataGrid'); $html .= parent::getInnerActionArea(); @@ -154,4 +154,4 @@ public function getInnerActionArea() } -?> \ No newline at end of file +?> diff --git a/modules/lists/ListsUI.php b/modules/lists/ListsUI.php index b5f132c8a..c1dbdfffc 100755 --- a/modules/lists/ListsUI.php +++ b/modules/lists/ListsUI.php @@ -88,13 +88,27 @@ public function handleRequest() $this->addToListFromDatagridModal(); break; - case 'removeFromListDatagrid': - $this->removeFromListDatagrid(); - break; - - case 'deleteStaticList': - $this->onDeleteStaticList(); - break; + case 'removeFromListDatagrid': + if ($this->isPostBack()) + { + $this->removeFromListDatagrid(); + } + else + { + CommonErrors::fatalModal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; + + case 'deleteStaticList': + if ($this->isPostBack()) + { + $this->onDeleteStaticList(); + } + else + { + CommonErrors::fatalModal(COMMONERROR_BADFIELDS, $this, 'Invalid request.'); + } + break; /* Main list page. */ case 'listByView': @@ -292,14 +306,14 @@ private function addToListFromDatagridModal() /* * Called by handleRequest to process the remove items from datagrid popup. */ - private function removeFromListDatagrid() - { - /* Bail out if we don't have a valid type. */ - if (!$this->isRequiredIDValid('dataItemType', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); - return; - } + private function removeFromListDatagrid() + { + /* Bail out if we don't have a valid type. */ + if (!$this->isRequiredIDValid('dataItemType', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); + return; + } $dataGrid = DataGrid::getFromRequest(); @@ -315,17 +329,17 @@ private function removeFromListDatagrid() } } - $dataItemType = $_GET['dataItemType']; + $dataItemType = $_POST['dataItemType']; $dataItemDesc = TemplateUtility::getDataItemTypeDescription($dataItemType); - if (!$this->isRequiredIDValid('savedListID', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid saved list ID.'); - return; - } - - $savedListID = $_GET['savedListID']; + if (!$this->isRequiredIDValid('savedListID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid saved list ID.'); + return; + } + + $savedListID = $_POST['savedListID']; /* Remove the items */ $savedLists = new SavedLists($this->_siteID); @@ -354,16 +368,16 @@ private function removeFromListDatagrid() /* * Called by handleRequest to delete a list. */ - private function onDeleteStaticList() - { - /* Bail out if we don't have a valid type. */ - if (!$this->isRequiredIDValid('savedListID', $_GET)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); - return; - } - - $savedListID = $_GET['savedListID']; + private function onDeleteStaticList() + { + /* Bail out if we don't have a valid type. */ + if (!$this->isRequiredIDValid('savedListID', $_POST)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); + return; + } + + $savedListID = $_POST['savedListID']; $savedLists = new SavedLists($this->_siteID); diff --git a/modules/lists/ajax/addToLists.php b/modules/lists/ajax/addToLists.php index 0e4396c0c..590233eca 100755 --- a/modules/lists/ajax/addToLists.php +++ b/modules/lists/ajax/addToLists.php @@ -62,19 +62,25 @@ function isRequiredValueValid($value) $interface = new SecureAJAXInterface(); -if (!isset($_REQUEST['listsToAdd'])) +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + +if (!isset($_POST['listsToAdd'])) { $interface->outputXMLErrorPage(-1, 'No listsToAdd passed.'); die(); } -if (!isset($_REQUEST['itemsToAdd'])) +if (!isset($_POST['itemsToAdd'])) { $interface->outputXMLErrorPage(-1, 'No itemsToAdd passed.'); die(); } -if (!$interface->isRequiredIDValid('dataItemType')) +if (!isset($_POST['dataItemType']) || !ctype_digit((string) $_POST['dataItemType'])) { $interface->outputXMLErrorPage(-1, 'Invalid saved list type.'); die(); @@ -82,9 +88,9 @@ function isRequiredValueValid($value) $siteID = $interface->getSiteID(); -$listsToAdd = explode(',', $_REQUEST['listsToAdd']); -$itemsToAdd = explode(',', $_REQUEST['itemsToAdd']); -$dataItemType = $_REQUEST['dataItemType']; +$listsToAdd = explode(',', $_POST['listsToAdd']); +$itemsToAdd = explode(',', $_POST['itemsToAdd']); +$dataItemType = $_POST['dataItemType']; foreach ($listsToAdd as $index => $data) { diff --git a/modules/lists/ajax/deleteList.php b/modules/lists/ajax/deleteList.php index e3a55757b..d4f6696e8 100755 --- a/modules/lists/ajax/deleteList.php +++ b/modules/lists/ajax/deleteList.php @@ -35,7 +35,13 @@ $interface = new SecureAJAXInterface(); -if (!$interface->isRequiredIDValid('savedListID')) +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + +if (!isset($_POST['savedListID']) || !ctype_digit((string) $_POST['savedListID'])) { $interface->outputXMLErrorPage(-1, 'Invalid saved list ID.'); die(); @@ -43,7 +49,7 @@ $siteID = $interface->getSiteID(); -$savedListID = $_REQUEST['savedListID']; +$savedListID = $_POST['savedListID']; $savedLists = new SavedLists($siteID); diff --git a/modules/lists/ajax/editListName.php b/modules/lists/ajax/editListName.php index 36014659f..23ffb25be 100755 --- a/modules/lists/ajax/editListName.php +++ b/modules/lists/ajax/editListName.php @@ -35,13 +35,19 @@ $interface = new SecureAJAXInterface(); -if (!$interface->isRequiredIDValid('savedListID')) +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + +if (!isset($_POST['savedListID']) || !ctype_digit((string) $_POST['savedListID'])) { $interface->outputXMLErrorPage(-1, 'Invalid saved list ID.'); die(); } -if (!isset($_REQUEST['savedListName'])) +if (!isset($_POST['savedListName'])) { $interface->outputXMLErrorPage(-1, 'Invalid name.'); die(); @@ -49,8 +55,8 @@ $siteID = $interface->getSiteID(); -$savedListID = $_REQUEST['savedListID']; -$savedListName = $_REQUEST['savedListName']; +$savedListID = $_POST['savedListID']; +$savedListName = $_POST['savedListName']; $savedLists = new SavedLists($siteID); diff --git a/modules/lists/ajax/newList.php b/modules/lists/ajax/newList.php index 006b07ea0..ec40051f2 100755 --- a/modules/lists/ajax/newList.php +++ b/modules/lists/ajax/newList.php @@ -35,13 +35,19 @@ $interface = new SecureAJAXInterface(); -if (!$interface->isRequiredIDValid('dataItemType')) +if ($_SERVER['REQUEST_METHOD'] !== 'POST') +{ + $interface->outputXMLErrorPage(-1, 'Invalid request.'); + die(); +} + +if (!isset($_POST['dataItemType']) || !ctype_digit((string) $_POST['dataItemType'])) { $interface->outputXMLErrorPage(-1, 'Invalid saved list type.'); die(); } -if (!isset($_REQUEST['description'])) +if (!isset($_POST['description'])) { $interface->outputXMLErrorPage(-1, 'Invalid name.'); die(); @@ -49,8 +55,8 @@ $siteID = $interface->getSiteID(); -$savedListName = $_REQUEST['description']; -$dataItemType = $_REQUEST['dataItemType']; +$savedListName = $_POST['description']; +$dataItemType = $_POST['dataItemType']; $savedLists = new SavedLists($siteID); diff --git a/modules/settings/Backup.tpl b/modules/settings/Backup.tpl index 30935f1ba..8e21dc977 100755 --- a/modules/settings/Backup.tpl +++ b/modules/settings/Backup.tpl @@ -52,9 +52,10 @@ _($attachmentsData['dateCreated']) ?> - - - +
+ + +
diff --git a/modules/settings/CareerPortalSettings.tpl b/modules/settings/CareerPortalSettings.tpl index 13f09c22d..cdf2e62ba 100755 --- a/modules/settings/CareerPortalSettings.tpl +++ b/modules/settings/CareerPortalSettings.tpl @@ -213,7 +213,8 @@