You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
522 lines
23 KiB
522 lines
23 KiB
2 years ago
|
<?php
|
||
|
|
||
|
/**
|
||
|
* The outside frame that holds all of the OpenEMR User Interface.
|
||
|
*
|
||
|
* @package OpenEMR
|
||
|
* @link http://www.open-emr.org
|
||
|
* @author Rod Roark <rod@sunsetsystems.com>
|
||
|
* @author Brady Miller <brady.g.miller@gmail.com>
|
||
|
* @author Ranganath Pathak <pathak@scrs1.org>
|
||
|
* @copyright Copyright (c) 2018 Rod Roark <rod@sunsetsystems.com>
|
||
|
* @copyright Copyright (c) 2018-2019 Brady Miller <brady.g.miller@gmail.com>
|
||
|
* @copyright Copyright (c) 2019 Ranganath Pathak <pathak@scrs1.org>
|
||
|
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
|
||
|
*/
|
||
|
|
||
|
// Set $sessionAllowWrite to true to prevent session concurrency issues during authorization and app setup related code
|
||
|
$sessionAllowWrite = true;
|
||
|
require_once('../globals.php');
|
||
|
|
||
|
use OpenEMR\Common\Auth\AuthUtils;
|
||
|
use OpenEMR\Common\Crypto\CryptoGen;
|
||
|
use OpenEMR\Common\Csrf\CsrfUtils;
|
||
|
use OpenEMR\Common\Session\SessionTracker;
|
||
|
use OpenEMR\Common\Utils\RandomGenUtils;
|
||
|
use OpenEMR\Core\Header;
|
||
|
use OpenEMR\Services\FacilityService;
|
||
|
use u2flib_server\U2F;
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
// Functions to support MFA.
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
function posted_to_hidden($name)
|
||
|
{
|
||
|
if (isset($_POST[$name])) {
|
||
|
echo "<input type='hidden' name='" . attr($name) . "' value='" . attr($_POST[$name]) . "' />\r\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function generate_html_start()
|
||
|
{
|
||
|
?>
|
||
|
<html>
|
||
|
<head>
|
||
|
<?php Header::setupHeader(); ?>
|
||
|
<title><?php echo xlt("MFA Authorization"); ?></title>
|
||
|
<style>
|
||
|
.alert-msg {
|
||
|
font-size:100%;
|
||
|
font-weight:700;
|
||
|
}
|
||
|
</style>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
function generate_html_u2f()
|
||
|
{
|
||
|
global $appId;
|
||
|
?>
|
||
|
<script src="<?php echo $GLOBALS['webroot'] ?>/library/js/u2f-api.js"></script>
|
||
|
<script>
|
||
|
function doAuth() {
|
||
|
var f = document.getElementById("u2fform");
|
||
|
var requests = JSON.parse(f.form_requests.value);
|
||
|
// The server's getAuthenticateData() repeats the same challenge in all requests.
|
||
|
var challenge = requests[0].challenge;
|
||
|
var registeredKeys = new Array();
|
||
|
for (var i = 0; i < requests.length; ++i) {
|
||
|
registeredKeys[i] = {"version": requests[i].version, "keyHandle": requests[i].keyHandle};
|
||
|
}
|
||
|
u2f.sign(
|
||
|
<?php echo js_escape($appId); ?>,
|
||
|
challenge,
|
||
|
registeredKeys,
|
||
|
function (data) {
|
||
|
if (data.errorCode && data.errorCode != 0) {
|
||
|
alert(<?php echo xlj("Key access failed with error"); ?> +' ' + data.errorCode);
|
||
|
return;
|
||
|
}
|
||
|
f.form_response.value = JSON.stringify(data);
|
||
|
f.submit();
|
||
|
},
|
||
|
60
|
||
|
);
|
||
|
}
|
||
|
|
||
|
</script>
|
||
|
<?php
|
||
|
}
|
||
|
function input_focus()
|
||
|
{
|
||
|
?>
|
||
|
<script>
|
||
|
$(function () {
|
||
|
$('#totp').focus();
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
function generate_html_top()
|
||
|
{
|
||
|
echo '</head>';
|
||
|
echo '<body>';
|
||
|
}
|
||
|
|
||
|
function generate_html_middle()
|
||
|
{
|
||
|
posted_to_hidden('new_login_session_management');
|
||
|
posted_to_hidden('languageChoice');
|
||
|
posted_to_hidden('authUser');
|
||
|
posted_to_hidden('clearPass');
|
||
|
}
|
||
|
|
||
|
require_once(dirname(__FILE__) . "/../../src/Common/Session/SessionUtil.php");
|
||
|
function generate_html_end()
|
||
|
{
|
||
|
// to be safe, remove clearPass from memory now (if it is not empty yet)
|
||
|
if (!empty($_POST["clearPass"])) {
|
||
|
if (function_exists('sodium_memzero')) {
|
||
|
sodium_memzero($_POST["clearPass"]);
|
||
|
} else {
|
||
|
$_POST["clearPass"] = '';
|
||
|
}
|
||
|
}
|
||
|
echo "</div></body></html>\n";
|
||
|
OpenEMR\Common\Session\SessionUtil::coreSessionDestroy();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (isset($_POST['new_login_session_management'])) {
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
// Begin code to support U2F and APP Based TOTP logic.
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
$errormsg = '';
|
||
|
$regs = array(); // for mapping device handles to their names
|
||
|
$registrations = array(); // the array of stored registration objects
|
||
|
$res1 = sqlStatement(
|
||
|
"SELECT a.name, a.method, a.var1 FROM login_mfa_registrations AS a " .
|
||
|
"WHERE a.user_id = ? AND (a.method = 'TOTP' OR a.method = 'U2F') ORDER BY a.name",
|
||
|
array($_SESSION['authUserID'])
|
||
|
);
|
||
|
|
||
|
$registrationAttempt = false;
|
||
|
$isU2F = false;
|
||
|
$isTOTP = false;
|
||
|
while ($row1 = sqlFetchArray($res1)) {
|
||
|
$registrationAttempt = true;
|
||
|
if ($row1['method'] == 'U2F') {
|
||
|
$isU2F = true;
|
||
|
$regobj = json_decode($row1['var1']);
|
||
|
$regs[json_encode($regobj->keyHandle)] = $row1['name'];
|
||
|
$registrations[] = $regobj;
|
||
|
} else { // $row1['method'] == 'TOTP'
|
||
|
$isTOTP = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ($registrationAttempt) {
|
||
|
$requests = '';
|
||
|
$errortype = '';
|
||
|
if ($isU2F) {
|
||
|
// There is at least one U2F key registered so we have to request or verify key data.
|
||
|
// https is required, and with a proxy the server might not see it.
|
||
|
$scheme = "https://"; // isset($_SERVER['HTTPS']) ? "https://" : "http://";
|
||
|
$appId = $scheme . $_SERVER['HTTP_HOST'];
|
||
|
$u2f = new u2flib_server\U2F($appId);
|
||
|
}
|
||
|
$userid = $_SESSION['authUserID'];
|
||
|
$form_response = empty($_POST['form_response']) ? '' : $_POST['form_response'];
|
||
|
if ($form_response) {
|
||
|
// TOTP METHOD enabled if TOTP is visible in post request
|
||
|
if (isset($_POST['totp']) && trim($_POST['totp']) != "" && $isTOTP) {
|
||
|
$errormsg = false;
|
||
|
|
||
|
$form_response = '';
|
||
|
|
||
|
$res1 = sqlQuery(
|
||
|
"SELECT a.var1 FROM login_mfa_registrations AS a WHERE a.user_id = ? AND a.method = 'TOTP'",
|
||
|
array($_SESSION['authUserID'])
|
||
|
);
|
||
|
$registrationSecret = false;
|
||
|
if (!empty($res1['var1'])) {
|
||
|
$registrationSecret = $res1['var1'];
|
||
|
}
|
||
|
|
||
|
// Decrypt the secret
|
||
|
// First, try standard method that uses standard key
|
||
|
$cryptoGen = new CryptoGen();
|
||
|
$secret = $cryptoGen->decryptStandard($registrationSecret);
|
||
|
if (empty($secret)) {
|
||
|
// Second, try the password hash, which was setup during install and is temporary
|
||
|
$passwordResults = privQuery(
|
||
|
"SELECT password FROM users_secure WHERE username = ?",
|
||
|
array($_POST["authUser"])
|
||
|
);
|
||
|
if (!empty($passwordResults["password"])) {
|
||
|
$secret = $cryptoGen->decryptStandard($registrationSecret, $passwordResults["password"]);
|
||
|
if (!empty($secret)) {
|
||
|
error_log("Disregard the decryption failed authentication error reported above this line; it is not an error.");
|
||
|
// Re-encrypt with the more secure standard key
|
||
|
$secretEncrypt = $cryptoGen->encryptStandard($secret);
|
||
|
privStatement(
|
||
|
"UPDATE login_mfa_registrations SET var1 = ? where user_id = ? AND method = 'TOTP'",
|
||
|
array($secretEncrypt, $userid)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!empty($secret)) {
|
||
|
$googleAuth = new Totp($secret);
|
||
|
$form_response = $googleAuth->validateCode($_POST['totp']);
|
||
|
}
|
||
|
|
||
|
if ($form_response) {
|
||
|
// Keep track of when challenges were last answered correctly.
|
||
|
privStatement(
|
||
|
"UPDATE users_secure SET last_challenge_response = NOW() WHERE id = ?",
|
||
|
array($_SESSION['authUserID'])
|
||
|
);
|
||
|
} else {
|
||
|
$errormsg = xl("The code you entered was not valid");
|
||
|
$errortype = "TOTP";
|
||
|
}
|
||
|
} elseif ($isU2F) { // Otherwise use U2F METHOD
|
||
|
// We have key data, check if it matches what was registered.
|
||
|
$tmprow = sqlQuery("SELECT login_work_area FROM users_secure WHERE id = ?", array($userid));
|
||
|
try {
|
||
|
$registration = $u2f->doAuthenticate(
|
||
|
json_decode($tmprow['login_work_area']), // these are the original challenge requests
|
||
|
$registrations,
|
||
|
json_decode($_POST['form_response'])
|
||
|
);
|
||
|
// Stored registration data needs to be updated because the usage count has changed.
|
||
|
// We have to use the matching registered key.
|
||
|
$strhandle = json_encode($registration->keyHandle);
|
||
|
if (isset($regs[$strhandle])) {
|
||
|
sqlStatement(
|
||
|
"UPDATE login_mfa_registrations SET `var1` = ? WHERE " .
|
||
|
"`user_id` = ? AND `method` = 'U2F' AND `name` = ?",
|
||
|
array(json_encode($registration), $userid, $regs[$strhandle])
|
||
|
);
|
||
|
} else {
|
||
|
error_log("Unexpected keyHandle returned from doAuthenticate(): '" . errorLogEscape($strhandle) . "'");
|
||
|
}
|
||
|
// Keep track of when challenges were last answered correctly.
|
||
|
sqlStatement(
|
||
|
"UPDATE users_secure SET last_challenge_response = NOW() WHERE id = ?",
|
||
|
array($_SESSION['authUserID'])
|
||
|
);
|
||
|
} catch (u2flib_server\Error $e) {
|
||
|
// Authentication failed so we will build the U2F form again.
|
||
|
$form_response = '';
|
||
|
$errormsg = xl('U2F Key Authentication error') . ": " . $e->getMessage();
|
||
|
$errortype = "U2F";
|
||
|
}
|
||
|
} else {
|
||
|
// do nothing
|
||
|
$form_response = '';
|
||
|
}
|
||
|
}
|
||
|
if (!$form_response) {
|
||
|
generate_html_start();
|
||
|
if ($isU2F) {
|
||
|
generate_html_u2f();
|
||
|
}
|
||
|
if ($isTOTP) {
|
||
|
input_focus();
|
||
|
}
|
||
|
generate_html_top();
|
||
|
if ($isTOTP) {
|
||
|
echo '<div class="container">';
|
||
|
echo '<div class="row">';
|
||
|
echo ' <div class="col-sm-12">';
|
||
|
echo ' <h2>' . xlt('TOTP Verification') . '</h2>';
|
||
|
echo ' </div>';
|
||
|
echo '</div>';
|
||
|
if ($errormsg && $errortype == "TOTP") {
|
||
|
echo '<div class="row"><div class="col-sm-12"><div class="alert alert-danger alert-msg">' . text($errormsg) . '</div></div></div>';
|
||
|
}
|
||
|
|
||
|
echo '<div class="row">';
|
||
|
echo ' <div class="col-sm-12">';
|
||
|
echo ' <form method="post" action="main_screen.php?auth=login&site=' . attr_url($_GET['site']) . '" target="_top" name="challenge_form" id=="challenge_form">';
|
||
|
echo ' <fieldset>';
|
||
|
echo ' <legend>' . xlt('Provide TOTP code') . '</legend>';
|
||
|
echo ' <div class="form-group">';
|
||
|
echo ' <div class="col-sm-6 offset-sm-3">';
|
||
|
echo ' <label for="totp">' . xlt('Enter the code from your authentication application on your device') . ':</label>';
|
||
|
echo ' <input type="text" name="totp" class="form-control input-lg" id="totp" maxlength="12" required>';
|
||
|
echo ' <input type="hidden" name="form_response" value="true" />';
|
||
|
generate_html_middle();
|
||
|
echo ' </div>';
|
||
|
echo ' </fieldset>';
|
||
|
echo ' <div class="form-group clearfix">';
|
||
|
echo ' <div class="col-sm-12 text-left position-override">';
|
||
|
echo ' <button type="submit" class="btn btn-secondary btn-save">' . xlt('Authenticate TOTP') . '</button>';
|
||
|
echo ' </div>';
|
||
|
echo ' </div>';
|
||
|
echo ' </div>';
|
||
|
echo ' </form>';
|
||
|
echo ' </div>';
|
||
|
echo '</div>';
|
||
|
}
|
||
|
if ($isU2F) {
|
||
|
// There is no key data yet or authentication failed, so we need to solicit it.
|
||
|
$requests = json_encode($u2f->getAuthenticateData($registrations));
|
||
|
// Persist the challenge also in the database because the browser is untrusted.
|
||
|
sqlStatement(
|
||
|
"UPDATE users_secure SET login_work_area = ? WHERE id = ?",
|
||
|
array($requests, $userid)
|
||
|
);
|
||
|
|
||
|
echo '<div class="container">';
|
||
|
echo '<div class="row">';
|
||
|
echo ' <div class="col-sm-12">';
|
||
|
echo ' <h2>' . xlt('U2F Key Verification') . '</h2>';
|
||
|
echo ' </div>';
|
||
|
echo '</div>';
|
||
|
if ($errormsg && $errortype == "U2F") {
|
||
|
echo '<div class="row"><div class="col-sm-12"><div class="alert alert-danger alert-msg">' . text($errormsg) . '</div></div></div>';
|
||
|
}
|
||
|
echo '<div class="row">';
|
||
|
echo ' <div class="col-sm-12">';
|
||
|
echo ' <form method="post" name="u2fform" id="u2fform" action="main_screen.php?auth=login&site=' . attr_url($_GET['site']) . '" target="_top">';
|
||
|
echo ' <fieldset>';
|
||
|
echo ' <legend>' . xlt('Insert U2F Key') . '</legend>';
|
||
|
echo ' <div class="form-group">';
|
||
|
echo ' <div class="col-sm-6 offset-sm-3">';
|
||
|
echo ' <ul>';
|
||
|
echo ' <li>' . xlt('Insert your key into a USB port and click the Authenticate button below.') . '</li>';
|
||
|
echo ' <li>' . xlt('Then press the flashing button on your key within 1 minute.') . '</li>';
|
||
|
echo ' </ul>';
|
||
|
echo ' </div>';
|
||
|
echo ' </fieldset>';
|
||
|
echo ' <div class="form-group clearfix">';
|
||
|
echo ' <div class="col-sm-12 text-left position-override">';
|
||
|
echo ' <button type="button" id="authutf" class="btn btn-secondary btn-save" onclick="doAuth()">' . xlt('Authenticate U2F') . '</button>';
|
||
|
echo ' <input type="hidden" name="form_requests" value="' . attr($requests) . '" />';
|
||
|
echo ' <input type="hidden" name="form_response" value="" />';
|
||
|
generate_html_middle();
|
||
|
echo ' </div>';
|
||
|
echo ' </div>';
|
||
|
echo ' </form>';
|
||
|
echo ' </div>';
|
||
|
echo '</div>';
|
||
|
}
|
||
|
exit(generate_html_end());
|
||
|
}
|
||
|
}
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
// End of U2F and APP Based TOTP logic.
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
// Creates a new session id when load this outer frame
|
||
|
// (allows creations of separate OpenEMR frames to view patients concurrently
|
||
|
// on different browser frame/windows)
|
||
|
// This session id is used below in the restoreSession.php include to create a
|
||
|
// session cookie for this specific OpenEMR instance that is then maintained
|
||
|
// within the OpenEMR instance by calling top.restoreSession() whenever
|
||
|
// refreshing or starting a new script.
|
||
|
|
||
|
// This is a new login, so create a new session id and remove the old session
|
||
|
session_regenerate_id(true);
|
||
|
// Also need to delete clearPass from memory
|
||
|
if (function_exists('sodium_memzero')) {
|
||
|
sodium_memzero($_POST["clearPass"]);
|
||
|
} else {
|
||
|
$_POST["clearPass"] = '';
|
||
|
}
|
||
|
} else {
|
||
|
// This is not a new login, so check csrf and then create a new session id and do NOT remove the old session
|
||
|
if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) {
|
||
|
CsrfUtils::csrfNotVerified();
|
||
|
}
|
||
|
session_regenerate_id(false);
|
||
|
}
|
||
|
// Set up the csrf private_key
|
||
|
// Note this key always remains private and never leaves server session. It is used to create
|
||
|
// the csrf tokens.
|
||
|
CsrfUtils::setupCsrfKey();
|
||
|
// Set up the session uuid. This will be used for mapping session setting to database.
|
||
|
// At this time only used for lastupdate tracking
|
||
|
SessionTracker::setupSessionDatabaseTracker();
|
||
|
|
||
|
$_SESSION["encounter"] = '';
|
||
|
|
||
|
if ($GLOBALS['login_into_facility']) {
|
||
|
$facility_id = $_POST['facility'];
|
||
|
if ($facility_id === 'user_default') {
|
||
|
//get the default facility of login user from users table
|
||
|
$facilityService = new FacilityService();
|
||
|
$facility = $facilityService->getFacilityForUser($_SESSION['authUserID']);
|
||
|
$facility_id = $facility['id'];
|
||
|
}
|
||
|
$_SESSION['facilityId'] = $facility_id;
|
||
|
if ($GLOBALS['set_facility_cookie']) {
|
||
|
// set cookie with facility for the calender screens
|
||
|
setcookie("pc_facility", $_SESSION['facilityId'], time() + (3600 * 365), $GLOBALS['webroot']);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Fetch the password expiration date (note LDAP skips this)
|
||
|
$is_expired = false;
|
||
|
if ((!AuthUtils::useActiveDirectory()) && ($GLOBALS['password_expiration_days'] != 0) && (check_integer($GLOBALS['password_expiration_days']))) {
|
||
|
$result = privQuery("select `last_update_password` from `users_secure` where `id` = ?", [$_SESSION['authUserID']]);
|
||
|
$current_date = date('Y-m-d');
|
||
|
if (!empty($result['last_update_password'])) {
|
||
|
$pwd_last_update = $result['last_update_password'];
|
||
|
} else {
|
||
|
error_log("OpenEMR ERROR: there is a problem with recording of last_update_password entry in users_secure table");
|
||
|
$pwd_last_update = $current_date;
|
||
|
}
|
||
|
|
||
|
// Display the password expiration message (will show during the grace time)
|
||
|
$pwd_alert_date = date('Y-m-d', strtotime($pwd_last_update . '+' . $GLOBALS['password_expiration_days'] . ' days'));
|
||
|
|
||
|
if (empty(strtotime($pwd_alert_date))) {
|
||
|
error_log("OpenEMR ERROR: there is a problem when trying to check if user's password is expired");
|
||
|
} elseif (strtotime($current_date) >= strtotime($pwd_alert_date)) {
|
||
|
$is_expired = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ($is_expired) {
|
||
|
//display the php file containing the password expiration message.
|
||
|
$frame1url = "pwd_expires_alert.php?csrf_token_form=" . attr_url(CsrfUtils::collectCsrfToken());
|
||
|
$frame1target = "adm";
|
||
|
$frame1label = "";
|
||
|
} elseif (!empty($_POST['patientID'])) {
|
||
|
$patientID = (int) $_POST['patientID'];
|
||
|
if (empty($_POST['encounterID'])) {
|
||
|
// Open patient summary screen (without a specific encounter)
|
||
|
$frame1url = "../patient_file/summary/demographics.php?set_pid=" . attr_url($patientID);
|
||
|
$frame1target = "pat";
|
||
|
$frame1label = xl('Patient Search/Add Screen');
|
||
|
} else {
|
||
|
// Open patient summary screen with a specific encounter
|
||
|
$encounterID = (int) $_POST['encounterID'];
|
||
|
$frame1url = "../patient_file/summary/demographics.php?set_pid=" . attr_url($patientID) . "&set_encounterid=" . attr_url($encounterID);
|
||
|
$frame1target = "pat";
|
||
|
$frame1label = xl('Patient Search/Add Screen');
|
||
|
}
|
||
|
} elseif (isset($_GET['mode']) && $_GET['mode'] == "loadcalendar") {
|
||
|
$frame1url = "calendar/index.php?pid=" . attr_url($_GET['pid']);
|
||
|
if (isset($_GET['date'])) {
|
||
|
$frame1url .= "&date=" . attr_url($_GET['date']);
|
||
|
}
|
||
|
|
||
|
$frame1target = "cal";
|
||
|
$frame1label = xl('Calendar Screen');
|
||
|
} else {
|
||
|
// standard layout
|
||
|
$map_paths_to_targets = array(
|
||
|
'main_info.php' => array(
|
||
|
'target' => 'cal' , "label" => xl('Calendar Screen')
|
||
|
),
|
||
|
'../new/new.php' => array(
|
||
|
'target' => 'pat' , "label" => xl('Patient Search/Add Screen')
|
||
|
),
|
||
|
'../../interface/main/finder/dynamic_finder.php' => array(
|
||
|
'target' => 'fin' , "label" => xl('Patient Finder Screen')
|
||
|
),
|
||
|
'../../interface/patient_tracker/patient_tracker.php?skip_timeout_reset=1' => array(
|
||
|
'target' => 'flb' , "label" => xl('Patient Flow Board')
|
||
|
),
|
||
|
'../../interface/main/messages/messages.php?form_active=1' => array(
|
||
|
'target' => 'msg' , "label" => xl('Messages Screen')
|
||
|
)
|
||
|
);
|
||
|
if ($GLOBALS['default_top_pane']) {
|
||
|
$frame1url = attr($GLOBALS['default_top_pane']);
|
||
|
$frame1target = $map_paths_to_targets[$GLOBALS['default_top_pane']]['target'];
|
||
|
$frame1label = $map_paths_to_targets[$GLOBALS['default_top_pane']]['label'];
|
||
|
if (empty($frame1target)) {
|
||
|
$frame1target = "msc";
|
||
|
}
|
||
|
} else {
|
||
|
$frame1url = "main_info.php";
|
||
|
$frame1target = "cal";
|
||
|
}
|
||
|
if ($GLOBALS['default_second_tab']) {
|
||
|
$frame2url = attr($GLOBALS['default_second_tab']);
|
||
|
$frame2target = $map_paths_to_targets[$GLOBALS['default_second_tab']]['target'];
|
||
|
$frame2label = $map_paths_to_targets[$GLOBALS['default_second_tab']]['label'];
|
||
|
if (empty($frame2target)) {
|
||
|
$frame2target = "msc";
|
||
|
}
|
||
|
} else {
|
||
|
// In the case where no second default tab is specified, set these session variables to null
|
||
|
$frame2url = null;
|
||
|
$frame2target = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$nav_area_width = '130';
|
||
|
if (!empty($GLOBALS['gbl_nav_area_width'])) {
|
||
|
$nav_area_width = $GLOBALS['gbl_nav_area_width'];
|
||
|
}
|
||
|
|
||
|
// Will set Session variables to communicate settings to tab layout
|
||
|
$_SESSION['frame1url'] = $frame1url;
|
||
|
$_SESSION['frame1target'] = $frame1target;
|
||
|
$_SESSION['frame1label'] = $frame1label;
|
||
|
$_SESSION['frame2url'] = $frame2url;
|
||
|
$_SESSION['frame2target'] = $frame2target;
|
||
|
$_SESSION['frame2label'] = $frame2label;
|
||
|
// mdsupport - Apps processing invoked for valid app selections from list
|
||
|
if ((isset($_POST['appChoice'])) && ($_POST['appChoice'] !== '*OpenEMR')) {
|
||
|
$_SESSION['app1'] = $_POST['appChoice'];
|
||
|
}
|
||
|
|
||
|
// Pass a unique token, so main.php script can not be run on its own
|
||
|
$_SESSION['token_main_php'] = RandomGenUtils::createUniqueToken();
|
||
|
header('Location: ' . $web_root . "/interface/main/tabs/main.php?token_main=" . urlencode($_SESSION['token_main_php']));
|
||
|
exit();
|
||
|
?>
|