ACL Login update layout to work with PC/Smartphone
Updated login template and password change template block
This commit is contained in:
@@ -180,6 +180,7 @@ class Login
|
|||||||
private array $login_template = [
|
private array $login_template = [
|
||||||
'strings' => [],
|
'strings' => [],
|
||||||
'password_change' => '',
|
'password_change' => '',
|
||||||
|
'password_forgot' => '',
|
||||||
'template' => ''
|
'template' => ''
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -232,13 +233,12 @@ class Login
|
|||||||
* @param \CoreLibs\Logging\Logging $log Logging class
|
* @param \CoreLibs\Logging\Logging $log Logging class
|
||||||
* @param \CoreLibs\Create\Session $session Session interface class
|
* @param \CoreLibs\Create\Session $session Session interface class
|
||||||
* @param array<string,mixed> $options Login ACL settings
|
* @param array<string,mixed> $options Login ACL settings
|
||||||
* $auto_login [default true] DEPRECATED, moved into options
|
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
\CoreLibs\DB\IO $db,
|
\CoreLibs\DB\IO $db,
|
||||||
\CoreLibs\Logging\Logging $log,
|
\CoreLibs\Logging\Logging $log,
|
||||||
\CoreLibs\Create\Session $session,
|
\CoreLibs\Create\Session $session,
|
||||||
array $options = []
|
array $options = [],
|
||||||
) {
|
) {
|
||||||
// attach db class
|
// attach db class
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
@@ -1601,6 +1601,10 @@ class Login
|
|||||||
$this->login_template['strings']['LANGUAGE'] = $locales['lang'] ?? 'en';
|
$this->login_template['strings']['LANGUAGE'] = $locales['lang'] ?? 'en';
|
||||||
|
|
||||||
// if password change is okay
|
// if password change is okay
|
||||||
|
// TODO: this should be a "forgot" password
|
||||||
|
// -> input email
|
||||||
|
// -> send to user with link + token
|
||||||
|
// -> validate token -> show change password
|
||||||
if ($this->password_change) {
|
if ($this->password_change) {
|
||||||
$html_string_password_change = $this->login_template['password_change'];
|
$html_string_password_change = $this->login_template['password_change'];
|
||||||
|
|
||||||
@@ -1617,14 +1621,14 @@ class Login
|
|||||||
// print error messagae
|
// print error messagae
|
||||||
if ($this->login_error) {
|
if ($this->login_error) {
|
||||||
$html_string_password_change = str_replace(
|
$html_string_password_change = str_replace(
|
||||||
'{ERROR_MSG}',
|
['{ERROR_VISIBLE}', '{ERROR_MSG}'],
|
||||||
$this->loginGetErrorMsg($this->login_error) . '<br>',
|
['login-visible', $this->loginGetErrorMsg($this->login_error)],
|
||||||
$html_string_password_change
|
$html_string_password_change
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$html_string_password_change = str_replace(
|
$html_string_password_change = str_replace(
|
||||||
'{ERROR_MSG}',
|
['{ERROR_VISIBLE}', '{ERROR_MSG}'],
|
||||||
'<br>',
|
['login-hidden', ''],
|
||||||
$html_string_password_change
|
$html_string_password_change
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1632,8 +1636,11 @@ class Login
|
|||||||
if ($this->change_password && !$this->password_change_ok) {
|
if ($this->change_password && !$this->password_change_ok) {
|
||||||
$html_string_password_change = str_replace(
|
$html_string_password_change = str_replace(
|
||||||
'{PASSWORD_CHANGE_SHOW}',
|
'{PASSWORD_CHANGE_SHOW}',
|
||||||
'<script language="JavaScript">'
|
<<<HTML
|
||||||
. 'ShowHideDiv(\'pw_change_div\');</script>',
|
<script language="JavaScript">
|
||||||
|
ShowHideDiv('login_pw_change_div');
|
||||||
|
</script>
|
||||||
|
HTML,
|
||||||
$html_string_password_change
|
$html_string_password_change
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -1660,18 +1667,22 @@ class Login
|
|||||||
// print error messagae
|
// print error messagae
|
||||||
if ($this->login_error) {
|
if ($this->login_error) {
|
||||||
$html_string = str_replace(
|
$html_string = str_replace(
|
||||||
'{ERROR_MSG}',
|
['{ERROR_VISIBLE}', '{ERROR_MSG}'],
|
||||||
$this->loginGetErrorMsg($this->login_error) . '<br>',
|
['login-visible', $this->loginGetErrorMsg($this->login_error)],
|
||||||
$html_string
|
$html_string
|
||||||
);
|
);
|
||||||
} elseif ($this->password_change_ok && $this->password_change) {
|
} elseif ($this->password_change_ok && $this->password_change) {
|
||||||
$html_string = str_replace(
|
$html_string = str_replace(
|
||||||
'{ERROR_MSG}',
|
['{ERROR_VISIBLE}', '{ERROR_MSG}'],
|
||||||
$this->loginGetErrorMsg(300) . '<br>',
|
['login-visible', $this->loginGetErrorMsg(300)],
|
||||||
$html_string
|
$html_string
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$html_string = str_replace('{ERROR_MSG}', '<br>', $html_string);
|
$html_string = str_replace(
|
||||||
|
['{ERROR_VISIBLE}', '{ERROR_MSG}'],
|
||||||
|
['login-hidden', ''],
|
||||||
|
$html_string
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the replace array context
|
// create the replace array context
|
||||||
@@ -1756,39 +1767,93 @@ class Login
|
|||||||
'NEW_PASSWORD' => $this->l->__('New Password'),
|
'NEW_PASSWORD' => $this->l->__('New Password'),
|
||||||
'NEW_PASSWORD_CONFIRM' => $this->l->__('New Password confirm'),
|
'NEW_PASSWORD_CONFIRM' => $this->l->__('New Password confirm'),
|
||||||
'CLOSE' => $this->l->__('Close'),
|
'CLOSE' => $this->l->__('Close'),
|
||||||
'JS_SHOW_HIDE' => "function ShowHideDiv(id) { "
|
'JS_SHOW_HIDE' => <<<JAVASCRIPT
|
||||||
. "element = document.getElementById(id); "
|
function ShowHideDiv(id) {
|
||||||
. "if (element.className == 'visible' || !element.className) element.className = 'hidden'; "
|
element = document.getElementById(id);
|
||||||
. "else element.className = 'visible'; }",
|
let visible = !!(
|
||||||
'PASSWORD_CHANGE_BUTTON' => '<input type="button" name="pw_change" value="'
|
element.offsetWidth ||
|
||||||
. $strings['PASSWORD_CHANGE_BUTTON_VALUE']
|
element.offsetHeight ||
|
||||||
. '" OnClick="ShowHideDiv(\'pw_change_div\');">'
|
element.getClientRects().length ||
|
||||||
|
window.getComputedStyle(element).visibility == "hidden"
|
||||||
|
);
|
||||||
|
if (visiblee) {
|
||||||
|
element.className = 'login-hidden';
|
||||||
|
} else {
|
||||||
|
element.className = 'login-visible';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JAVASCRIPT,
|
||||||
|
'PASSWORD_CHANGE_BUTTON' => str_replace(
|
||||||
|
'{PASSWORD_CHANGE_BUTTON_VALUE}',
|
||||||
|
$strings['PASSWORD_CHANGE_BUTTON_VALUE'],
|
||||||
|
// phpcs:disable Generic.Files.LineLength
|
||||||
|
<<<HTML
|
||||||
|
<input type="button" name="pw_change" value="{PASSWORD_CHANGE_BUTTON_VALUE}" OnClick="ShowHideDiv('login_pw_change_div'); return false;">
|
||||||
|
HTML
|
||||||
|
// phpcs:enable Generic.Files.LineLength
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
// TODO: submit or JS to set target page as ajax call
|
// phpcs:disable Generic.Files.LineLength
|
||||||
// NOTE: for the HTML block I ignore line lengths
|
|
||||||
// phpcs:disable
|
|
||||||
$this->login_template['password_change'] = <<<HTML
|
$this->login_template['password_change'] = <<<HTML
|
||||||
<div id="pw_change_div" class="hidden" style="position: absolute; top: 30px; left: 50px; width: 400px; height: 220px; background-color: white; border: 1px solid black; padding: 25px;">
|
<div id="loginPasswordChangeBox" class="login-password-change login-hidden">
|
||||||
<table>
|
<div id="loginTitle" class="login-title">
|
||||||
<tr><td class="norm" align="center" colspan="2"><h3>{TITLE_PASSWORD_CHANGE}</h3></td></tr>
|
{TITLE_PASSWORD_CHANGE}
|
||||||
<tr><td class="norm" colspan="2">{ERROR_MSG}</td></tr>
|
</div>
|
||||||
<tr><td class="norm" align="right">{USERNAME}</td><td><input type="text" name="pw_username" value=""></td></tr>
|
<div id="loginPasswordChangeError" class="login-error {ERROR_VISIBLE}">
|
||||||
<tr><td class="norm" align="right">{OLD_PASSWORD}</td>
|
{ERROR_MSG}
|
||||||
<td><input type="password" name="pw_old_password" value=""></td></tr>
|
</div>
|
||||||
<tr><td class="norm" align="right">{NEW_PASSWORD}</td>
|
<div id="loginPasswordChange" class="login-data">
|
||||||
<td><input type="password" name="pw_new_password" value=""></td></tr>
|
<div class="login-data-row">
|
||||||
<tr><td class="norm" align="right">{NEW_PASSWORD_CONFIRM}</td>
|
<div class="login-data-left">
|
||||||
<td><input type="password" name="pw_new_password_confirm" value=""></td></tr>
|
{USERNAME}
|
||||||
<tr><td></td>
|
</div>
|
||||||
<td><input type="submit" name="change_password" value="{PASSWORD_CHANGE_BUTTON_VALUE}">
|
<div class="login-data-right">
|
||||||
<input type="button" name="pw_change" value="{CLOSE}" OnClick="ShowHideDiv('pw_change_div');"></td></tr>
|
<input type="text" name="login_username" class="login-input-text">
|
||||||
</table>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="login-data-row">
|
||||||
|
<div class="login-data-left">
|
||||||
|
{OLD_PASSWORD}
|
||||||
|
</div>
|
||||||
|
<div class="login-data-right">
|
||||||
|
<input type="password" name="login_pw_old_password" class="login-input-text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="login-data-row">
|
||||||
|
<div class="login-data-left">
|
||||||
|
{NEW_PASSWORD}
|
||||||
|
</div>
|
||||||
|
<div class="login-data-right">
|
||||||
|
<input type="password" name="login_pw_new_password" class="login-input-text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="login-data-row">
|
||||||
|
<div class="login-data-left">
|
||||||
|
{NEW_PASSWORD_CONFIRM}
|
||||||
|
</div>
|
||||||
|
<div class="login-data-right">
|
||||||
|
<input type="password" name="login_pw_new_password_confirm" class="login-input-text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="login-data-row login-button-row">
|
||||||
|
<div class="login-data-left">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="login-data-right">
|
||||||
|
<button type="submit" name="login_change_password" class="login-button" value="{PASSWORD_CHANGE_BUTTON_VALUE}">{PASSWORD_CHANGE_BUTTON_VALUE}</button>
|
||||||
|
</div>
|
||||||
|
<div class="login-data-button">
|
||||||
|
<button type="button" name="login_pw_change" class="login-button" value="{CLOSE}" OnClick="ShowHideDiv('loginPasswordChangeBox'); return false;">{CLOSE}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{PASSWORD_CHANGE_SHOW}
|
{PASSWORD_CHANGE_SHOW}
|
||||||
HTML;
|
HTML;
|
||||||
// phpcs:enable
|
// phpcs:enable Generic.Files.LineLength
|
||||||
}
|
}
|
||||||
if ($this->password_forgot) {
|
if ($this->password_forgot) {
|
||||||
|
// TODO: create a password forget request flow
|
||||||
}
|
}
|
||||||
if (!$this->password_change && !$this->password_forgot) {
|
if (!$this->password_change && !$this->password_forgot) {
|
||||||
$strings = array_merge($strings, [
|
$strings = array_merge($strings, [
|
||||||
@@ -1807,71 +1872,162 @@ HTML;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now check templates
|
// now check templates
|
||||||
// TODO: submit or JS to set target page as ajax call
|
|
||||||
if (!$this->login_template['template']) {
|
if (!$this->login_template['template']) {
|
||||||
|
// phpcs:disable Generic.Files.LineLength
|
||||||
$this->login_template['template'] = <<<HTML
|
$this->login_template['template'] = <<<HTML
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{LANGUAGE}">
|
<html lang="{LANGUAGE}">
|
||||||
<head>
|
<head>
|
||||||
<title>{HTML_TITLE}</title>
|
<meta charset="utf-8">
|
||||||
<style type="text/css">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
.norm { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; line-height: 15px; color: #000000}
|
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
|
||||||
h3 { font-size: 18px; }
|
<title>{HTML_TITLE}</title>
|
||||||
.visible { visibility: visible; }
|
<style type="text/css">
|
||||||
.hidden { visibility: hidden; display: none; }
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 100%;
|
||||||
|
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.login-box {
|
||||||
|
margin: 50px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.login-title {
|
||||||
|
font-size: 2em;
|
||||||
|
padding: 1% 0 1% 10%;
|
||||||
|
background-color: hsl(0, 0%, 90%);
|
||||||
|
}
|
||||||
|
.login-error {
|
||||||
|
margin: 2% 5%;
|
||||||
|
}
|
||||||
|
.login-data {
|
||||||
|
margin: 0 5% 5% 5%;
|
||||||
|
}
|
||||||
|
.login-data-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
.login-data-row .login-data-left {
|
||||||
|
width: 10%;
|
||||||
|
font-size: 0.8em;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 5px;
|
||||||
|
margin: auto 0;
|
||||||
|
}
|
||||||
|
.login-data-row .login-data-right {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
.login-data-row .login-data-button {
|
||||||
|
width: 70%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
input.login-input-text {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
button.login-button {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
.login-visible {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.login-hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.login-password-change {
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
left: 10%;
|
||||||
|
width: 80%;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
@media only screen and ( max-width: 749px ) {
|
||||||
|
.login-box {
|
||||||
|
margin: 5% 0;
|
||||||
|
}
|
||||||
|
.login-data {
|
||||||
|
margin: 0 5% 5% 5%;
|
||||||
|
}
|
||||||
|
.login-error {
|
||||||
|
margin: 10% 5%;
|
||||||
|
}
|
||||||
|
.login-data-row {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.login-data-row .login-data-left,
|
||||||
|
.login-data-row .login-data-right,
|
||||||
|
.login-data-row .login-data-button {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.login-data-row .login-data-left {
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
.login-data-row .login-data-button {
|
||||||
|
text-align: left;
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
.login-password-change {
|
||||||
|
top: 5%;
|
||||||
|
left: 5%;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script language="JavaScript">
|
<script language="JavaScript">
|
||||||
<!--
|
|
||||||
{JS_SHOW_HIDE}
|
{JS_SHOW_HIDE}
|
||||||
//-->
|
</script>
|
||||||
</script>
|
|
||||||
{LOGOUT_TARGET}
|
{LOGOUT_TARGET}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF">
|
<body bgcolor="#FFFFFF">
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<table width="500" border="0" cellpadding="2" cellspacing="1">
|
<div id="loginBox" class="login-box">
|
||||||
<tr>
|
<div id="loginTitle" class="login-title">
|
||||||
<td class="norm" align="right">
|
{TITLE}
|
||||||
<h3>{TITLE}</h3>
|
</div>
|
||||||
</td>
|
<div id="loginError" class="login-error {ERROR_VISIBLE}">
|
||||||
<td> </td>
|
{ERROR_MSG}
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div id="loginData" class="login-data">
|
||||||
<td class="norm" colspan="2" align="center">
|
<div class="login-data-row">
|
||||||
{ERROR_MSG}
|
<div class="login-data-left">
|
||||||
</td>
|
{USERNAME}
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div class="login-data-right">
|
||||||
<td align="right" class="norm">{USERNAME}</td>
|
<input type="text" name="login_username" class="login-input-text">
|
||||||
<td><input type="text" name="login_username"></td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div class="login-data-row">
|
||||||
<td align="right" class="norm">{PASSWORD}</td>
|
<div class="login-data-left">
|
||||||
<td><input type="password" name="login_password"></td>
|
{PASSWORD}
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div class="login-data-right">
|
||||||
<td align="right"></td>
|
<input type="password" name="login_password" class="login-input-text">
|
||||||
<td>
|
</div>
|
||||||
<input type="submit" name="login_login" value="{LOGIN}">
|
</div>
|
||||||
{PASSWORD_CHANGE_BUTTON}
|
<div class="login-data-row login-button-row">
|
||||||
</td>
|
<div class="login-data-left">
|
||||||
</tr>
|
|
||||||
<tr>
|
</div>
|
||||||
<td align="right">
|
<div class="login-data-right">
|
||||||
<br><br>
|
<button type="submit" name="login_login" class="login-button" value="{LOGIN}">{LOGIN}</button>
|
||||||
</td>
|
{PASSWORD_CHANGE_BUTTON}
|
||||||
<td> </td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
</table>
|
</div>
|
||||||
{PASSWORD_CHANGE_DIV}
|
{PASSWORD_CHANGE_DIV}
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
HTML;
|
HTML;
|
||||||
|
// phpcs:enable Generic.Files.LineLength
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2167,11 +2323,11 @@ HTML;
|
|||||||
$this->password = $_POST['login_password'] ?? '';
|
$this->password = $_POST['login_password'] ?? '';
|
||||||
$this->logout = $_POST['login_logout'] ?? '';
|
$this->logout = $_POST['login_logout'] ?? '';
|
||||||
// password change vars
|
// password change vars
|
||||||
$this->change_password = $_POST['change_password'] ?? '';
|
$this->change_password = $_POST['login_change_password'] ?? '';
|
||||||
$this->pw_username = $_POST['pw_username'] ?? '';
|
$this->pw_username = $_POST['login_pw_username'] ?? '';
|
||||||
$this->pw_old_password = $_POST['pw_old_password'] ?? '';
|
$this->pw_old_password = $_POST['login_pw_old_password'] ?? '';
|
||||||
$this->pw_new_password = $_POST['pw_new_password'] ?? '';
|
$this->pw_new_password = $_POST['login_pw_new_password'] ?? '';
|
||||||
$this->pw_new_password_confirm = $_POST['pw_new_password_confirm'] ?? '';
|
$this->pw_new_password_confirm = $_POST['login_pw_new_password_confirm'] ?? '';
|
||||||
// disallow user list for password change
|
// disallow user list for password change
|
||||||
$this->pw_change_deny_users = ['admin'];
|
$this->pw_change_deny_users = ['admin'];
|
||||||
// max login counts before error reporting
|
// max login counts before error reporting
|
||||||
|
|||||||
Reference in New Issue
Block a user