包含:登录失败锁定、90天密码有效期、30分钟会话超时、 强制改密、登录审计日志、屏幕水印、企业背景图、 备案信息固定底部、favicon、JS空集合保护、 会话过期体验优化(403 JSON)、display_errors 关闭、 固定 key 根治 Integrity check failed 等全部改动 注意:config.inc.php/.htaccess/.user.ini 含敏感信息, 通过 .gitignore 排除,勿推送到公开仓库。
265 lines
6.7 KiB
PHP
265 lines
6.7 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace MRBS;
|
|
|
|
use MRBS\Form\ElementFieldset;
|
|
use MRBS\Form\ElementInputSubmit;
|
|
use MRBS\Form\FieldDiv;
|
|
use MRBS\Form\FieldInputPassword;
|
|
use MRBS\Form\FieldInputRadioGroup;
|
|
use MRBS\Form\FieldSelect;
|
|
use MRBS\Form\Form;
|
|
|
|
require "defaultincludes.inc";
|
|
|
|
|
|
function get_field_password(bool $new) : FieldInputPassword
|
|
{
|
|
$field = new FieldInputPassword();
|
|
$field->setLabel(get_vocab('kiosk_password'))
|
|
->setControlAttributes(array(
|
|
'name' => 'kiosk_password',
|
|
'required' => true)
|
|
);
|
|
|
|
if ($new)
|
|
{
|
|
$field->setControlAttribute('autocomplete', 'new-password');
|
|
}
|
|
|
|
|
|
return $field;
|
|
}
|
|
|
|
|
|
function get_fieldset_buttons(?string $returl, string $save_name, string $save_value) : ElementFieldset
|
|
{
|
|
// The Back and Enter buttons
|
|
$fieldset = new ElementFieldset();
|
|
$field = new FieldDiv();
|
|
|
|
// Only include a Back button if there's somewhere to go back to
|
|
if (isset($returl))
|
|
{
|
|
$back = new ElementInputSubmit();
|
|
$back->setAttributes(array(
|
|
'name' => 'back_button',
|
|
'value' => get_vocab('back'),
|
|
'formnovalidate' => true)
|
|
);
|
|
}
|
|
|
|
$submit = new ElementInputSubmit();
|
|
$submit->setAttributes(array(
|
|
'class' => 'default_action',
|
|
'name' => $save_name,
|
|
'value' => $save_value)
|
|
);
|
|
|
|
$field->setAttribute('class', 'submit_buttons')
|
|
->addLabelClass('no_suffix')
|
|
->addControlElement($submit);
|
|
|
|
if (isset($back))
|
|
{
|
|
$field->addLabelElement($back);
|
|
}
|
|
|
|
$fieldset->addElement($field);
|
|
|
|
return $fieldset;
|
|
}
|
|
|
|
|
|
function print_enter_form() : void
|
|
{
|
|
global $kiosk_default_mode;
|
|
global $area, $room;
|
|
|
|
$form = new Form(Form::METHOD_POST);
|
|
|
|
$form->setAttributes(array(
|
|
'class' => 'standard',
|
|
'id' => 'kiosk_enter', // This id is used by the Javascript
|
|
'action' => multisite(this_page()))
|
|
);
|
|
|
|
$fieldset = new ElementFieldset();
|
|
$fieldset->addLegend('');
|
|
|
|
// The mode
|
|
$field = new FieldInputRadioGroup();
|
|
$options = array(
|
|
'area' => get_vocab('area'),
|
|
'room' => get_vocab('room')
|
|
);
|
|
|
|
$value = (isset($kiosk_default_mode) && array_key_exists($kiosk_default_mode, $options)) ? $kiosk_default_mode : 'room';
|
|
|
|
$field->setLabel(get_vocab('mode'))
|
|
->addRadioOptions($options, 'mode', $value, true);
|
|
|
|
$fieldset->addElement($field);
|
|
|
|
// Area
|
|
$field = new FieldSelect();
|
|
$areas = get_area_names();
|
|
$field->setLabel(get_vocab('area'))
|
|
->addSelectOptions($areas, $area, true)
|
|
->setControlAttributes(array(
|
|
'name' => 'area'
|
|
));
|
|
$fieldset->addElement($field);
|
|
|
|
// Room
|
|
$field = new FieldSelect();
|
|
$options = array();
|
|
foreach($areas as $area_id => $area_name)
|
|
{
|
|
$rooms = get_room_names($area_id);
|
|
if (!empty($rooms))
|
|
{
|
|
$options[$area_name] = $rooms;
|
|
}
|
|
}
|
|
$field->setLabel(get_vocab('room'))
|
|
->addSelectOptions($options, $room, true)
|
|
->setControlAttributes(array(
|
|
'name' => 'room'
|
|
));
|
|
|
|
$fieldset->addElement($field);
|
|
|
|
// The kiosk password
|
|
$fieldset->addElement(get_field_password(true));
|
|
|
|
$form->addElement($fieldset);
|
|
|
|
// The Back and Enter buttons
|
|
$return_url = session()->getReferrer();
|
|
$form->addElement(get_fieldset_buttons($return_url, 'enter_button', get_vocab('enter')));
|
|
if (isset($return_url))
|
|
{
|
|
$form->addHiddenInput('return_url', $return_url);
|
|
}
|
|
|
|
|
|
$form->render();
|
|
}
|
|
|
|
|
|
function print_exit_form() : void
|
|
{
|
|
$form = new Form(Form::METHOD_POST);
|
|
|
|
$form->setAttributes(array(
|
|
'class' => 'standard',
|
|
'id' => 'kiosk_exit', // This id is used by the Javascript
|
|
'action' => multisite(this_page()))
|
|
);
|
|
|
|
$fieldset = new ElementFieldset();
|
|
$fieldset->addLegend('');
|
|
|
|
$fieldset->addElement(get_field_password(false));
|
|
$form->addElement($fieldset);
|
|
|
|
// Use an empty string for returl to ensure that the Back button is displayed. As we're in kiosk mode,
|
|
// for security reasons we don't want to use a form variable to pass the return URL; however, we can
|
|
// get the return URL from the session variable.
|
|
$form->addElement(get_fieldset_buttons('', 'exit_button', get_vocab('exit')));
|
|
|
|
$form->render();
|
|
}
|
|
|
|
|
|
$context = array(
|
|
'view' => $view,
|
|
'view_all' => $view_all,
|
|
'year' => $year,
|
|
'month' => $month,
|
|
'day' => $day,
|
|
'area' => $area,
|
|
'room' => $room ?? null,
|
|
'kiosk' => $kiosk ?? null
|
|
);
|
|
|
|
if (!empty(get_form_var('back_button')))
|
|
{
|
|
// For security reasons, we don't put the return_url in a form variable when we're in kiosk mode.
|
|
if (is_kiosk_mode())
|
|
{
|
|
$return_url = session()->isset('kiosk_url') ? session()->get('kiosk_url') : null;
|
|
}
|
|
else
|
|
{
|
|
$return_url = get_form_var('return_url', 'url_local');
|
|
}
|
|
location_header((!empty($return_url)) ? $return_url : multisite("index.php"));
|
|
// location_header() includes an exit
|
|
}
|
|
|
|
// Check whether they are trying to exit kiosk mode
|
|
if (!empty($kiosk) && session()->isset('kiosk_password_hash'))
|
|
{
|
|
// Check the CSRF token
|
|
Form::checkToken();
|
|
print_header($context);
|
|
echo "<h1>" . get_vocab('exit_kiosk_mode') . "</h1>\n";
|
|
echo "<p>" . get_vocab('exit_kiosk_intro') . "</p>\n";
|
|
print_exit_form();
|
|
print_footer(true);
|
|
}
|
|
|
|
$kiosk_password = get_form_var('kiosk_password');
|
|
|
|
if (!empty(get_form_var('exit_button')))
|
|
{
|
|
// Phase 2 (Exit) - Check the CSRF token
|
|
Form::checkToken();
|
|
$location = (session()->isset('kiosk_url')) ? session()->get('kiosk_url') : 'index.php?kiosk=' . $kiosk_default_mode;
|
|
if (session()->isset('kiosk_password_hash') && password_verify($kiosk_password, session()->get('kiosk_password_hash')))
|
|
{
|
|
session()->unset('kiosk_url');
|
|
session()->unset('kiosk_password_hash');
|
|
$location = remove_query_parameter($location, 'kiosk');
|
|
}
|
|
location_header(multisite($location));
|
|
// location_header() includes an exit
|
|
}
|
|
|
|
// Check the user is authorised for this page
|
|
if (!checkAuthorised(this_page()))
|
|
{
|
|
exit;
|
|
}
|
|
|
|
if (!empty(get_form_var('enter_button')))
|
|
{
|
|
// Phase 2 (Enter) - Check the CSRF token enter kiosk mode
|
|
Form::checkToken();
|
|
$mode = get_form_var('mode');
|
|
|
|
if (method_exists(session(), 'logoffUser'))
|
|
{
|
|
session()->logoffUser();
|
|
}
|
|
session()->init(0); // We only want the session to expire when the browser is closed
|
|
|
|
$kiosk_url = multisite(url_base() . "index.php?kiosk=$mode&area=$area&room=$room");
|
|
session()->set('kiosk_password_hash', password_hash($kiosk_password, PASSWORD_DEFAULT));
|
|
session()->set('kiosk_url', $kiosk_url);
|
|
|
|
location_header($kiosk_url);
|
|
// location_header() includes an exit
|
|
}
|
|
|
|
// Phase 1
|
|
|
|
// Print the page header
|
|
print_header($context);
|
|
echo "<h1>" . get_vocab('enter_kiosk_mode') . "</h1>\n";
|
|
echo "<p>" . get_vocab('enter_kiosk_intro') . "</p>\n";
|
|
print_enter_form();
|
|
print_footer();
|