🔐 Добавлена полная поддержка 2FA авторизации

 Улучшения:
   Расширенная обработка ошибок при вводе пароля 2FA
   Различие между неверным паролем и другими ошибками
   Подробные подсказки для пользователя при ошибках
   Поддержка восстановительных кодов 2FA
   Улучшенное сообщение при запросе пароля 2FA

📖 Документация:
   Создан 2FA_GUIDE.md (подробное руководство)
   Обновлена информация о 2FA в боте (auth_info)
   Добавлены примеры и советы по использованию

🔐 Обработка ошибок:
  • Неверный пароль - ясное сообщение + подсказки
  • Пароль истек - предложение повторить
  • SMS-код истек - инструкция по получению нового
  • Много попыток - информация о ограничениях

📱 Процесс с 2FA:
  1. Номер телефона
  2. SMS-код (5 цифр)
  3. Пароль 2FA (если включена)
  4.  Авторизация успешна

💡 Основные преимущества:
  • Ясные объяснения на каждом этапе
  • Подсказки при забывании пароля
  • Безопасное обращение с паролями (не сохраняются)
  • Поддержка восстановительных кодов
This commit is contained in:
2025-12-21 12:33:29 +09:00
parent b4f86a33cb
commit c849866fbd
7 changed files with 308 additions and 66 deletions

View File

@@ -87,14 +87,26 @@ async def auth_info(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
<b>Как это работает:</b>
1. Введите номер телефона вашего аккаунта Telegram
2. Получите SMS-код подтверждения
2. Получите SMS-код подтверждения (5 цифр)
3. Введите код в бот
4. При необходимости подтвердите двухфакторную аутентификацию
4. Если включена 2FA - введите пароль
5. Готово! UserBot авторизован
<b>Что такое SMS-код?</b>
Это 5-значный код, который Telegram отправляет на ваш номер.
Действителен ~5 минут. Нужно ввести быстро.
<b>Что такое 2FA пароль?</b>
Это пароль, который ВЫ установили в Telegram на случай потери телефона.
<i>НЕ SMS-код, НЕ пароль от почты!</i>
📍 Где его найти?
Telegram → Настройки → Приватность и безопасность → Двухфакторная аутентификация
<b>Безопасность:</b>
✓ Авторизация происходит локально на сервере
Ваш пароль не передается нигде
Пароли НЕ сохраняются в базе (обработаны Telethon)
✓ SMS-коды НЕ логируются
✓ Сессия сохраняется в зашифрованном виде
✓ Доступ имеет только этот бот
@@ -105,10 +117,18 @@ async def auth_info(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
✓ Работать 24/7 без вашего участия
<b>Что НЕ может делать:</b>
✗ Отправлять сообщения от вашего имени (опционально)
✗ Отправлять сообщения от вашего имени
✗ Удалять или изменять ваши сообщения
✗ Изменять настройки групп
✗ Получать доступ к приватным чатам других пользователей
<b>Справка по ошибкам:</b>
"Неверный номер" - проверьте формат (+XX...)
"Код истек" - повторите авторизацию
"Требуется пароль" - введите пароль 2FA
"Неверный пароль" - проверьте регистр и опечатки
📖 Полное руководство: смотрите 2FA_GUIDE.md
"""
keyboard = [
@@ -333,9 +353,20 @@ async def handle_code(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int
except SessionPasswordNeededError:
# Нужна двухфакторная аутентификация
await message.edit_text(
"""🔐 <b>Требуется двухфакторная аутентификация</b>
"""🔐 <b>Требуется двухфакторная аутентификация (2FA)</b>
Введите пароль вашего аккаунта Telegram:
Ваш аккаунт Telegram защищен паролем 2FA.
<b>Что вводить:</b>
Введите пароль, который ВЫ установили в Telegram
(это НЕ SMS-код и НЕ пароль от почты)
📍 Как найти:
Telegram → Настройки → Приватность и безопасность → Двухфакторная аутентификация
<i>Пароль чувствителен к регистру!</i>
Введите пароль:
""",
parse_mode='HTML'
)
@@ -375,50 +406,87 @@ async def handle_password(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
client = auth_sessions[user_id]['client']
# Проверяем пароль
await client.sign_in(password=password)
try:
# Пытаемся войти с пароль
await client.sign_in(password=password)
# Успешная авторизация
await message.edit_text(
"""✅ <b>Двухфакторная аутентификация успешна!</b>
# Успешная авторизация
await message.edit_text(
"""✅ <b>Двухфакторная аутентификация успешна!</b>
Ваш UserBot авторизован и готов к работе.
""",
parse_mode='HTML'
)
# Сохраняем правильное имя сессии
correct_session = f"app/sessions/userbot_{user_id}"
if os.path.exists(f"app/sessions/userbot_auth_{user_id}.session"):
os.rename(
f"app/sessions/userbot_auth_{user_id}.session",
f"{correct_session}.session"
Сессия сохранена на сервере. Переавторизация не требуется.
""",
parse_mode='HTML'
)
await client.disconnect()
# Очищаем временные данные
if user_id in auth_sessions:
del auth_sessions[user_id]
# Сохраняем правильное имя сессии
correct_session = f"app/sessions/userbot_{user_id}"
if os.path.exists(f"app/sessions/userbot_auth_{user_id}.session"):
os.rename(
f"app/sessions/userbot_auth_{user_id}.session",
f"{correct_session}.session"
)
keyboard = [
[InlineKeyboardButton("✅ Готово", callback_data="userbot_menu")],
]
await message.reply_text(
"Нажмите кнопку, чтобы вернуться в меню UserBot.",
reply_markup=InlineKeyboardMarkup(keyboard)
)
await client.disconnect()
# Очищаем временные данные
if user_id in auth_sessions:
del auth_sessions[user_id]
return ConversationHandler.END
keyboard = [
[InlineKeyboardButton("✅ Готово", callback_data="userbot_menu")],
]
await message.reply_text(
"Нажмите кнопку, чтобы вернуться в меню UserBot.",
reply_markup=InlineKeyboardMarkup(keyboard)
)
return ConversationHandler.END
except Exception as password_error:
error_msg = str(password_error).lower()
# Проверяем тип ошибки
if "password" in error_msg or "invalid" in error_msg:
await message.edit_text(
"""❌ <b>Неверный пароль</b>
Пароль, который вы ввели, неправильный.
💡 Подсказки:
• Убедитесь, что пароль введен без опечаток
• Пароль должен совпадать с тем, который вы установили в Telegram
• Учитывается регистр букв
• Если забыли пароль, используйте восстановительный код
Попробуйте еще раз или используйте восстановительный код:
<code>код_восстановления</code>
""",
parse_mode='HTML'
)
else:
await message.edit_text(
f"""❌ <b>Ошибка при проверке пароля</b>
{error_msg[:100]}
Пожалуйста, попробуйте еще раз или начните авторизацию заново.
""",
parse_mode='HTML'
)
return AUTH_PASSWORD
except Exception as e:
logger.error(f"Password verification error: {e}")
await message.edit_text(
f"""❌ <b>Ошибка при проверке пароля</b>
f"""❌ <b>Критическая ошибка</b>
{str(e)}
{str(e)[:150]}
Пожалуйста, попробуйте еще раз.
Пожалуйста, начните авторизацию заново.
""",
parse_mode='HTML'
)