battles/classes/Battles/RememberPassword.php

75 lines
3.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Battles;
use tidy, Battles\Database\Db;
class RememberPassword
{
const OK_MAIL_SENT = 'Письмо отправлено!';
const OK_PASSWORD_CHANGED = 'Пароль изменён!';
const ERROR_MAIL_NOT_SENT = 'Письмо не отправлено!';
const ERROR_WRONG_LOGIN = 'Такого пользователя не существует!';
const ERROR_TOO_MANY_TRIES = 'Вы уже отправляли себе письмо сегодня!';
const ERROR_OLD_HASH = 'Ссылка устарела!';
const ERROR_WRONG_HASH = 'Неверная ссылка!';
private function mailSend(string $to, string $message): bool
{
$from = "=?UTF-8?B?" . base64_encode('Noreply') . "?= <noreply@" . GAMEDOMAIN . ">";
$subject = "=?UTF-8?B?" . base64_encode('Восстановление забытого пароля') . "?=";
$headers = [
'From' => $from,
'MIME-Version' => '1.0',
'Content-type' => 'text/html; charset=UTF-8',
];
if (extension_loaded('tidy')) {
$cleaner = new tidy();
$message = $cleaner->repairString($message, ['show-errors' => 0, 'show-warnings' => false], 'utf8');
}
return mail($to, $subject, $message, $headers);
}
public function sendRecoveryMail(string $to): string
{
$check = Db::getInstance()->ofetch('SELECT email FROM users WHERE login = ?', $to);
if (!empty(Db::getInstance()->fetchColumn('select email from users where login = ?', $to))) {
return self::ERROR_WRONG_LOGIN;
}
if (!empty(Db::getInstance()->ofetch('SELECT 1 FROM users_recovery WHERE login = ?', $to))) {
return self::ERROR_TOO_MANY_TRIES;
}
$hash = uniqid();
$tomorrow = date('d-M-Y', strtotime('+1 days'));
Db::getInstance()->execute('INSERT INTO users_recovery (login, hash, ip, date) VALUES (?,?,?,?)', [$to, $hash, $tomorrow, $_SERVER['REMOTE_ADDR']]);
$message = sprintf(
'Здравствуйте!<br><br>Кто-то запросил восстановление пароля к вашему персонажу %s <br><br>
Для смены пароля пройдите по <a href="//%s/rememberpassword.php?change=%s">данной ссылке</a>.<br><br>
Ссылка будет действовать до <em>%s</em>',
$to,
GAMEDOMAIN,
$hash,
$tomorrow
);
return self::mailSend($check->email, $message) ? self::OK_MAIL_SENT : self::ERROR_MAIL_NOT_SENT;
}
public function isAllowed($hash)
{
return Db::getInstance()->execute('SELECT count(*) FROM users_recovery WHERE hash = ? AND date < ?', [$hash, date('d-M-Y')])->fetchColumn() ? true : self::ERROR_OLD_HASH;
}
public function setNewPassword(string $newPassword, string $hash):string
{
$login = Db::getInstance()->execute('select login from users_recovery where hash = ?', $hash)->fetchColumn();
if (empty($login)) {
return self::ERROR_WRONG_HASH;
}
$newPassword = password_hash($newPassword, PASSWORD_DEFAULT);
Db::getInstance()->execute('UPDATE users SET pass = ? WHERE login = ?', [$newPassword, $login]);
Db::getInstance()->execute('DELETE FROM users_recovery WHERE hash = ?', $hash);
return self::OK_PASSWORD_CHANGED;
}
}