diff --git a/mirzaev/skillparts/system/controllers/AuthenticationController.php b/mirzaev/skillparts/system/controllers/AuthenticationController.php index 95c99a6..2ec840e 100644 --- a/mirzaev/skillparts/system/controllers/AuthenticationController.php +++ b/mirzaev/skillparts/system/controllers/AuthenticationController.php @@ -11,6 +11,7 @@ use yii\filters\AccessControl; use Throwable; use Exception; +use yii\bootstrap\ActiveForm; class AuthenticationController extends Controller { @@ -35,15 +36,19 @@ class AuthenticationController extends Controller public function actionIndex() { - if (yii::$app->request->isAjax) { + // Инициализация + $model = new AccountForm(yii::$app->request->post('AccountForm')); + $type = yii::$app->request->post('type') ?? yii::$app->request->get('type'); + $model->scenario = $model::SCENARIO_AUTHENTICATION; + + if (yii::$app->request->isPost) { // AJAX-POST-запрос - // Инициализация - $model = new AccountForm(yii::$app->request->post('AccountForm')); - $model->scenario = $model::SCENARIO_AUTHENTICATION; - yii::$app->response->format = Response::FORMAT_JSON; + // Валидация формы + if (!empty($errors = ActiveForm::validate($model))) return $errors; + if (!yii::$app->user->isGuest || $model->authentication()) { // Аккаунт аутентифицирован diff --git a/mirzaev/skillparts/system/controllers/PolicyController.php b/mirzaev/skillparts/system/controllers/PolicyController.php new file mode 100644 index 0000000..bfbeb47 --- /dev/null +++ b/mirzaev/skillparts/system/controllers/PolicyController.php @@ -0,0 +1,15 @@ +render('/policy/index'); + } +} diff --git a/mirzaev/skillparts/system/controllers/RegistrationController.php b/mirzaev/skillparts/system/controllers/RegistrationController.php index a75e650..caaaa59 100644 --- a/mirzaev/skillparts/system/controllers/RegistrationController.php +++ b/mirzaev/skillparts/system/controllers/RegistrationController.php @@ -10,28 +10,15 @@ use yii\web\Controller; use yii\web\Response; use app\models\AccountForm; +use yii\bootstrap\ActiveForm; class RegistrationController extends Controller { - // public function behaviors() - // { - // return [ - // 'access' => [ - // 'class' => AccessControl::class, - // 'rules' => [ - // [ - // 'allow' => true, - // 'roles' => ['?'], - // ] - // ], - // ] - // ]; - // } - public function actionIndex() { // Инициализация $model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm')); + $type = yii::$app->request->post('type') ?? yii::$app->request->get('type'); $model->scenario = $model::SCENARIO_REGISTRATION; if (yii::$app->request->isPost) { @@ -39,7 +26,10 @@ class RegistrationController extends Controller yii::$app->response->format = Response::FORMAT_JSON; - if (!yii::$app->user->isGuest || $model->registration()) { + // Валидация формы + if (!empty($errors = ActiveForm::validate($model))) return $errors; + + if ($type === 'registration' && (!yii::$app->user->isGuest || $model->registration())) { // Данные прошли проверку и аккаунт был создан // Аутентификация @@ -88,7 +78,7 @@ class RegistrationController extends Controller yii::$app->response->statusCode = 400; return [ - 'main' => $this->renderPartial('/account/index', compact('model')), + 'main' => $this->renderPartial('/account/index', compact('model') + ['registration' => true]), 'redirect' => '/registration', '_csrf' => yii::$app->request->getCsrfToken() ]; @@ -98,7 +88,7 @@ class RegistrationController extends Controller if (!yii::$app->user->isGuest) { yii::$app->response->redirect('/'); } else { - return $this->render('/account/index', compact('model')); + return $this->render('/account/index', compact('model') + ['registration' => true]); } } } diff --git a/mirzaev/skillparts/system/models/AccountForm.php b/mirzaev/skillparts/system/models/AccountForm.php index b99fef4..634ac4a 100644 --- a/mirzaev/skillparts/system/models/AccountForm.php +++ b/mirzaev/skillparts/system/models/AccountForm.php @@ -24,6 +24,8 @@ class AccountForm extends Model public $mail; public $pswd; public $auto = false; + public $rept; + public $pols; private $account = false; @@ -32,14 +34,63 @@ class AccountForm extends Model { return [ // Обязательные поля - [['mail', 'pswd'], 'required', 'message' => 'Заполните поле'], + [ + [ + 'mail', + 'pswd' + ], + 'required', + 'message' => 'Заполните поле' + ], + // Обязательные поля для регистрации + [ + [ + 'rept', + 'pols' + ], + 'required', + 'message' => 'Заполните поле', + 'on' => self::SCENARIO_REGISTRATION + ], + // Повтор пароля + [ + 'rept', + 'compare', + 'compareAttribute' => 'pswd', + 'message' => "Пароли не совпадают", + 'on' => self::SCENARIO_REGISTRATION, + ], + // Принятие политики конфидециальности + [ + 'pols', + 'compare', + 'compareValue' => 'on', + 'message' => "Чтобы продолжить примите нашу политику конфидециальности", + 'on' => self::SCENARIO_REGISTRATION, + ], // Функция "Запомнить меня" - ['auto', 'boolean', 'on' => self::SCENARIO_AUTHENTICATION], + [ + 'auto', + 'boolean', + 'on' => self::SCENARIO_AUTHENTICATION + ], // Проверка почты, - ['mail', 'email', 'message' => 'Проверьте почту'], - ['mail', 'validateMail', 'on' => self::SCENARIO_REGISTRATION], + [ + 'mail', + 'email', + 'message' => 'Проверьте почту' + ], + [ + 'mail', + 'validateMail', + 'on' => self::SCENARIO_REGISTRATION + ], // Проверка пароля - ['pswd', 'validatePassword', 'on' => self::SCENARIO_AUTHENTICATION] + [ + 'pswd', + 'validatePassword', + 'on' => self::SCENARIO_AUTHENTICATION + ] ]; } @@ -48,7 +99,8 @@ class AccountForm extends Model return [ 'mail' => 'Почта', 'pswd' => 'Пароль', - 'auto' => '' + 'auto' => '', + 'pols' => 'Политика конфедециальности' ]; } @@ -59,6 +111,12 @@ class AccountForm extends Model $account = $this->getAccount(); + if (is_null($account)) { + // Не удалось проверить аккаунт + + return; + } + if (!$account || $account->validateMail($this->mail)) { // Проверка не пройдена @@ -74,6 +132,12 @@ class AccountForm extends Model $account = $this->getAccount(); + if (is_null($account)) { + // Не удалось проверить аккаунт + + return; + } + if (!$account || !$account->validatePassword($this->pswd)) { // Проверка не пройдена @@ -111,7 +175,7 @@ class AccountForm extends Model // Инициализация нового аккаунта $this->account = new Account(); - if (isset($this->mail, $this->pswd) && $this->validate()) { + if ($this->validate()) { // Проверка пройдена // Запись параметров diff --git a/mirzaev/skillparts/system/views/account/index.php b/mirzaev/skillparts/system/views/account/index.php index 2d180df..d81ecf7 100644 --- a/mirzaev/skillparts/system/views/account/index.php +++ b/mirzaev/skillparts/system/views/account/index.php @@ -16,34 +16,68 @@ use app\models\AccountForm;
'form_account', + 'id' => $form_id, 'action' => false, 'fieldConfig' => [ 'template' => '{label}{input}{error}', - 'options' => ['class' => ''] + 'options' => [ + 'class' => '' + ] ], 'options' => [ - 'class' => '', + 'class' => 'form_account', 'onsubmit' => 'return false;' - ] + ], + 'enableClientValidation' => false, + 'enableAjaxValidation' => true ]); $model = $model ?? new AccountForm; ?> - field($model, 'mail', ['enableLabel' => false, 'options' => ['class' => 'mb-2']])->textInput(['autofocus' => true, 'placeholder' => $model->getAttributeLabel('mail')]) ?> - field($model, 'pswd', ['enableLabel' => false])->passwordInput(['placeholder' => $model->getAttributeLabel('pswd')]) ?> + + +
Регистрация
+ +

Регистрация

+ + + +
Аутентификация
+ +

Аутентификация

+ + -
+ field($model, 'mail', ['enableLabel' => false, 'options' => ['class' => 'mb-2'], 'errorOptions' => ['class' => 'help-block help-block-error small']])->textInput(['autofocus' => true, 'placeholder' => $model->getAttributeLabel('mail')]) ?> + field($model, 'pswd', ['enableLabel' => false, 'errorOptions' => ['class' => 'help-block help-block-error small']])->passwordInput(['placeholder' => $model->getAttributeLabel('pswd')]) ?> + +
'submitAuthentication', 'onclick' => 'authentication(this.parentElement.parentElement);', 'class' => 'flex-grow-1 mr-2 btn btn-primary button_clean']) ?> field($model, 'auto', ['checkboxTemplate' => '
{beginLabel}' . Html::submitButton('{labelTitle}', ['name' => 'submit', 'data-toggle' => 'button', 'class' => 'w-100 btn btn-primary button_clean', 'aria-pressed' => 'false']) . '{endLabel}
'])->checkbox()->label($model->getAttributeLabel('auto'), ['class' => 'w-100 m-0']) ?>
- 'submitRegistration', 'onclick' => 'registration(this.parentElement);', 'class' => 'col-12 ml-auto btn btn-success btn-sm button_clean']) ?> + + 'submitRegistration', 'onclick' => 'return registration_start(this.parentElement);', 'class' => 'col-12 ml-auto btn btn-success btn-sm button_clean']) ?>
-
\ No newline at end of file + + + + + diff --git a/mirzaev/skillparts/system/views/account/panel/authenticated.php b/mirzaev/skillparts/system/views/account/panel/authenticated.php index dd42b96..0e5f0ae 100644 --- a/mirzaev/skillparts/system/views/account/panel/authenticated.php +++ b/mirzaev/skillparts/system/views/account/panel/authenticated.php @@ -4,19 +4,8 @@ declare(strict_types=1); use yii; -if (!yii::$app->user->isGuest) { - // $popup = yii::$app->controller->renderPartial('/notification/panel'); - - // echo << - // - // - // - // HTML; -} ?> + @@ -27,4 +16,4 @@ if (!yii::$app->user->isGuest) { - \ No newline at end of file + diff --git a/mirzaev/skillparts/system/views/account/panel/deauthenticated.php b/mirzaev/skillparts/system/views/account/panel/deauthenticated.php index 6f777c7..66dc7a1 100644 --- a/mirzaev/skillparts/system/views/account/panel/deauthenticated.php +++ b/mirzaev/skillparts/system/views/account/panel/deauthenticated.php @@ -5,14 +5,14 @@ declare(strict_types=1); use yii; ?> +
Личный кабинет -
\ No newline at end of file + diff --git a/mirzaev/skillparts/system/views/index.php b/mirzaev/skillparts/system/views/index.php index a822535..c895610 100644 --- a/mirzaev/skillparts/system/views/index.php +++ b/mirzaev/skillparts/system/views/index.php @@ -2,8 +2,9 @@ declare(strict_types=1); -$this->title = 'SkillParts'; +use yii; +$this->title = 'SkillParts'; ?> @@ -84,4 +85,4 @@ $this->title = 'SkillParts'; - \ No newline at end of file + diff --git a/mirzaev/skillparts/system/views/policy/index.php b/mirzaev/skillparts/system/views/policy/index.php new file mode 100644 index 0000000..f77aad1 --- /dev/null +++ b/mirzaev/skillparts/system/views/policy/index.php @@ -0,0 +1,53 @@ + + +
+
+
+
+

Политика конфидециальности

+ + В данной Политике обработки персональных данных (далее – Политика) мы информируем Вас о порядке обработки Ваших персональных данных при использовании нашего веб-сайта https://skillparts.ru/ (далее - «Сайт») в целях исполнения заключенных договоров. +

+ Мы обязуемся обеспечить конфиденциальность полученных от Вас с Вашего логина персональных данных физических лиц для целей, указанных в Политике, а также безопасность при их обработке в соответствии с требованиями Законодательства Российской Федерации. +

+ При регистрации на Сайте и использовании Сайта Вы предоставляете нам персональные данные, не являющиеся специальными или биометрическими, бессрочно (вплоть до отзыва Вами либо физическим лицом – субъектом персональных данных своего согласия на обработку персональных данных): имя, номер телефона, адрес электронной почты, а также иную информацию, относящуюся к Вам, физическому лицу – субъекту персональных данных прямо или косвенно. +

+ Настоящим Вы соглашаетесь с проведением нами онлайн-скоринга (оценки) таких Ваших персональных данных, как Ваше поведение на нашем Сайте, cookie, сведения о геопозиции, IP-адрес. +

+ Настоящим Вы подтверждаете, что действуете свободно, своей волей и в своем интересе, а также подтверждаете свою дееспособность. +

+ Настоящим Вы подтверждаете и несете ответственность за то, что физические лица – субъекты персональных данных, полученных нами от Вас с Вашего логина, ознакомлены с настоящей Политикой и при передаче нам своих персональных данных действовали свободно, своей волей и в своем интересе, а также были дееспособны. +

+ Предоставляя персональные данные, Вы соглашаетесь с тем, что предоставленные Вами персональные данные будут обрабатываться нами, а именно: ООО «СТАНДАРТМАШИНЕРИ», адрес (место нахождения): 680014, Хабаровский край, г. Хабаровск, ул. Промышленная 3, офис 105, ИНН 2724241607, ОГРН 1202700014626, как с использованием средств автоматизации, так и без использования таких средств. +

+ В ходе обработки с Вашими персональными данными в целях исполнения заключенных договоров могут быть совершены следующие действия: сбор, запись, систематизация, накопление, хранение, уточнение (обновление, изменение), извлечение, использование, передача (распространение, предоставление, доступ), обезличивание, блокирование, удаление, уничтожение персональных данных. +

+ Не считается нарушением обязательств передача информации в соответствии с обоснованными и применимыми требованиями законодательства Российской Федерации. +

+ Мы используем предоставленные Вами персональные данные в целях: - исполнения заключенных с Вами договоров; - отправки Вам маркетинговых, рекламных и новостных рассылок, включая, но не ограничиваясь, новости о нас и наших партнерах; информацию о ценах на товары, наши предложения и предложения наших партнеров; - отправки Вам сообщений информационного характера и сервисных сообщений; - для осуществления деятельности по поставке и продвижению товаров и услуг; - оценки и анализа работы Сайта; - информирования Вас об акциях, скидках и специальных предложениях посредством электронных рассылок. +

+ Настоящим Вы подтверждаете, что сообщили нам собственные (либо полученные и передаваемые нам законным путем в соответствии с ФЗ РФ «О персональных данных») и достоверные персональные данные. +

+ Данное Вами согласие действительно с момента сообщения нам Вами персональных (регистрационных) данных. +

+ Настоящим уведомляем Вас, что в том случае, если хотите внести уточнения в Ваши персональные данные, заблокировать или уничтожить их в случае, если персональные данные являются неполными, устаревшими, неточными, незаконно полученными или не являются необходимыми для заявленной цели обработки, либо в случае возникновения у Вас желания отозвать свое согласие на обработку персональных данных или устранить наши неправомерные действия в отношении Ваших персональных данных, то Вы должны направить нам официальный запрос одним из следующих способов: +
• по Почте России по адресу: 680014, Хабаровский край, г. Хабаровск, ул. Промышленная 3, офис 105, в качестве получателя необходимо указывать: ООО «СТАНДАРТМАШИНЕРИ»; +
• на адрес электронной почты (E-mail) Info@skillparts.ru + + В случае направления нам официального запроса в тексте запроса необходимо указать Ваши: +
• Фамилия, Имя, Отчество (если есть); +
• Номер основного документа, удостоверяющего личность субъекта персональных данных или его представителя, сведения о дате выдачи указанного документа и выдавшем его органе; +
• Сведения, подтверждающие Ваше участие в отношениях с нами либо сведения, иным способом подтверждающие факт обработки нами Ваших персональных данных; +
• Подпись гражданина (или его законного представителя). +

+ Если запрос отправляется в электронном виде, то он должен быть оформлен в виде электронного документа и подписан электронной подписью в соответствии с законодательством РФ. +
Мы обязуемся немедленно прекратить обработку Ваших персональных данных с момента получения от Вас письменного заявления (отзыва) и/или в случае достижения цели обработки и уничтожим их в срок и на условиях, установленных законом. +

+ Вы можете отписаться от маркетинговых, рекламных и новостных рассылок путём направления нам соответствующего запроса на адрес электронной почты (E-mail) Info@skillparts.ru. +
Мы не несем ответственности за сведения, предоставленные Вами на Сайте в общедоступной форме. +
При обработке персональных данных мы принимаем необходимые и достаточные организационные и технические меры для защиты персональных данных от неправомерного доступа к ним, а также от иных неправомерных действий в отношении персональных данных. +

+ Обращаем Ваше внимание, что данная Политика обработки персональных данных может обновляться в связи с возможными поправками в Законодательстве Российской Федерации, а также изменениями наших внутренних процессов и документов. Новая редакция Политики обработки персональных данных вступает в силу с момента ее размещения на Сайте. +
+
+
diff --git a/mirzaev/skillparts/system/web/css/main.css b/mirzaev/skillparts/system/web/css/main.css index 9043043..45a1b16 100644 --- a/mirzaev/skillparts/system/web/css/main.css +++ b/mirzaev/skillparts/system/web/css/main.css @@ -178,6 +178,10 @@ main { font-family: 'Gilroy'; } +.form_account .has-error > .checkbox { + color: #d90000 +} + /* @media (max-width: 400px) {} */ /* Малые девайсы («ландшафтные телефоны», >= 576px) */ @@ -194,4 +198,4 @@ main { /* Экстрабольшие девайсы (большие десктопы, >= 1200px) */ -/* @media (max-width: 1200px) {} */ \ No newline at end of file +/* @media (max-width: 1200px) {} */ diff --git a/mirzaev/skillparts/system/web/css/pages/policy.css b/mirzaev/skillparts/system/web/css/pages/policy.css new file mode 100644 index 0000000..c8a5888 --- /dev/null +++ b/mirzaev/skillparts/system/web/css/pages/policy.css @@ -0,0 +1,3 @@ +#page_policy article { + background-color: #fff; +} diff --git a/mirzaev/skillparts/system/web/js/account.js b/mirzaev/skillparts/system/web/js/account.js index 8d21e4f..54ccad3 100644 --- a/mirzaev/skillparts/system/web/js/account.js +++ b/mirzaev/skillparts/system/web/js/account.js @@ -27,9 +27,14 @@ function authentication(form) { '_csrf': yii.getCsrfToken() }; } else { - form = $(form).serialize(); + form = $(form).serializeArray(); } + form.push({ + name: 'type', + value: 'authentication' + }); + $.ajax({ url: '/authentication', type: 'post', @@ -126,15 +131,146 @@ function deauthentication() { }); }; -function registration(form) { +function registration_start(form, type) { + // Инициализация постфикса + let postfix = ''; + + if (type === 'menu') { + postfix = '-menu'; + } + + // Удаление кнопок аутентификации + form.children[4].remove(); + + // Инициализация поля ввода пароля + let password = form.children[3]; + + // Изменение стиля + password.classList.add('mb-2'); + + // Инициализация кнопки регистрации + let registration = form.children[4]; + + // Изменение размера + registration.classList.remove('btn-sm'); + registration.classList.add('btn'); + + // Изменение вызываемой функции + registration.setAttribute('onclick', 'return registration_end(this.parentElement);'); + + // Инициализация оболочки поля повтора пароля + let password_repeat_wrap = document.createElement('div'); + password_repeat_wrap.setAttribute('class', 'mb-3 field-accountform-rept required'); + + // Инициализация поля повтора пароля + let password_repeat = document.createElement('input'); + password_repeat.setAttribute('id', 'accountform-rept' + postfix); + password_repeat.classList.add('form-control'); + password_repeat.setAttribute('type', 'password'); + password_repeat.setAttribute('name', 'AccountForm[rept]'); + password_repeat.setAttribute('placeholder', 'Повтор пароля'); + password_repeat.setAttribute('aria-required', 'true'); + password_repeat.setAttribute('aria-invalid', 'true'); + + // Инициализация элемента с текстом ошибок поля повтора пароля + let password_repeat_errors = document.createElement('p'); + password_repeat_errors.setAttribute('class', 'help-block help-block-error small'); + + // Инициализация оболочки элемента с подтверждением политики персональных данных + let private_policy_wrap = document.createElement('div'); + private_policy_wrap.setAttribute('class', 'mb-3 field-accountform-pols required'); + + // Инициализация оболочки для класса checkbox для элемента с подтверждением политики персональных данных + let private_policy_checkbox = document.createElement('div'); + private_policy_checkbox.classList.add('checkbox'); + private_policy_checkbox.classList.add('text-center'); + + // Инициализация оболочки для класса label для элемента с подтверждением политики персональных данных + let private_policy_label = document.createElement('label'); + private_policy_label.setAttribute('for', 'accountform-pols'); + + // Инициализация скрытого элемента с подтверждением политики персональных данных + let private_policy_hidden = document.createElement('input'); + private_policy_hidden.setAttribute('type', 'hidden'); + private_policy_hidden.setAttribute('name', 'AccountForm[pols]'); + private_policy_hidden.setAttribute('value', '0'); + + // Инициализация элемента с подтверждением политики персональных данных + let private_policy = document.createElement('input'); + private_policy.setAttribute('id', 'accountform-pols' + postfix); + private_policy.setAttribute('type', 'checkbox'); + private_policy.setAttribute('name', 'AccountForm[pols]'); + private_policy.setAttribute('placeholder', 'Политика конфиденциальности'); + + // Инициализация оболочки элемента с текстом элемента с подтверждением политики персональных данных + let private_policy_text_wrap = document.createElement('small'); + private_policy_text_wrap.setAttribute('class', 'ml-2'); + + // Инициализация элемента с текстом элемента с подтверждением политики персональных данных + let private_policy_text = document.createElement('a'); + private_policy_text.setAttribute('href', '/policy'); + private_policy_text.innerText = 'Политика'; + + // Запись в документ + form.insertBefore(password_repeat_wrap, registration); + password_repeat_wrap.appendChild(password_repeat); + password_repeat_wrap.appendChild(password_repeat_errors); + form.insertBefore(private_policy_wrap, registration); + private_policy_wrap.appendChild(private_policy_checkbox); + private_policy_checkbox.appendChild(private_policy_label); + private_policy_label.appendChild(private_policy); + private_policy_label.appendChild(private_policy_text_wrap); + private_policy_text_wrap.appendChild(private_policy_text); + private_policy_text_wrap.appendChild(document.createTextNode(' конфидециальности')); + + // Инициализация заголовка + let title = form.children[1]; + + // Обновление заголовка + title.innerText = 'Регистрация'; + + // Подключение к ActiveForm + $(form).yiiActiveForm('add', { + id: 'accountform-rept', + name: 'rept', + container: '.field-accountform-rept', + input: '#accountform-rept', + error: '.help-block.help-block-error.small', + enableAjaxValidation: true + }); + + // Подключение к ActiveForm + $(form).yiiActiveForm('add', { + id: 'accountform-pols', + name: 'pols', + container: '.field-accountform-pols', + input: '#accountform-pols', + enableAjaxValidation: true + }); + + // Обновление валидатора + $(form).yiiActiveForm('data').settings.validationUrl = '/registration'; + + return false; +}; + +function registration_end(form) { + // Инициализация + $(form).yiiActiveForm('validate', true); + if (form == undefined) { form = { '_csrf': yii.getCsrfToken() }; } else { - form = $(form).serialize(); + form = $(form).serializeArray(); } + form.push({ + name: 'type', + value: 'registration' + }); + $.ajax({ url: '/registration', type: 'post', @@ -184,6 +320,8 @@ function registration(form) { } } }); + + return false; }; -document.addEventListener('DOMContentLoaded', identification(), true); \ No newline at end of file +document.addEventListener('DOMContentLoaded', identification(), true); diff --git a/mirzaev/skillparts/system/web/js/profile_panel.js b/mirzaev/skillparts/system/web/js/profile_panel.js index 8d4c80c..9968fe6 100644 --- a/mirzaev/skillparts/system/web/js/profile_panel.js +++ b/mirzaev/skillparts/system/web/js/profile_panel.js @@ -8,7 +8,7 @@ function page_profile_panel_notification_create(form, html = 0) { // Запись параметра типа уведомления (тест и html-код) form.push({ - name: "Notification[html]", + name: 'Notification[html]', value: html }); } @@ -48,4 +48,4 @@ function page_profile_panel_write (form) { }); return false; -} \ No newline at end of file +}