Merge pull request #14313 from nulll-pointer/enh_1
Fixes #13654 Login modal after session expiration
This commit is contained in:
commit
4576538be6
110
js/ajax.js
110
js/ajax.js
@ -336,7 +336,115 @@ var AJAX = {
|
||||
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
|
||||
AJAX.active = true;
|
||||
AJAX.$msgbox = PMA_ajaxShowMessage();
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
if($(this).attr('id') === 'login_form') {
|
||||
$.post(url, params, AJAX.loginResponseHandler);
|
||||
} else {
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Response handler to handle login request from login modal after session expiration
|
||||
*
|
||||
* To refer to self use 'AJAX', instead of 'this' as this function
|
||||
* is called in the jQuery context.
|
||||
*
|
||||
* @param object data Event data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
loginResponseHandler: function (data) {
|
||||
if (typeof data === 'undefined' || data === null) {
|
||||
return;
|
||||
}
|
||||
PMA_ajaxRemoveMessage(AJAX.$msgbox);
|
||||
|
||||
PMA_commonParams.set("token", data.new_token);
|
||||
|
||||
AJAX.scriptHandler.load([]);
|
||||
|
||||
if (data._displayMessage) {
|
||||
$('#page_content').prepend(data._displayMessage);
|
||||
PMA_highlightSQL($('#page_content'));
|
||||
}
|
||||
|
||||
$('#pma_errors').remove();
|
||||
|
||||
var msg = '';
|
||||
if (data._errSubmitMsg) {
|
||||
msg = data._errSubmitMsg;
|
||||
}
|
||||
if (data._errors) {
|
||||
$('<div/>', { id : 'pma_errors', class : 'clearfloat' })
|
||||
.insertAfter('#selflink')
|
||||
.append(data._errors);
|
||||
// bind for php error reporting forms (bottom)
|
||||
$('#pma_ignore_errors_bottom').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
PMA_ignorePhpErrors();
|
||||
});
|
||||
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
PMA_ignorePhpErrors(false);
|
||||
});
|
||||
// In case of 'sendErrorReport'='always'
|
||||
// submit the hidden error reporting form.
|
||||
if (data._sendErrorAlways === '1' &&
|
||||
data._stopErrorReportLoop !== '1'
|
||||
) {
|
||||
$('#pma_report_errors_form').submit();
|
||||
PMA_ajaxShowMessage(PMA_messages.phpErrorsBeingSubmitted, false);
|
||||
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
|
||||
} else if (data._promptPhpErrors) {
|
||||
// otherwise just prompt user if it is set so.
|
||||
msg = msg + PMA_messages.phpErrorsFound;
|
||||
// scroll to bottom where all the errors are displayed.
|
||||
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
|
||||
}
|
||||
}
|
||||
|
||||
PMA_ajaxShowMessage(msg, false);
|
||||
// bind for php error reporting forms (popup)
|
||||
$('#pma_ignore_errors_popup').on('click', function () {
|
||||
PMA_ignorePhpErrors();
|
||||
});
|
||||
$('#pma_ignore_all_errors_popup').on('click', function () {
|
||||
PMA_ignorePhpErrors(false);
|
||||
});
|
||||
|
||||
if (typeof data.success !== 'undefined' && data.success) {
|
||||
// reload page if user trying to login has changed
|
||||
if(PMA_commonParams.get('user') !== data._params['user']) {
|
||||
window.location = "index.php";
|
||||
PMA_ajaxShowMessage(PMA_messages.strLoading, false);
|
||||
AJAX.active = false;
|
||||
AJAX.xhr = null;
|
||||
return;
|
||||
}
|
||||
// remove the login modal if the login is successful otherwise show error.
|
||||
if(typeof data.logged_in !== 'undefined' && data.logged_in === 1) {
|
||||
if($("#modalOverlay").length) {
|
||||
$("#modalOverlay").remove();
|
||||
}
|
||||
$("fieldset.disabled_for_expiration").removeAttr("disabled").removeClass("disabled_for_expiration");
|
||||
AJAX.fireTeardown("functions.js");
|
||||
AJAX.fireOnload("functions.js");
|
||||
}
|
||||
if(typeof data.new_token !== 'undefined') {
|
||||
$("input[name=token]").val(data.new_token);
|
||||
}
|
||||
|
||||
} else if(typeof data.logged_in !== 'undefined' && data.logged_in === 0) {
|
||||
$("#modalOverlay").replaceWith(data.error);
|
||||
} else {
|
||||
PMA_ajaxShowMessage(data.error, false);
|
||||
AJAX.active = false;
|
||||
AJAX.xhr = null;
|
||||
PMA_handleRedirectAndReload(data);
|
||||
if (data.fieldWithError) {
|
||||
$(':input.error').removeClass('error');
|
||||
$('#' + data.fieldWithError).addClass('error');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -949,7 +949,8 @@ AJAX.registerOnload('functions.js', function () {
|
||||
'server' : PMA_commonParams.get('server'),
|
||||
'db' : PMA_commonParams.get('db'),
|
||||
'guid': guid,
|
||||
'access_time':_idleSecondsCounter
|
||||
'access_time': _idleSecondsCounter,
|
||||
'check_timeout': 1
|
||||
};
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
@ -978,7 +979,19 @@ AJAX.registerOnload('functions.js', function () {
|
||||
if (isStorageSupported('sessionStorage')) {
|
||||
window.sessionStorage.clear();
|
||||
}
|
||||
window.location.reload(true);
|
||||
// append the login form on the page, disable all the forms which were not disabled already, close all the open jqueryui modal boxes
|
||||
if (!$("#modalOverlay").length) {
|
||||
$("fieldset").not(':disabled').attr("disabled", "disabled").addClass("disabled_for_expiration");
|
||||
$('body').append(data.error);
|
||||
$(".ui-dialog").each(function(i) {
|
||||
$("#" + $(this).attr("aria-describedby")).dialog("close");
|
||||
});
|
||||
$("#input_username").focus();
|
||||
} else {
|
||||
PMA_commonParams.set("token", data.new_token);
|
||||
$("input[name=token]").val(data.new_token);
|
||||
}
|
||||
_idleSecondsCounter = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -4321,6 +4334,9 @@ function PMA_slidingMessage (msg, $obj) {
|
||||
*/
|
||||
AJAX.registerOnload('functions.js', function () {
|
||||
var $elm = $('#sqlquery');
|
||||
if ($elm.siblings().filter(".CodeMirror").length > 0) {
|
||||
return;
|
||||
}
|
||||
if ($elm.length > 0) {
|
||||
if (typeof CodeMirror !== 'undefined') {
|
||||
codemirror_editor = PMA_getSQLEditor($elm);
|
||||
|
||||
@ -38,6 +38,10 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
$(document).on('keydown', function (e) {
|
||||
//disable the shortcuts when session has timed out.
|
||||
if ($("#modalOverlay").length > 0) {
|
||||
return;
|
||||
}
|
||||
if (e.ctrlKey && e.altKey && e.keyCode === keyC) {
|
||||
PMA_console.toggle();
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ AJAX.registerTeardown('sql.js', function () {
|
||||
$(document).off('mouseenter', 'th.column_heading.pointer');
|
||||
$(document).off('mouseleave', 'th.column_heading.pointer');
|
||||
$(document).off('click', 'th.column_heading.marker');
|
||||
$(window).off('scroll');
|
||||
$(document).off('scroll', window);
|
||||
$(document).off('keyup', '.filter_rows');
|
||||
$(document).off('click', '#printView');
|
||||
if (codemirror_editor) {
|
||||
@ -405,7 +405,7 @@ AJAX.registerOnload('sql.js', function () {
|
||||
var $stick_columns = initStickyColumns($table_results);
|
||||
rearrangeStickyColumns($stick_columns, $table_results);
|
||||
// adjust sticky columns on scroll
|
||||
$(window).on('scroll', function () {
|
||||
$(document).on('scroll', window, function () {
|
||||
handleStickyColumns($stick_columns, $table_results);
|
||||
});
|
||||
});
|
||||
|
||||
@ -86,7 +86,10 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
global $conn_error;
|
||||
|
||||
$response = Response::getInstance();
|
||||
if ($response->loginPage()) {
|
||||
|
||||
// When sending login modal after session has expired, send the new token explicitly with the response to update the token in all the forms having a hidden token.
|
||||
$session_expired = isset($_REQUEST['check_timeout']) || isset($_REQUEST['session_timedout']);
|
||||
if (!$session_expired && $response->loginPage()) {
|
||||
if (defined('TESTSUITE')) {
|
||||
return true;
|
||||
} else {
|
||||
@ -94,6 +97,23 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
}
|
||||
}
|
||||
|
||||
// When sending login modal after session has expired, send the new token explicitly with the response to update the token in all the forms having a hidden token.
|
||||
if($session_expired) {
|
||||
$response->setRequestStatus(false);
|
||||
$response->addJSON(
|
||||
'new_token',
|
||||
$_SESSION[' PMA_token ']
|
||||
);
|
||||
}
|
||||
|
||||
// logged_in response parameter is used to check if the login, using the modal was successful after session expiration
|
||||
if(isset($_REQUEST['session_timedout'])) {
|
||||
$response->addJSON(
|
||||
'logged_in',
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// No recall if blowfish secret is not configured as it would produce
|
||||
// garbage
|
||||
if ($GLOBALS['cfg']['LoginCookieRecall']
|
||||
@ -109,7 +129,14 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
$autocomplete = ' autocomplete="off"';
|
||||
}
|
||||
|
||||
echo $this->template->render('login/header', ['theme' => $GLOBALS['PMA_Theme']]);
|
||||
// wrap the login form in a div which overlays the whole page.
|
||||
if($session_expired) {
|
||||
echo $this->template->render('login/header', ['theme' => $GLOBALS['PMA_Theme'],
|
||||
'add_class' => ' modal_form', 'session_expired' => 1]);
|
||||
} else {
|
||||
echo $this->template->render('login/header', ['theme' => $GLOBALS['PMA_Theme'],
|
||||
'add_class' => '', 'session_expired' => 0]);
|
||||
}
|
||||
|
||||
if ($GLOBALS['cfg']['DBG']['demo']) {
|
||||
echo '<fieldset>';
|
||||
@ -148,10 +175,15 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
<br />
|
||||
<!-- Login form -->
|
||||
<form method="post" id="login_form" action="index.php" name="login_form"' , $autocomplete ,
|
||||
' class="disableAjax login hide js-show">
|
||||
' class="' . ($session_expired ? "" : "disableAjax hide ") . 'login js-show">
|
||||
<fieldset>
|
||||
<legend>';
|
||||
echo '<input type="hidden" name="set_session" value="', htmlspecialchars(session_id()), '" />';
|
||||
|
||||
// Add a hidden element session_timedout which is used to check if the user requested login after session expiration
|
||||
if($session_expired) {
|
||||
echo '<input type="hidden" name="session_timedout" value="1" />';
|
||||
}
|
||||
echo __('Log in');
|
||||
echo Util::showDocu('index');
|
||||
echo '</legend>';
|
||||
@ -236,8 +268,16 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
$GLOBALS['error_handler']->dispErrors();
|
||||
echo '</div>';
|
||||
}
|
||||
echo $this->template->render('login/footer');
|
||||
|
||||
// close the wrapping div tag, if the request is after session timeout
|
||||
if($session_expired) {
|
||||
echo $this->template->render('login/footer', ['session_expired' => 1]);
|
||||
} else {
|
||||
echo $this->template->render('login/footer', ['session_expired' => 0]);
|
||||
}
|
||||
|
||||
echo Config::renderFooter();
|
||||
|
||||
if (! defined('TESTSUITE')) {
|
||||
exit;
|
||||
} else {
|
||||
@ -472,6 +512,7 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
{
|
||||
// Name and password cookies need to be refreshed each time
|
||||
// Duration = one month for username
|
||||
|
||||
$this->storeUsernameCookie($this->user);
|
||||
|
||||
// Duration = as configured
|
||||
@ -480,27 +521,54 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
if (! isset($_POST['change_pw'])) {
|
||||
$this->storePasswordCookie($this->password);
|
||||
}
|
||||
// URL where to go:
|
||||
$redirect_url = './index.php';
|
||||
|
||||
// any parameters to pass?
|
||||
$url_params = array();
|
||||
if (strlen($GLOBALS['db']) > 0) {
|
||||
$url_params['db'] = $GLOBALS['db'];
|
||||
}
|
||||
if (strlen($GLOBALS['table']) > 0) {
|
||||
$url_params['table'] = $GLOBALS['table'];
|
||||
}
|
||||
// any target to pass?
|
||||
if (! empty($GLOBALS['target'])
|
||||
&& $GLOBALS['target'] != 'index.php'
|
||||
) {
|
||||
$url_params['target'] = $GLOBALS['target'];
|
||||
}
|
||||
|
||||
// user logged in successfully after session expiration
|
||||
if(isset($_REQUEST['session_timedout'])) {
|
||||
$response = Response::getInstance();
|
||||
$response->addJSON(
|
||||
'logged_in',
|
||||
1
|
||||
);
|
||||
$response->addJSON(
|
||||
'success',
|
||||
1
|
||||
);
|
||||
$response->addJSON(
|
||||
'new_token',
|
||||
$_SESSION[' PMA_token ']
|
||||
);
|
||||
if($user_changed) {
|
||||
$response->addJSON(
|
||||
'user_changed',
|
||||
1
|
||||
);
|
||||
}
|
||||
if (! defined('TESTSUITE')) {
|
||||
exit;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Set server cookies if required (once per session) and, in this case,
|
||||
// force reload to ensure the client accepts cookies
|
||||
if (! $GLOBALS['from_cookie']) {
|
||||
// URL where to go:
|
||||
$redirect_url = './index.php';
|
||||
|
||||
// any parameters to pass?
|
||||
$url_params = [];
|
||||
if (strlen($GLOBALS['db']) > 0) {
|
||||
$url_params['db'] = $GLOBALS['db'];
|
||||
}
|
||||
if (strlen($GLOBALS['table']) > 0) {
|
||||
$url_params['table'] = $GLOBALS['table'];
|
||||
}
|
||||
// any target to pass?
|
||||
if (! empty($GLOBALS['target'])
|
||||
&& $GLOBALS['target'] != 'index.php'
|
||||
) {
|
||||
$url_params['target'] = $GLOBALS['target'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear user cache.
|
||||
|
||||
@ -4285,17 +4285,26 @@ class Util
|
||||
public static function getStartAndNumberOfRowsPanel($sql_query)
|
||||
{
|
||||
$template = new Template();
|
||||
$pos = isset($_REQUEST['pos'])
|
||||
? $_REQUEST['pos']
|
||||
: $_SESSION['tmpval']['pos'];
|
||||
|
||||
if (isset($_REQUEST['session_max_rows'])) {
|
||||
$rows = $_REQUEST['session_max_rows'];
|
||||
} else if (isset($_SESSION['tmpval']['max_rows'])
|
||||
&& $_SESSION['tmpval']['max_rows'] != 'all'
|
||||
) {
|
||||
$rows = $_SESSION['tmpval']['max_rows'];
|
||||
} else {
|
||||
if ($_SESSION['tmpval']['max_rows'] != 'all') {
|
||||
$rows = $_SESSION['tmpval']['max_rows'];
|
||||
} else {
|
||||
$rows = $GLOBALS['cfg']['MaxRows'];
|
||||
}
|
||||
$rows = $GLOBALS['cfg']['MaxRows'];
|
||||
$_SESSION['tmpval']['max_rows'] = $rows;
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['pos'])) {
|
||||
$pos = $_REQUEST['pos'];
|
||||
} else if(isset($_SESSION['tmpval']['pos'])) {
|
||||
$pos = $_SESSION['tmpval']['pos'];
|
||||
} else {
|
||||
$number_of_line = intval($_REQUEST['unlim_num_rows']);
|
||||
$pos = ((ceil($number_of_line / $rows) - 1) * $rows);
|
||||
$_SESSION['tmpval']['pos'] = $pos;
|
||||
}
|
||||
|
||||
return $template->render('start_and_number_of_rows_panel', [
|
||||
|
||||
@ -1 +1,4 @@
|
||||
</div>
|
||||
{% if check_timeout == true %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<div class="container">
|
||||
{% if session_expired == true %}
|
||||
<div id="modalOverlay">
|
||||
{% endif %}
|
||||
<div class="container{{ add_class }}">
|
||||
<a href="{{ 'https://www.phpmyadmin.net/'|link }}" target="_blank" rel="noopener noreferrer" class="logo">
|
||||
<img src="{{ theme.getImgPath('logo_right.png', 'pma_logo.png') }}" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0" />
|
||||
</a>
|
||||
|
||||
@ -221,7 +221,7 @@ class AuthenticationCookieTest extends PmaTestCase
|
||||
|
||||
$this->assertContains(
|
||||
'<form method="post" id="login_form" action="index.php" name="login_form" ' .
|
||||
'class="disableAjax login hide js-show">',
|
||||
'class="(disableAjax hide login js-show|login js-show)">',
|
||||
$result
|
||||
);
|
||||
|
||||
@ -324,7 +324,7 @@ class AuthenticationCookieTest extends PmaTestCase
|
||||
|
||||
$this->assertContains(
|
||||
'<form method="post" id="login_form" action="index.php" name="login_form" ' .
|
||||
'autocomplete="off" class="disableAjax login hide js-show">',
|
||||
'class="(disableAjax hide login js-show|login js-show)">',
|
||||
$result
|
||||
);
|
||||
|
||||
|
||||
@ -629,6 +629,28 @@ body#loginform div.container {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
div.container.modal_form {
|
||||
margin: 0 auto;
|
||||
width: 30em;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
#login_form {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div#modalOverlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
form.login label {
|
||||
float: <?php echo $left; ?>;
|
||||
width: 10em;
|
||||
|
||||
@ -909,6 +909,28 @@ body#loginform div.container {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
div.container.modal_form {
|
||||
margin: 0 auto;
|
||||
width: 30em;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
#login_form {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div#modalOverlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
form.login label {
|
||||
float: <?php echo $left; ?>;
|
||||
width: 10em;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user