Forgot > Start * @copyright Tamaranga */ class ForgotStart extends AuthForm { public function init() { parent::init(); $this->setTemplate('auth/forgot.start', 'users'); } public function data() { $data = parent::data(); if ($this->request->user()) { return Users::redirectToAccountSettings(); } $data['social'] = $this->fromSocial(); $data['emailOnly'] = $this->emailOnly(); $data['register_url'] = $this->registrationUrl('start'); return $data; } public function fromSocial() { return $this->request->get('social', TYPE_BOOL); } public function validate($data = []) { $data = $this->validateUsingRules($data, [ 'credential' => TYPE_NOTAGS, ]); if ($this->emailOnly() && ! $this->input->isEmail($data['credential'])) { $this->errors->set(_t('users', 'Incorrect email'), 'credential'); } if ($this->errors->no()) { $data = $this->validateBlocks($data); } return $data; } public function submit() { do { if ($this->request->user()) { $this->errors->reloadPage(); break; } if (! $this->security->validateReferer()) { $this->errors->reloadPage(); break; } $data = $this->validate(); if ($this->errors->any()) { break; } if ($this->emailOnly() || $this->input->isEmail($data['credential'])) { $this->recoverByEmail($data['credential']); break; } if ($this->input->isPhoneNumber($data['credential'])) { $this->recoverByPhoneNumber($data['credential']); break; } $this->errors->set(_t('users', 'Incorrect email or phone number'), 'credential'); break; } while (false); return parent::submit(); } /** * Recover access to user account by email * @param string $email * @return bool */ public function recoverByEmail(string $email) { # Get user data by email # - recover is allowed for not activated accounts $data = Users::model()->userDataByFilter(['email' => $email, 'blocked' => 0], [ 'user_id', 'name', 'activated', 'activate_expire', ]); if (empty($data) || $this->isAdministrator($data['user_id'])) { $this->errors->set(_t('users', 'This email was not found in the database'), 'credential'); return false; } /** * Генерируем "ключ восстановления", помечаем период его действия. * В случае если аккаунт неактивирован, период действия ключа восстановления пароля будет равен * периоду действия ссылки активации аккаунта, поскольку задействуется * одно и тоже поле "activate_expire" */ $code = func::generator(20); $saved = Users::model()->userSave($data['user_id'], [ 'activate_key' => $code, 'activate_expire' => (! $data['activated'] ? $data['activate_expire'] : date('Y-m-d H:i:s', strtotime('+4 hours'))), ]); if (! $saved) { $this->errors->reloadPage(); return false; } # Send notification with link to "Finish" step $this->app->sendMailTemplate([ 'link' => $this->forgotUrl(['code' => $code, 'social' => $this->fromSocial()]), 'email' => $email, 'name' => $data['name'], 'user_id' => $data['user_id'], ], 'users_forgot_start', $email); $this->respond('success_message', _t('users', 'Instructions to change the password were sent to your email.')); return true; } /** * Recover access to user account by phone number * @param string $phone * @return bool */ public function recoverByPhoneNumber(string $phone) { # Get user data by phone number # - recover is allowed for not activated accounts $data = Users::model()->userDataByFilter(['phone_number' => $phone, 'blocked' => 0], [ 'user_id', 'password_salt', ]); if (empty($data) || $this->isAdministrator($data['user_id'])) { $this->errors->set(_t('users', 'This phone number was not found in the database'), 'credential'); return false; } # Update activation code (password) $activationData = Users::getActivationInfo(); Users::model()->userSave($data['user_id'], [ 'password' => $this->security->passwordHash($activationData['key'], $data['password_salt']), ]); # Send via sms Users::sms(false)->sendPassword($phone, $activationData['key']); $this->respond('success_message', _t('users', 'An SMS with the password was sent to the [phone] number.', [ 'phone' => $phone, ])); return true; } public function isAdministrator($userId) { return Users::model()->userIsAdministrator($userId); } }