public function check_for_errors() { $user = array(); $user['errors'] = ''; $user = Container::get('hooks')->fire('model.register.check_for_errors_start', $user); // Check that someone from this IP didn't register a user within the last hour (DoS prevention) $already_registered = DB::for_table('users')->where('registration_ip', Utils::getIp())->where_gt('registered', time() - 3600); $already_registered = Container::get('hooks')->fireDB('model.register.check_for_errors_ip_query', $already_registered); $already_registered = $already_registered->find_one(); if ($already_registered) { throw new Error(__('Registration flood'), 429); } $user['username'] = Utils::trim(Input::post('req_user')); $user['email1'] = strtolower(Utils::trim(Input::post('req_email1'))); if (ForumSettings::get('o_regs_verify') == '1') { $email2 = strtolower(Utils::trim(Input::post('req_email2'))); $user['password1'] = Random::pass(12); $password2 = $user['password1']; } else { $user['password1'] = Utils::trim(Input::post('req_password1')); $password2 = Utils::trim(Input::post('req_password2')); } // Validate username and passwords $profile = new \FeatherBB\Model\Profile(); $user['errors'] = $profile->check_username($user['username'], $user['errors']); if (Utils::strlen($user['password1']) < 6) { $user['errors'][] = __('Pass too short'); } elseif ($user['password1'] != $password2) { $user['errors'][] = __('Pass not match'); } // Antispam feature $lang_antispam_questions = (require ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/antispam.php'); $question = Input::post('captcha_q') ? trim(Input::post('captcha_q')) : ''; $answer = Input::post('captcha') ? strtoupper(trim(Input::post('captcha'))) : ''; $lang_antispam_questions_array = array(); foreach ($lang_antispam_questions as $k => $v) { $lang_antispam_questions_array[md5($k)] = strtoupper($v); } if (empty($lang_antispam_questions_array[$question]) || $lang_antispam_questions_array[$question] != $answer) { $user['errors'][] = __('Robot test fail'); } // Validate email if (!Container::get('email')->is_valid_email($user['email1'])) { $user['errors'][] = __('Invalid email'); } elseif (ForumSettings::get('o_regs_verify') == '1' && $user['email1'] != $email2) { $user['errors'][] = __('Email not match'); } // Check if it's a banned email address if (Container::get('email')->is_banned_email($user['email1'])) { if (ForumSettings::get('p_allow_banned_email') == '0') { $user['errors'][] = __('Banned email'); } $user['banned_email'] = 1; // Used later when we send an alert email } // Check if someone else already has registered with that email address $dupe_list = array(); $dupe_mail = DB::for_table('users')->select('username')->where('email', $user['email1']); $dupe_mail = Container::get('hooks')->fireDB('model.register.check_for_errors_dupe', $dupe_mail); $dupe_mail = $dupe_mail->find_many(); if ($dupe_mail) { if (ForumSettings::get('p_allow_dupe_email') == '0') { $user['errors'][] = __('Dupe email'); } foreach ($dupe_mail as $cur_dupe) { $dupe_list[] = $cur_dupe['username']; } } // Make sure we got a valid language string if (Input::post('language')) { $user['language'] = preg_replace('%[\\.\\\\/]%', '', Input::post('language')); if (!file_exists(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . $user['language'] . '/common.po')) { throw new Error(__('Bad request'), 500); } } else { $user['language'] = ForumSettings::get('o_default_lang'); } $user = Container::get('hooks')->fire('model.register.check_for_errors', $user); return $user; }
public function password_forgotten() { $this->hook->fire('password_forgotten_start'); if (!$this->user->is_guest) { header('Location: ' . Url::base()); exit; } // Start with a clean slate $errors = array(); if ($this->feather->request()->isPost()) { // Validate the email address $email = strtolower(Utils::trim($this->request->post('req_email'))); if (!$this->email->is_valid_email($email)) { $errors[] = __('Invalid email'); } // Did everything go according to plan? if (empty($errors)) { $result['select'] = array('id', 'username', 'last_email_sent'); $result = DB::for_table('users')->select_many($result['select'])->where('email', $email); $result = $this->hook->fireDB('password_forgotten_query', $result); $result = $result->find_many(); if ($result) { // Load the "activate password" template $mail_tpl = trim(file_get_contents($this->feather->forum_env['FEATHER_ROOT'] . 'featherbb/lang/' . $this->user->language . '/mail_templates/activate_password.tpl')); $mail_tpl = $this->hook->fire('mail_tpl_password_forgotten', $mail_tpl); // The first row contains the subject $first_crlf = strpos($mail_tpl, "\n"); $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8)); $mail_message = trim(substr($mail_tpl, $first_crlf)); // Do the generic replacements first (they apply to all emails sent out here) $mail_message = str_replace('<base_url>', Url::base() . '/', $mail_message); $mail_message = str_replace('<board_mailer>', $this->config['o_board_title'], $mail_message); $mail_message = $this->hook->fire('mail_message_password_forgotten', $mail_message); // Loop through users we found foreach ($result as $cur_hit) { if ($cur_hit->last_email_sent != '' && time() - $cur_hit->last_email_sent < 3600 && time() - $cur_hit->last_email_sent >= 0) { throw new Error(sprintf(__('Email flood'), intval((3600 - (time() - $cur_hit->last_email_sent)) / 60)), 429); } // Generate a new password and a new password activation code $new_password = Random::pass(12); $new_password_key = Random::pass(8); $query['update'] = array('activate_string' => Random::hash($new_password), 'activate_key' => $new_password_key, 'last_email_sent' => time()); $query = DB::for_table('users')->where('id', $cur_hit->id)->find_one()->set($query['update']); $query = $this->hook->fireDB('password_forgotten_mail_query', $query); $query = $query->save(); // Do the user specific replacements to the template $cur_mail_message = str_replace('<username>', $cur_hit->username, $mail_message); $cur_mail_message = str_replace('<activation_url>', $this->feather->urlFor('profileAction', ['id' => $cur_hit->id, 'action' => 'change_pass']) . '?key=' . $new_password_key, $cur_mail_message); $cur_mail_message = str_replace('<new_password>', $new_password, $cur_mail_message); $cur_mail_message = $this->hook->fire('cur_mail_message_password_forgotten', $cur_mail_message); $this->email->feather_mail($email, $mail_subject, $cur_mail_message); } throw new Error(__('Forget mail') . ' <a href="mailto:' . Utils::escape($this->config['o_admin_email']) . '">' . Utils::escape($this->config['o_admin_email']) . '</a>.', 400); } else { $errors[] = __('No email match') . ' ' . Utils::escape($email) . '.'; } } } $errors = $this->hook->fire('password_forgotten', $errors); return $errors; }
public function change_email($id) { $id = Container::get('hooks')->fire('model.profile.change_email_start', $id); // Make sure we are allowed to change this user's email if (User::get()->id != $id) { $id = Container::get('hooks')->fire('model.profile.change_email_not_id', $id); if (!User::get()->is_admmod) { // A regular user trying to change another user's email? throw new Error(__('No permission'), 403); } elseif (User::get()->g_moderator == '1') { // A moderator trying to change a user's email? $user['select'] = array('u.group_id', 'g.g_moderator'); $user = DB::for_table('users')->table_alias('u')->select_many($user['select'])->inner_join('groups', array('g.g_id', '=', 'u.group_id'), 'g')->where('u.id', $id); $user = Container::get('hooks')->fireDB('model.profile.change_email_not_id_query', $user); $user = $user->find_one(); if (!$user) { throw new Error(__('Bad request'), 404); } if (User::get()->g_mod_edit_users == '0' || User::get()->g_mod_change_passwords == '0' || $user['group_id'] == ForumEnv::get('FEATHER_ADMIN') || $user['g_moderator'] == '1') { throw new Error(__('No permission'), 403); } } } if (Input::query('key')) { $key = Input::query('key'); $key = Container::get('hooks')->fire('model.profile.change_email_key', $key); $new_email_key = DB::for_table('users')->where('id', $id); $new_email_key = Container::get('hooks')->fireDB('model.profile.change_email_key_query', $new_email_key); $new_email_key = $new_email_key->find_one_col('activate_key'); if ($key == '' || $key != $new_email_key) { throw new Error(__('Email key bad') . ' <a href="mailto:' . Utils::escape(ForumSettings::get('o_admin_email')) . '">' . Utils::escape(ForumSettings::get('o_admin_email')) . '</a>.', 400); } else { $update_mail = DB::for_table('users')->where('id', $id)->find_one()->set_expr('email', 'activate_string')->set_expr('activate_string', 'NULL')->set_expr('activate_key', 'NULL'); $update_mail = Container::get('hooks')->fireDB('model.profile.change_email_query', $update_mail); $update_mail = $update_mail->save(); return Router::redirect(Router::pathFor('home'), __('Email updated')); } } elseif (Request::isPost()) { Container::get('hooks')->fire('model.profile.change_email_post'); if (Random::hash(Input::post('req_password')) !== User::get()->password) { throw new Error(__('Wrong pass')); } // Validate the email address $new_email = strtolower(Utils::trim(Input::post('req_new_email'))); $new_email = Container::get('hooks')->fire('model.profile.change_email_new_email', $new_email); if (!Container::get('email')->is_valid_email($new_email)) { throw new Error(__('Invalid email'), 400); } // Check if it's a banned email address if (Container::get('email')->is_banned_email($new_email)) { if (ForumSettings::get('p_allow_banned_email') == '0') { throw new Error(__('Banned email'), 403); } elseif (ForumSettings::get('o_mailing_list') != '') { // Load the "banned email change" template $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/banned_email_change.tpl')); $mail_tpl = Container::get('hooks')->fire('model.profile.change_email_mail_tpl', $mail_tpl); // The first row contains the subject $first_crlf = strpos($mail_tpl, "\n"); $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8)); $mail_subject = Container::get('hooks')->fire('model.profile.change_email_mail_subject', $mail_subject); $mail_message = trim(substr($mail_tpl, $first_crlf)); $mail_message = str_replace('<username>', User::get()->username, $mail_message); $mail_message = str_replace('<email>', $new_email, $mail_message); $mail_message = str_replace('<profile_url>', Router::pathFor('userProfile', ['id' => $id]), $mail_message); $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message); $mail_message = Container::get('hooks')->fire('model.profile.change_email_mail_message', $mail_message); Container::get('email')->feather_mail(ForumSettings::get('o_mailing_list'), $mail_subject, $mail_message); } } // Check if someone else already has registered with that email address $result['select'] = array('id', 'username'); $result = DB::for_table('users')->select_many($result['select'])->where('email', $new_email); $result = Container::get('hooks')->fireDB('model.profile.change_email_check_mail', $result); $result = $result->find_many(); if ($result) { if (ForumSettings::get('p_allow_dupe_email') == '0') { throw new Error(__('Dupe email'), 400); } elseif (ForumSettings::get('o_mailing_list') != '') { foreach ($result as $cur_dupe) { $dupe_list[] = $cur_dupe['username']; } // Load the "dupe email change" template $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/dupe_email_change.tpl')); $mail_tpl = Container::get('hooks')->fire('model.profile.change_email_mail_dupe_tpl', $mail_tpl); // The first row contains the subject $first_crlf = strpos($mail_tpl, "\n"); $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8)); $mail_subject = Container::get('hooks')->fire('model.profile.change_email_mail_dupe_subject', $mail_subject); $mail_message = trim(substr($mail_tpl, $first_crlf)); $mail_message = str_replace('<username>', User::get()->username, $mail_message); $mail_message = str_replace('<dupe_list>', implode(', ', $dupe_list), $mail_message); $mail_message = str_replace('<profile_url>', Router::pathFor('userProfile', ['id' => $id]), $mail_message); $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message); $mail_message = Container::get('hooks')->fire('model.profile.change_email_mail_dupe_message', $mail_message); Container::get('email')->feather_mail(ForumSettings::get('o_mailing_list'), $mail_subject, $mail_message); } } $new_email_key = Random::pass(8); $new_email_key = Container::get('hooks')->fire('model.profile.change_email_new_email_key', $new_email_key); // Update the user unset($user); $user['update'] = array('activate_string' => $new_email, 'activate_key' => $new_email_key); $user = DB::for_table('users')->where('id', tid)->find_one()->set($user['update']); $user = Container::get('hooks')->fireDB('model.profile.change_email_user_query', $user); $user = $user->save(); // Load the "activate email" template $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/activate_email.tpl')); $mail_tpl = Container::get('hooks')->fire('model.profile.change_email_mail_activate_tpl', $mail_tpl); // The first row contains the subject $first_crlf = strpos($mail_tpl, "\n"); $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8)); $mail_subject = Container::get('hooks')->fire('model.profile.change_email_mail_activate_subject', $mail_subject); $mail_message = trim(substr($mail_tpl, $first_crlf)); $mail_message = str_replace('<username>', User::get()->username, $mail_message); $mail_message = str_replace('<base_url>', Url::base(), $mail_message); $mail_message = str_replace('<activation_url>', Router::pathFor('profileAction', ['id' => $id, 'action' => 'change_email']) . '?key=' . $new_email_key, $mail_message); $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message); $mail_message = Container::get('hooks')->fire('model.profile.change_email_mail_activate_message', $mail_message); Container::get('email')->feather_mail($new_email, $mail_subject, $mail_message); Container::get('hooks')->fire('model.profile.change_email_sent'); throw new Error(__('Activate email sent') . ' <a href="mailto:' . Utils::escape(ForumSettings::get('o_admin_email')) . '">' . Utils::escape(ForumSettings::get('o_admin_email')) . '</a>.', true); } Container::get('hooks')->fire('model.profile.change_email'); }
public function forget() { if (!$this->feather->user->is_guest) { Url::redirect($this->feather->urlFor('home'), 'Already logged in'); } if ($this->feather->request->isPost()) { // Validate the email address $email = strtolower(Utils::trim($this->feather->request->post('req_email'))); if (!$this->feather->email->is_valid_email($email)) { throw new Error(__('Invalid email'), 400); } $user = ModelAuth::get_user_from_email($email); if ($user) { // Load the "activate password" template $mail_tpl = trim(file_get_contents($this->feather->forum_env['FEATHER_ROOT'] . 'featherbb/lang/' . $this->feather->user->language . '/mail_templates/activate_password.tpl')); $mail_tpl = $this->feather->hooks->fire('mail_tpl_password_forgotten', $mail_tpl); // The first row contains the subject $first_crlf = strpos($mail_tpl, "\n"); $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8)); $mail_message = trim(substr($mail_tpl, $first_crlf)); // Do the generic replacements first (they apply to all emails sent out here) $mail_message = str_replace('<base_url>', Url::base() . '/', $mail_message); $mail_message = str_replace('<board_mailer>', $this->feather->forum_settings['o_board_title'], $mail_message); $mail_message = $this->feather->hooks->fire('mail_message_password_forgotten', $mail_message); if ($user->last_email_sent != '' && time() - $user->last_email_sent < 3600 && time() - $user->last_email_sent >= 0) { throw new Error(sprintf(__('Email flood'), intval((3600 - (time() - $user->last_email_sent)) / 60)), 429); } // Generate a new password and a new password activation code $new_password = Random::pass(12); $new_password_key = Random::pass(8); ModelAuth::set_new_password($new_password, $new_password_key, $user->id); // Do the user specific replacements to the template $cur_mail_message = str_replace('<username>', $user->username, $mail_message); $cur_mail_message = str_replace('<activation_url>', $this->feather->urlFor('profileAction', ['action' => 'change_pass']) . '?key=' . $new_password_key, $cur_mail_message); $cur_mail_message = str_replace('<new_password>', $new_password, $cur_mail_message); $cur_mail_message = $this->feather->hooks->fire('cur_mail_message_password_forgotten', $cur_mail_message); $this->feather->email->feather_mail($email, $mail_subject, $cur_mail_message); Url::redirect($this->feather->urlFor('home'), __('Forget mail') . ' <a href="mailto:' . $this->feather->utils->escape($this->feather->forum_settings['o_admin_email']) . '">' . $this->feather->utils->escape($this->feather->forum_settings['o_admin_email']) . '</a>.', 200); } else { throw new Error(__('No email match') . ' ' . Utils::escape($email) . '.', 400); } } $this->feather->template->setPageInfo(array('active_page' => 'login', 'title' => array(Utils::escape($this->feather->forum_settings['o_board_title']), __('Request pass')), 'required_fields' => array('req_email' => __('Email')), 'focus_element' => array('request_pass', 'req_email')))->addTemplate('login/password_forgotten.php')->display(); }