Disable invalid_attempts config + Refactor for Contao 4.9
This commit is contained in:
14 files changed
+104
-277
No files matched your search
@@ -52,7 +52,6 @@ terminal42_password_validation:
|
||||
numbers: 1
|
||||
other: 1
|
||||
other_chars: "+*ç%&/()=?"
|
||||
invalid_attempts: 3
|
||||
password_history: 10
|
||||
change_days: 90
|
||||
Contao\BackendUser:
|
||||
@@ -61,7 +60,6 @@ terminal42_password_validation:
|
||||
|
||||
Parameter | Purpose
|
||||
--------- | -------
|
||||
`invalid_attempts`: | Disable the user. Requires an admin to enable the account. Create a notification with type "account_disabled" which will be sent out to the admin and/or user.
|
||||
`password_history`: | Keep track of the latest `n` passwords, and force the users not to choose one of their recent passwords.
|
||||
`change_days`: | Ask the user to change their password after certain days.
|
||||
|
||||
@@ -71,18 +69,6 @@ Parameter | Purpose
|
||||
the page root.
|
||||
2. You can now force members to change their passwords by ticking the corresponding checkbox in the member edit-mask.
|
||||
|
||||
### Notifications
|
||||
|
||||
#### Account disabled
|
||||
|
||||
The bundle triggers a notification whenever an account gets disabled (only when using `invalid_attempts` options). This allows you to inform both website admin and account holder.
|
||||
|
||||
To create such notification, you can create a notification of type "Account disabled" in the notification center. This notification is chosen automatically for both back and front end users. If you only have one notification of this type, no further action is needed.
|
||||
|
||||
However, you have the possibility to select a dedicated notification:
|
||||
- To use a dedicated notification for users and members, set the `nc_account_disabled` parameter in the above mentioned config tree. Just set the notification ID as parameter value.
|
||||
- To use a dedicated notification for members on a certain page, you can select a notification in the page root config.
|
||||
|
||||
## Add your own password validator
|
||||
|
||||
You can add your own validation rule, e.g. a dictionary check.
|
||||
|
||||
+4
-5
@@ -26,12 +26,11 @@
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"contao/core-bundle": "^4.4",
|
||||
"contao/core-bundle": "^4.9",
|
||||
"paragonie/hidden-string": "^1.0",
|
||||
"symfony/config": "^3.3 || ^4.0",
|
||||
"symfony/dependency-injection": "^3.3 || ^4.0",
|
||||
"symfony/http-kernel": "^3.3 || ^4.0",
|
||||
"terminal42/notification_center": "^1.3"
|
||||
"symfony/config": "^4.0",
|
||||
"symfony/dependency-injection": "^4.0",
|
||||
"symfony/http-kernel": "^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"contao/manager-plugin": "^2.7",
|
||||
|
||||
@@ -29,8 +29,12 @@ final class Configuration implements ConfigurationInterface
|
||||
->children()
|
||||
->integerNode('min_length')->end()
|
||||
->integerNode('max_length')->end()
|
||||
->integerNode('invalid_attempts')->end()
|
||||
->integerNode('nc_account_disabled')->end()
|
||||
->integerNode('invalid_attempts')
|
||||
->setDeprecated('The "%node%" option is not available since Contao 4.9 comes with improved brute-force-protection.')
|
||||
->end()
|
||||
->integerNode('nc_account_disabled')
|
||||
->setDeprecated('The "%node%" option is not available since Contao 4.9 comes with improved brute-force-protection.')
|
||||
->end()
|
||||
->integerNode('password_history')->end()
|
||||
->integerNode('change_days')->end()
|
||||
->scalarNode('other_chars')->end()
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Password Validation Bundle for Contao Open Source CMS.
|
||||
*
|
||||
* @copyright Copyright (c) 2020, terminal42 gmbh
|
||||
* @author terminal42 <https://terminal42.ch>
|
||||
* @license MIT
|
||||
* @link http://github.com/terminal42/contao-password-validation
|
||||
*/
|
||||
|
||||
namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
|
||||
use Contao\BackendUser;
|
||||
use Contao\CoreBundle\Framework\ContaoFramework;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\Message;
|
||||
use Contao\PageModel;
|
||||
use Contao\User;
|
||||
use NotificationCenter\Model\Notification;
|
||||
use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration;
|
||||
|
||||
final class InvalidAttemptsListener
|
||||
{
|
||||
private $configuration;
|
||||
private $framework;
|
||||
|
||||
public function __construct(ValidationConfiguration $configuration, ContaoFramework $framework)
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
$this->framework = $framework;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable account if maximum invalid attempts reached.
|
||||
*
|
||||
* @return bool Never return true as it would authenticate the user!
|
||||
*/
|
||||
public function onCheckCredentials(string $username, string $password, User $user): bool
|
||||
{
|
||||
if (null === $this->getMaximumInvalidAttempts(\get_class($user))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user instanceof BackendUser && $user->isAdmin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for <=1 because the loginCount will be decreased after this hook call.
|
||||
if ($user->loginCount <= 1) {
|
||||
// Disable the account
|
||||
$user->disable = '1';
|
||||
// Reset the login count as we do not want the default routine to lock the account.
|
||||
// No need to save as the user will be saved nonetheless.
|
||||
++$user->loginCount;
|
||||
|
||||
Message::addError($this->translate('accountDisabled'));
|
||||
|
||||
if (null !== $notification = $this->getNotification($user)) {
|
||||
$notification->send($this->getNotificationTokens($username, $user));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set loginCount to maximum allowed attempts after successful login.
|
||||
*/
|
||||
public function onPostLogin(User $user): void
|
||||
{
|
||||
if (null === $maximumAttempts = $this->getMaximumInvalidAttempts(\get_class($user))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user->loginCount = $maximumAttempts;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
private function getMaximumInvalidAttempts(string $userEntity): ?int
|
||||
{
|
||||
if (false === $this->configuration->hasConfiguration($userEntity)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$configuration = $this->configuration->getConfiguration($userEntity);
|
||||
|
||||
if ($invalidAttempts = $configuration['invalid_attempts']) {
|
||||
return $invalidAttempts;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getNotification(User $user): ?Notification
|
||||
{
|
||||
/** @var PageModel $adapter */
|
||||
$adapter = $this->framework->getAdapter(PageModel::class);
|
||||
|
||||
if (($user instanceof FrontendUser) && null !== $rootPage = $adapter->findByPk($GLOBALS['objPage']->rootId)) {
|
||||
$notification = Notification::findByPk($rootPage->nc_account_disabled);
|
||||
}
|
||||
|
||||
$configuration = $this->configuration->getConfiguration(\get_class($user));
|
||||
if (null === $notification && $notificationId = $configuration['nc_account_disabled']) {
|
||||
$notification = Notification::findByPk($notificationId);
|
||||
}
|
||||
|
||||
if (null === $notification) {
|
||||
$notification = Notification::findOneBy('type', 'account_disabled');
|
||||
}
|
||||
|
||||
return $notification;
|
||||
}
|
||||
|
||||
private function getNotificationTokens(string $username, User $user): array
|
||||
{
|
||||
$tokens = [];
|
||||
|
||||
$tokens['user_class'] = \get_class($user);
|
||||
$tokens['username'] = $username;
|
||||
|
||||
foreach ($user->getData() as $k => $v) {
|
||||
$tokens['user_'.$k] = $v;
|
||||
}
|
||||
|
||||
$tokens['admin_email'] = $GLOBALS['TL_ADMIN_EMAIL'];
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
private function translate(string $key)
|
||||
{
|
||||
return $GLOBALS['TL_LANG']['ERR']['passwordValidation'][$key];
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
|
||||
use Contao\CoreBundle\ServiceAnnotation\Callback;
|
||||
use Contao\CoreBundle\ServiceAnnotation\Hook;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\Input;
|
||||
use Contao\MemberModel;
|
||||
@@ -33,6 +35,9 @@ final class NoPwChangePageWarning
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Hook("getSystemMessages")
|
||||
*/
|
||||
public function onGetSystemMessages(): string
|
||||
{
|
||||
$needsPwChangePage = false;
|
||||
@@ -68,6 +73,9 @@ final class NoPwChangePageWarning
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @Callback(table="tl_page", target="config.onload")
|
||||
*/
|
||||
public function tlPageShowWarning(): void
|
||||
{
|
||||
if (Input::get('act')) {
|
||||
|
||||
@@ -13,12 +13,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
|
||||
use Contao\CoreBundle\ServiceAnnotation\Callback;
|
||||
use Contao\User;
|
||||
use Terminal42\PasswordValidationBundle\Model\PasswordHistory;
|
||||
use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration;
|
||||
|
||||
/**
|
||||
* This listener forces a password change for passwords being too old.
|
||||
*
|
||||
* @Callback("postLogin")
|
||||
*/
|
||||
final class PasswordChangeListener
|
||||
{
|
||||
@@ -29,7 +32,7 @@ final class PasswordChangeListener
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
public function onPostLogin(User $user): void
|
||||
public function __invoke(User $user): void
|
||||
{
|
||||
if (null === $maxDays = $this->getMaxDays($user)) {
|
||||
return;
|
||||
|
||||
@@ -14,6 +14,8 @@ declare(strict_types=1);
|
||||
namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
|
||||
use Contao\BackendUser;
|
||||
use Contao\CoreBundle\ServiceAnnotation\Callback;
|
||||
use Contao\CoreBundle\ServiceAnnotation\Hook;
|
||||
use Contao\Database\Result as DatabaseResult;
|
||||
use Contao\DataContainer;
|
||||
use Contao\FrontendUser;
|
||||
@@ -49,6 +51,8 @@ final class PasswordHistoryListener
|
||||
/**
|
||||
* This hook is triggered for frontend users exclusively (ModuleChangePassword and save_callback).
|
||||
*
|
||||
* @Hook("setNewPassword")
|
||||
*
|
||||
* @param MemberModel|DatabaseResult $member
|
||||
*/
|
||||
public function onSetNewPassword($member, string $password): void
|
||||
@@ -94,6 +98,8 @@ final class PasswordHistoryListener
|
||||
|
||||
/**
|
||||
* This listener keeps track of the backend user's passwords.
|
||||
*
|
||||
* @Callback(table="tl_user", target="fields.password.save")
|
||||
*/
|
||||
public function onBackendSaveCallback(string $password, DataContainer $dc): string
|
||||
{
|
||||
@@ -126,10 +132,6 @@ final class PasswordHistoryListener
|
||||
|
||||
private function hashPassword(string $password): string
|
||||
{
|
||||
if (version_compare(VERSION, '4.8', '>=')) {
|
||||
return $this->encoderFactory->getEncoder(User::class)->encodePassword($password, null);
|
||||
}
|
||||
|
||||
return password_hash($password, PASSWORD_DEFAULT);
|
||||
return $this->encoderFactory->getEncoder(User::class)->encodePassword($password, null);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ declare(strict_types=1);
|
||||
namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
|
||||
use Contao\BackendUser;
|
||||
use Contao\CoreBundle\ServiceAnnotation\Hook;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\Widget;
|
||||
use ParagonIE\HiddenString\HiddenString;
|
||||
@@ -24,6 +25,8 @@ use Terminal42\PasswordValidationBundle\Validation\ValidatorManager;
|
||||
|
||||
/**
|
||||
* This listener validates the password input by providing a regexp.
|
||||
*
|
||||
* @Hook("addCustomRegexp")
|
||||
*/
|
||||
final class PasswordRegexpListener
|
||||
{
|
||||
@@ -37,7 +40,7 @@ final class PasswordRegexpListener
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
public function onAddCustomRegexp(string $rgxp, $input, Widget $widget): bool
|
||||
public function __invoke(string $rgxp, $input, Widget $widget): bool
|
||||
{
|
||||
if ('terminal42_password_validation' !== $rgxp) {
|
||||
return false;
|
||||
|
||||
+20
-15
@@ -16,13 +16,14 @@ namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
use Contao\CoreBundle\Exception\PageNotFoundException;
|
||||
use Contao\CoreBundle\Exception\RedirectResponseException;
|
||||
use Contao\CoreBundle\Framework\ContaoFramework;
|
||||
use Contao\CoreBundle\Routing\ScopeMatcher;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\MemberModel;
|
||||
use Contao\PageModel;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
|
||||
final class PasswordChangeFrontendListener
|
||||
final class RedirectToPasswordChangePageListener
|
||||
{
|
||||
private $framework;
|
||||
|
||||
@@ -30,24 +31,38 @@ final class PasswordChangeFrontendListener
|
||||
|
||||
private $authenticationTrustResolver;
|
||||
|
||||
private $scopeMatcher;
|
||||
|
||||
public function __construct(
|
||||
ContaoFramework $framework,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
AuthenticationTrustResolverInterface $authenticationTrustResolver
|
||||
AuthenticationTrustResolverInterface $authenticationTrustResolver,
|
||||
ScopeMatcher $scopeMatcher
|
||||
) {
|
||||
$this->framework = $framework;
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
$this->authenticationTrustResolver = $authenticationTrustResolver;
|
||||
$this->scopeMatcher = $scopeMatcher;
|
||||
}
|
||||
|
||||
public function onGetPageLayout(PageModel $page): void
|
||||
public function __invoke(RequestEvent $event): void
|
||||
{
|
||||
if (!$this->scopeMatcher->isFrontendMasterRequest($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$token = $this->tokenStorage->getToken();
|
||||
if (null === $token || $this->authenticationTrustResolver->isAnonymous($token)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->framework->initialize();
|
||||
$request = $event->getRequest();
|
||||
$page = $request->attributes->get('pageModel');
|
||||
|
||||
// Check if actual page is available
|
||||
if (!$page instanceof PageModel) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $token->getUser();
|
||||
if (!$user instanceof FrontendUser) {
|
||||
@@ -77,14 +92,4 @@ final class PasswordChangeFrontendListener
|
||||
// Redirect to password-change page
|
||||
throw new RedirectResponseException($pwChangePage->getAbsoluteUrl());
|
||||
}
|
||||
|
||||
public function onSetNewPassword($member): void
|
||||
{
|
||||
if ($member instanceof MemberModel) {
|
||||
// We only want to reset "pwChange" if the user changed their password with the change-password module.
|
||||
// If this hook is called within the save_callback (backend mask), $member is an instance of Database\Result.
|
||||
$member->pwChange = '';
|
||||
$member->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Password Validation Bundle for Contao Open Source CMS.
|
||||
*
|
||||
* @copyright Copyright (c) 2020, terminal42 gmbh
|
||||
* @author terminal42 <https://terminal42.ch>
|
||||
* @license MIT
|
||||
* @link http://github.com/terminal42/contao-password-validation
|
||||
*/
|
||||
|
||||
namespace Terminal42\PasswordValidationBundle\EventListener;
|
||||
|
||||
use Contao\CoreBundle\Exception\PageNotFoundException;
|
||||
use Contao\CoreBundle\ServiceAnnotation\Hook;
|
||||
use Contao\FrontendUser;
|
||||
use Contao\MemberModel;
|
||||
use Contao\PageModel;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
|
||||
/**
|
||||
* @Hook("setNewPassword")
|
||||
*/
|
||||
final class SetNewPasswordListener
|
||||
{
|
||||
public function __invoke($member): void
|
||||
{
|
||||
if ($member instanceof MemberModel) {
|
||||
// We only want to reset "pwChange" if the user changed their password with the change-password module.
|
||||
// If this hook is called within the save_callback (backend mask), $member is an instance of Database\Result.
|
||||
$member->pwChange = '';
|
||||
$member->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,27 @@
|
||||
services:
|
||||
terminal42_password_validation.listener.regexp:
|
||||
class: Terminal42\PasswordValidationBundle\EventListener\PasswordRegexpListener
|
||||
public: true
|
||||
Terminal42\PasswordValidationBundle\EventListener\PasswordRegexpListener:
|
||||
arguments:
|
||||
['@terminal42_password_validation.validator_manager', '@terminal42_password_validation.validator_configuration']
|
||||
|
||||
terminal42_password_validation.listener.history_log:
|
||||
class: Terminal42\PasswordValidationBundle\EventListener\PasswordHistoryListener
|
||||
public: true
|
||||
Terminal42\PasswordValidationBundle\EventListener\PasswordHistoryListener:
|
||||
arguments:
|
||||
['@terminal42_password_validation.validator_configuration', '@security.encoder_factory', '@database_connection']
|
||||
|
||||
terminal42_password_validation.listener.invalid_attempts:
|
||||
class: Terminal42\PasswordValidationBundle\EventListener\InvalidAttemptsListener
|
||||
public: true
|
||||
arguments:
|
||||
['@terminal42_password_validation.validator_configuration', '@contao.framework']
|
||||
|
||||
terminal42_password_validation.listener.password_change:
|
||||
class: Terminal42\PasswordValidationBundle\EventListener\PasswordChangeListener
|
||||
public: true
|
||||
Terminal42\PasswordValidationBundle\EventListener\PasswordChangeListener:
|
||||
arguments:
|
||||
['@terminal42_password_validation.validator_configuration']
|
||||
|
||||
terminal42_password_validation.listener.no_password_change_page_warning:
|
||||
class: Terminal42\PasswordValidationBundle\EventListener\NoPwChangePageWarning
|
||||
public: true
|
||||
Terminal42\PasswordValidationBundle\EventListener\NoPwChangePageWarning:
|
||||
arguments:
|
||||
['@terminal42_password_validation.validator_configuration']
|
||||
|
||||
terminal42_password_validation.listener.password_change_frontend:
|
||||
class: Terminal42\PasswordValidationBundle\EventListener\PasswordChangeFrontendListener
|
||||
public: true
|
||||
Terminal42\PasswordValidationBundle\EventListener\RedirectToPasswordChangePageListener:
|
||||
arguments:
|
||||
- '@contao.framework'
|
||||
- '@security.token_storage'
|
||||
- '@security.authentication.trust_resolver'
|
||||
- '@contao.routing.scope_matcher'
|
||||
tags:
|
||||
- kernel.event_listener
|
||||
|
||||
Terminal42\PasswordValidationBundle\EventListener\SetNewPasswordListener: ~
|
||||
@@ -13,60 +13,4 @@ declare(strict_types=1);
|
||||
|
||||
use Terminal42\PasswordValidationBundle\Model\PasswordHistory;
|
||||
|
||||
$GLOBALS['TL_HOOKS']['addCustomRegexp'][] =
|
||||
['terminal42_password_validation.listener.regexp', 'onAddCustomRegexp'];
|
||||
$GLOBALS['TL_HOOKS']['setNewPassword'][] =
|
||||
['terminal42_password_validation.listener.history_log', 'onSetNewPassword'];
|
||||
$GLOBALS['TL_HOOKS']['getPageLayout'][] =
|
||||
['terminal42_password_validation.listener.password_change_frontend', 'onGetPageLayout'];
|
||||
$GLOBALS['TL_HOOKS']['setNewPassword'][] =
|
||||
['terminal42_password_validation.listener.password_change_frontend', 'onSetNewPassword'];
|
||||
$GLOBALS['TL_HOOKS']['checkCredentials'][] =
|
||||
['terminal42_password_validation.listener.invalid_attempts', 'onCheckCredentials'];
|
||||
$GLOBALS['TL_HOOKS']['postLogin'][] =
|
||||
['terminal42_password_validation.listener.invalid_attempts', 'onPostLogin'];
|
||||
$GLOBALS['TL_HOOKS']['postLogin'][] =
|
||||
['terminal42_password_validation.listener.password_change', 'onPostLogin'];
|
||||
$GLOBALS['TL_HOOKS']['getSystemMessages'][] =
|
||||
['terminal42_password_validation.listener.no_password_change_page_warning', 'onGetSystemMessages'];
|
||||
|
||||
$GLOBALS['TL_MODELS']['tl_password_history'] = PasswordHistory::class;
|
||||
|
||||
$GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE'] = array_merge(
|
||||
(array) $GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE'],
|
||||
[
|
||||
'password_validation' => [
|
||||
'account_disabled' => [
|
||||
'recipients' => [
|
||||
'admin_email',
|
||||
'user_email',
|
||||
],
|
||||
'email_text' => [
|
||||
'username',
|
||||
'user_class',
|
||||
'user_*',
|
||||
],
|
||||
'email_html' => [
|
||||
'username',
|
||||
'user_class',
|
||||
'user_*',
|
||||
],
|
||||
'email_sender_name' => [
|
||||
'admin_email',
|
||||
],
|
||||
'email_sender_address' => [
|
||||
'admin_email',
|
||||
],
|
||||
'email_recipient_cc' => [
|
||||
'admin_email',
|
||||
],
|
||||
'email_recipient_bcc' => [
|
||||
'admin_email',
|
||||
],
|
||||
'email_replyTo' => [
|
||||
'admin_email',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
@@ -12,12 +12,11 @@ declare(strict_types=1);
|
||||
*/
|
||||
|
||||
use Contao\CoreBundle\DataContainer\PaletteManipulator;
|
||||
use Contao\CoreBundle\Exception\PaletteNotFoundException;
|
||||
use Contao\CoreBundle\DataContainer\PaletteNotFoundException;
|
||||
|
||||
$paletteManipulator = PaletteManipulator::create()
|
||||
->addLegend('pwChangeLegend', 'publish_legend', PaletteManipulator::POSITION_BEFORE)
|
||||
->addField('pwChangePage', 'pwChangeLegend', PaletteManipulator::POSITION_APPEND)
|
||||
->addField('nc_account_disabled', 'pwChangeLegend', PaletteManipulator::POSITION_APPEND)
|
||||
;
|
||||
|
||||
try {
|
||||
@@ -38,18 +37,3 @@ $GLOBALS['TL_DCA']['tl_page']['fields']['pwChangePage'] = [
|
||||
'sql' => "int(10) unsigned NOT NULL default '0'",
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'eager'],
|
||||
];
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_page']['fields']['nc_account_disabled'] = [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_page']['nc_account_disabled'],
|
||||
'exclude' => true,
|
||||
'inputType' => 'select',
|
||||
'options_callback' => static function () {
|
||||
return \Contao\System::getContainer()
|
||||
->get('database_connection')
|
||||
->executeQuery('SELECT id,title FROM tl_nc_notification WHERE type=\'account_disabled\' ORDER BY title')
|
||||
->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
},
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => "int(10) unsigned NOT NULL default '0'",
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy', 'table' => 'tl_nc_notification'],
|
||||
];
|
||||
@@ -12,5 +12,3 @@ declare(strict_types=1);
|
||||
*/
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_user']['fields']['password']['eval']['rgxp'] = 'terminal42_password_validation';
|
||||
$GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'][] =
|
||||
['terminal42_password_validation.listener.history_log', 'onBackendSaveCallback'];
|
||||
Reference in new issue
Block a user