many fixes and expands and module expansions

This commit is contained in:
Dennis Eichhorn 2021-04-04 17:10:51 +02:00
parent 857e9aea6e
commit 3104ac6cbd
12 changed files with 236 additions and 27 deletions

View File

@ -18,7 +18,7 @@
"pid": "/",
"type": 2,
"subtype": 1,
"name": "General",
"name": "Settings",
"uri": "{/prefix}admin/settings/general?{?}",
"target": "self",
"icon": null,

View File

@ -584,7 +584,7 @@
},
"group_permission_from": {
"name": "group_permission_from",
"type": "INT",
"type": "VARCHAR(255)",
"default": null,
"null": true
},
@ -781,7 +781,7 @@
},
"account_permission_from": {
"name": "account_permission_from",
"type": "INT",
"type": "VARCHAR(255)",
"default": null,
"null": true
},

View File

@ -170,7 +170,7 @@ return [
'dest' => '\Modules\Admin\Controller\ApiController:apiSettingsAccountLocalizationSet',
'verb' => RouteVerb::SET,
'permission' => [
'module' => AdminApiController::MODULE_NAME,
'module' => ApiController::MODULE_NAME,
'type' => PermissionType::MODIFY,
'state' => PermissionState::ACCOUNT_SETTINGS,
],

View File

@ -55,8 +55,13 @@ use phpOMS\System\File\Local\File;
use phpOMS\System\MimeType;
use phpOMS\Uri\HttpUri;
use phpOMS\Utils\Parser\Markdown\Markdown;
use phpOMS\Validation\Network\Email;
use phpOMS\Validation\Network\Email as EmailValidator;
use phpOMS\Version\Version;
use phpOMS\Message\Mail\Email;
use phpOMS\Message\Mail\Imap;
use phpOMS\Message\Mail\MailHandler;
use phpOMS\Message\Mail\SubmitType;
use phpOMS\System\CharsetType;
/**
* Admin controller class.
@ -131,7 +136,7 @@ final class ApiController extends Controller
}
/**
* Api method to login
* Api method to send forgotten password email
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -145,6 +150,65 @@ final class ApiController extends Controller
*/
public function apiForgot(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
$account = AccountMapper::getBy((string) $request->getData('login'), 'login');
$forgotten = $this->app->appSettings->get(
null,
['forgott_date', 'forgrott_count'],
self::MODULE_NAME,
null,
$account->getId()
);
if ((int) $forgotten['forgrotten_count'] > 3) {
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
$response->set($request->uri->__toString(), [
'status' => NotificationLevel::ERROR,
'title' => 'Password Reset',
'message' => 'Password reset failed due to invalid login data or too many reset attemps.',
'response' => null,
]);
}
$handler = new MailHandler();
$handler->setMailer(SubmitType::MAIL);
$mail = new Email();
$mail->setFrom('test1@orange-management.email', 'Orange-Management');
$mail->addTo($account->email, \trim($account->name1 . ' ' . $account->name2 . ' ' . $account->name3));
$mail->subject = 'Orange Management: Forgot Password';
$mail->body = 'Please reset your password at: .....';
$this->app->appSettings->set([
['name' => 'forgott_date', 'module' => self::MODULE_NAME, 'account' => $account->getId(), 'content' => (string) \time()],
['name' => 'forgotten_count', 'module' => self::MODULE_NAME, 'account' => $account->getId(), 'content' => (string) (((int) $forgotten['forgrotten_count']) + 1)],
], true);
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
$response->set($request->uri->__toString(), [
'status' => NotificationLevel::OK,
'title' => 'Password Reset',
'message' => 'You received a pasword reset email.',
'response' => null,
]);
}
/**
* Api method to reset the password
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiResetPassword(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
// @todo: implement
}
/**
@ -707,7 +771,7 @@ final class ApiController extends Controller
if (($val['name1'] = empty($request->getData('name1')))
|| ($val['type'] = !AccountType::isValidValue((int) $request->getData('type')))
|| ($val['status'] = !AccountStatus::isValidValue((int) $request->getData('status')))
|| ($val['email'] = !empty($request->getData('email')) && !Email::isValid((string) $request->getData('email')))
|| ($val['email'] = !empty($request->getData('email')) && !EmailValidator::isValid((string) $request->getData('email')))
) {
return $val;
}

View File

@ -31,6 +31,7 @@ use phpOMS\Message\ResponseAbstract;
use phpOMS\Module\ModuleInfo;
use phpOMS\Utils\StringUtils;
use phpOMS\Views\View;
use Model\SettingMapper;
/**
* Admin controller class.
@ -78,15 +79,18 @@ final class BackendController extends Controller
public function viewSettingsGeneral(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$settings = $this->app->appSettings->get(null, [
$generalSettings = $this->app->appSettings->get(null, [
SettingsEnum::PASSWORD_PATTERN, SettingsEnum::LOGIN_TIMEOUT, SettingsEnum::PASSWORD_INTERVAL, SettingsEnum::PASSWORD_HISTORY, SettingsEnum::LOGIN_TRIES, SettingsEnum::LOGGING_STATUS, SettingsEnum::LOGGING_PATH, SettingsEnum::DEFAULT_ORGANIZATION,
SettingsEnum::LOGIN_STATUS, SettingsEnum::DEFAULT_LOCALIZATION, SettingsEnum::ADMIN_MAIL,
]);
$view->setTemplate('/Modules/Admin/Theme/Backend/settings-general');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1000104001, $request, $response));
$view->setData('settings', $settings);
$view->setData('defaultlocalization', LocalizationMapper::get((int) $settings[SettingsEnum::DEFAULT_LOCALIZATION]));
$view->setData('generalSettings', $generalSettings);
$view->setData('defaultlocalization', LocalizationMapper::get((int) $generalSettings[SettingsEnum::DEFAULT_LOCALIZATION]));
$view->setData('settings', SettingMapper::getAll());
return $view;
}

View File

@ -44,7 +44,7 @@ class AccountPermission extends PermissionAbstract
* @param null|int $unit Unit Unit to check (null if all are acceptable)
* @param null|string $app App App to check (null if all are acceptable)
* @param null|string $module Module to check (null if all are acceptable)
* @param int $from Module providing this permission
* @param null|string $from Module providing this permission
* @param null|int $type Type (e.g. customer) (null if all are acceptable)
* @param null|int $element (e.g. customer id) (null if all are acceptable)
* @param null|int $component (e.g. address) (null if all are acceptable)
@ -57,7 +57,7 @@ class AccountPermission extends PermissionAbstract
int $unit = null,
string $app = null,
string $module = null,
int $from = 0,
string $from = null,
int $type = null,
int $element = null,
int $component = null,

View File

@ -38,7 +38,7 @@ final class AccountPermissionMapper extends DataMapperAbstract
'account_permission_unit' => ['name' => 'account_permission_unit', 'type' => 'int', 'internal' => 'unit'],
'account_permission_app' => ['name' => 'account_permission_app', 'type' => 'string', 'internal' => 'app'],
'account_permission_module' => ['name' => 'account_permission_module', 'type' => 'string', 'internal' => 'module'],
'account_permission_from' => ['name' => 'account_permission_from', 'type' => 'int', 'internal' => 'from'],
'account_permission_from' => ['name' => 'account_permission_from', 'type' => 'string', 'internal' => 'from'],
'account_permission_type' => ['name' => 'account_permission_type', 'type' => 'int', 'internal' => 'type'],
'account_permission_element' => ['name' => 'account_permission_element', 'type' => 'int', 'internal' => 'element'],
'account_permission_component' => ['name' => 'account_permission_component', 'type' => 'int', 'internal' => 'component'],

View File

@ -41,4 +41,46 @@ class Address extends Location
* @since 1.0.0
*/
public string $addition = '';
/**
* {@inheritdoc}
*/
public function toArray() : array
{
$data = parent::toArray();
$data['name'] = $this->name;
$data['addition'] = $this->addition;
return $data;
}
/**
* {@inheritdoc}
*/
public function jsonSerialize()
{
return $this->toArray();
}
/**
* {@inheritdoc}
*/
public function serialize() : string
{
return (string) \json_encode($this->jsonSerialize());
}
/**
* {@inheritdoc}
*/
public function unserialize($serialized) : void
{
parent::unserialize($serialized);
$data = \json_decode($serialized, true);
$this->name = $data['name'];
$this->addition = $data['addition'];
}
}

View File

@ -44,7 +44,7 @@ class GroupPermission extends PermissionAbstract
* @param null|int $unit Unit Unit to check (null if all are acceptable)
* @param null|string $app App App to check (null if all are acceptable)
* @param null|string $module Module to check (null if all are acceptable)
* @param int $from Module providing this permission
* @param null|string $from Module providing this permission
* @param null|int $type Type (e.g. customer) (null if all are acceptable)
* @param null|int $element (e.g. customer id) (null if all are acceptable)
* @param null|int $component (e.g. address) (null if all are acceptable)
@ -57,7 +57,7 @@ class GroupPermission extends PermissionAbstract
int $unit = null,
string $app = null,
string $module = null,
int $from = 0,
string $from = null,
int $type = null,
int $element = null,
int $component = null,

View File

@ -38,7 +38,7 @@ final class GroupPermissionMapper extends DataMapperAbstract
'group_permission_unit' => ['name' => 'group_permission_unit', 'type' => 'int', 'internal' => 'unit'],
'group_permission_app' => ['name' => 'group_permission_app', 'type' => 'string', 'internal' => 'app'],
'group_permission_module' => ['name' => 'group_permission_module', 'type' => 'string', 'internal' => 'module'],
'group_permission_from' => ['name' => 'group_permission_from', 'type' => 'int', 'internal' => 'from'],
'group_permission_from' => ['name' => 'group_permission_from', 'type' => 'string', 'internal' => 'from'],
'group_permission_type' => ['name' => 'group_permission_type', 'type' => 'int', 'internal' => 'type'],
'group_permission_element' => ['name' => 'group_permission_element', 'type' => 'int', 'internal' => 'element'],
'group_permission_component' => ['name' => 'group_permission_component', 'type' => 'int', 'internal' => 'component'],

View File

@ -29,9 +29,15 @@ echo $this->getData('nav')->render(); ?>
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('Accounts'); ?><i class="fa fa-download floatRight download btn"></i></div>
<div class="portlet-head">
<?= $this->getHtml('Accounts'); ?>
<?php include __DIR__ . '/../../../../Web/Backend/Themes/popup-export-data.tpl.php'; ?>
</div>
<table id="accountList" class="default">
<thead>
<template>
</template>
<tr>
<td><?= $this->getHtml('ID', '0', '0'); ?>
<label for="accountList-r1-asc">
@ -42,9 +48,7 @@ echo $this->getData('nav')->render(); ?>
<input id="accountList-r1-desc" name="accountList-sort" type="radio">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<?php include __DIR__ . '/../../../../Web/Backend/Themes/popup-export-data.tpl.php'; ?>
<td><?= $this->getHtml('Status'); ?>
<label for="accountList-r2-asc">
<input id="accountList-r2-asc" name="accountList-sort" type="radio">

View File

@ -19,6 +19,7 @@ use phpOMS\Uri\UriFactory;
/**
* @var \phpOMS\Views\View $this
*/
$generalSettings = $this->getData('generalSettings') ?? [];
$settings = $this->getData('settings') ?? [];
$countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants();
@ -44,6 +45,7 @@ $l11n = $this->getData('defaultlocalization') ?? new NullLocalization();
<ul class="tab-links">
<li><label for="c-tab-1"><?= $this->getHtml('General'); ?></label></li>
<li><label for="c-tab-2"><?= $this->getHtml('Localization'); ?></label></li>
<li><label for="c-tab-3"><?= $this->getHtml('Settings'); ?></label></li>
</ul>
</div>
<div class="tab-content">
@ -60,7 +62,7 @@ $l11n = $this->getData('defaultlocalization') ?? new NullLocalization();
<tr><td><label for="iOname"><?= $this->getHtml('OrganizationName'); ?></label>
<tr><td>
<select id="iOname" name="settings_1000000009">
<?php $unit = UnitMapper::get((int) $settings[1000000009]); ?>
<?php $unit = UnitMapper::get((int) $generalSettings[1000000009]); ?>
<option value="<?= $unit->getId(); ?>"><?= $this->printHtml($unit->name); ?>
</select>
</table>
@ -80,23 +82,23 @@ $l11n = $this->getData('defaultlocalization') ?? new NullLocalization();
<tr><td>
<label for="iPassword"><?= $this->getHtml('PasswordRegex'); ?></label>
<i class="tooltip" data-tooltip="<?= $this->getHtml('i:PasswordRegex'); ?>"><i class="fa fa-info-circle"></i></i>
<tr><td><input id="iPassword" name="settings_1000000001" type="text" value="<?= $this->printHtml($settings['1000000001']['content']); ?>" placeholder="&#xf023; ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&;:\(\)\[\]=\{\}\+\-])[A-Za-z\d$@$!%*?&;:\(\)\[\]=\{\}\+\-]{8,}">
<tr><td><input id="iPassword" name="settings_1000000001" type="text" value="<?= $this->printHtml($generalSettings['1000000001']['content']); ?>" placeholder="&#xf023; ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&;:\(\)\[\]=\{\}\+\-])[A-Za-z\d$@$!%*?&;:\(\)\[\]=\{\}\+\-]{8,}">
<tr><td>
<label for="iLoginRetries"><?= $this->getHtml('LoginRetries'); ?></label>
<i class="tooltip" data-tooltip="<?= $this->getHtml('i:LoginRetries'); ?>"><i class="fa fa-info-circle"></i></i>
<tr><td><input id="iLoginRetries" name="settings_1000000005" type="number" value="<?= $this->printHtml($settings['1000000005']['content']); ?>" min="-1">
<tr><td><input id="iLoginRetries" name="settings_1000000005" type="number" value="<?= $this->printHtml($generalSettings['1000000005']['content']); ?>" min="-1">
<tr><td>
<label for="iTimeoutPeriod"><?= $this->getHtml('TimeoutPeriod'); ?></label>
<i class="tooltip" data-tooltip="<?= $this->getHtml('i:TimeoutPeriod'); ?>"><i class="fa fa-info-circle"></i></i>
<tr><td><input id="iTimeoutPeriod" name="settings_1000000002" type="number" value="<?= $this->printHtml($settings['1000000002']['content']); ?>">
<tr><td><input id="iTimeoutPeriod" name="settings_1000000002" type="number" value="<?= $this->printHtml($generalSettings['1000000002']['content']); ?>">
<tr><td>
<label for="iPasswordChangeInterval"><?= $this->getHtml('PasswordChangeInterval'); ?></label>
<i class="tooltip" data-tooltip="<?= $this->getHtml('i:PasswordChangeInterval'); ?>"><i class="fa fa-info-circle"></i></i>
<tr><td><input id="iPasswordChangeInterval" name="settings_1000000003" type="number" value="<?= $this->printHtml($settings['1000000003']['content']); ?>">
<tr><td><input id="iPasswordChangeInterval" name="settings_1000000003" type="number" value="<?= $this->printHtml($generalSettings['1000000003']['content']); ?>">
<tr><td>
<label for="iPasswordHistory"><?= $this->getHtml('PasswordHistory'); ?></label>
<i class="tooltip" data-tooltip="<?= $this->getHtml('i:PasswordHistory'); ?>"><i class="fa fa-info-circle"></i></i>
<tr><td><input id="iPasswordHistory" name="settings_1000000004" type="number" value="<?= $this->printHtml($settings['1000000004']['content']); ?>">
<tr><td><input id="iPasswordHistory" name="settings_1000000004" type="number" value="<?= $this->printHtml($generalSettings['1000000004']['content']); ?>">
</table>
</div>
<div class="portlet-foot"><input id="iSubmitGeneral" name="submitGeneral" type="submit" value="<?= $this->getHtml('Save', '0', '0'); ?>"></div>
@ -118,7 +120,7 @@ $l11n = $this->getData('defaultlocalization') ?? new NullLocalization();
<?= $this->getHtml('Log'); ?>
</label>
<tr><td><label for="iLogPath"><?= $this->getHtml('LogPath'); ?></label>
<tr><td><input id="iLogPath" name="settings_1000000007" type="text" value="<?= $this->printHtml($settings['1000000007']['content']); ?>" placeholder="&#xf023; /Logs">
<tr><td><input id="iLogPath" name="settings_1000000007" type="text" value="<?= $this->printHtml($generalSettings['1000000007']['content']); ?>" placeholder="&#xf023; /Logs">
</table>
</div>
<div class="portlet-foot"><input id="iSubmitGeneral" name="submitGeneral" type="submit" value="<?= $this->getHtml('Save', '0', '0'); ?>"></div>
@ -544,5 +546,98 @@ $l11n = $this->getData('defaultlocalization') ?? new NullLocalization();
</div>
</div>
</div>
<input type="radio" id="c-tab-3" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>>
<div class="tab">
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('Settings'); ?><i class="fa fa-download floatRight download btn"></i></div>
<table id="settingsList" class="default">
<thead>
<tr>
<td>
<td><?= $this->getHtml('ID', '0', '0'); ?>
<label for="settingsList-sort-1">
<input type="radio" name="settingsList-sort" id="settingsList-sort-1">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="settingsList-sort-2">
<input type="radio" name="settingsList-sort" id="settingsList-sort-2">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('Name'); ?>
<label for="settingsList-sort-3">
<input type="radio" name="settingsList-sort" id="settingsList-sort-3">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="settingsList-sort-4">
<input type="radio" name="settingsList-sort" id="settingsList-sort-4">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td class="wf-100"><?= $this->getHtml('Value'); ?>
<td><?= $this->getHtml('Module'); ?>
<label for="settingsList-sort-5">
<input type="radio" name="settingsList-sort" id="settingsList-sort-5">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="settingsList-sort-6">
<input type="radio" name="settingsList-sort" id="settingsList-sort-6">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('Group'); ?>
<label for="settingsList-sort-7">
<input type="radio" name="settingsList-sort" id="settingsList-sort-7">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="settingsList-sort-8">
<input type="radio" name="settingsList-sort" id="settingsList-sort-8">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('Account'); ?>
<label for="settingsList-sort-9">
<input type="radio" name="settingsList-sort" id="settingsList-sort-9">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="settingsList-sort-10">
<input type="radio" name="settingsList-sort" id="settingsList-sort-10">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<tbody>
<?php $count = 0;
foreach ($settings as $key => $setting) : ++$count;
?>
<tr tabindex="0">
<td><i class="fa fa-cogs"></i>
<td data-label="<?= $this->getHtml('ID', '0', '0'); ?>"><?= $setting->getId(); ?>
<td data-label="<?= $this->getHtml('Name'); ?>"><?= $this->printHtml($setting->name); ?>
<td data-label="<?= $this->getHtml('Value'); ?>"><?= $this->printHtml($setting->content); ?>
<td data-label="<?= $this->getHtml('Module'); ?>"><?= $this->printHtml($setting->module); ?>
<td data-label="<?= $this->getHtml('Group'); ?>"><?= $this->printHtml($setting->group); ?>
<td data-label="<?= $this->getHtml('Account'); ?>"><?= $this->printHtml($setting->account); ?>
<?php endforeach; ?>
<?php if ($count === 0) : ?>
<tr><td colspan="7" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
<div class="portlet-foot"></div>
</div>
</div>
</div>
</div>
</div>
</div>