From 6dc515080422882c1521eea9a0f75a5a54d3414f Mon Sep 17 00:00:00 2001 From: Egor Date: Thu, 25 Sep 2025 11:03:49 +0300 Subject: [PATCH] Revert "Add Happ cryptoLink proxy support" --- .env.example | 2 - app/config.py | 19 ----- app/external/webhook_server.py | 32 +------- app/utils/happ_links.py | 133 -------------------------------- app/utils/subscription_utils.py | 8 +- main.py | 5 +- 6 files changed, 5 insertions(+), 194 deletions(-) delete mode 100644 app/utils/happ_links.py diff --git a/.env.example b/.env.example index e405f914..1070f38a 100644 --- a/.env.example +++ b/.env.example @@ -291,8 +291,6 @@ CONNECT_BUTTON_HAPP_DOWNLOAD_ENABLED=false HAPP_DOWNLOAD_LINK_IOS= HAPP_DOWNLOAD_LINK_ANDROID= HAPP_DOWNLOAD_LINK_PC= -HAPP_CRYPTOLINK_PROXY_BASE_URL= -HAPP_CRYPTOLINK_PROXY_PATH=/happ-link # Пропустить принятие правил использования бота SKIP_RULES_ACCEPT=false diff --git a/app/config.py b/app/config.py index 2d61952f..bace5055 100644 --- a/app/config.py +++ b/app/config.py @@ -210,8 +210,6 @@ class Settings(BaseSettings): CONNECT_BUTTON_MODE: str = "guide" MINIAPP_CUSTOM_URL: str = "" CONNECT_BUTTON_HAPP_DOWNLOAD_ENABLED: bool = False - HAPP_CRYPTOLINK_PROXY_BASE_URL: Optional[str] = None - HAPP_CRYPTOLINK_PROXY_PATH: str = "/happ-link" HAPP_DOWNLOAD_LINK_IOS: Optional[str] = None HAPP_DOWNLOAD_LINK_ANDROID: Optional[str] = None HAPP_DOWNLOAD_LINK_PC: Optional[str] = None @@ -549,26 +547,9 @@ class Settings(BaseSettings): def get_cryptobot_invoice_expires_seconds(self) -> int: return self.CRYPTOBOT_INVOICE_EXPIRES_HOURS * 3600 - def get_happ_cryptolink_proxy_base_url(self) -> Optional[str]: - base_url = (self.HAPP_CRYPTOLINK_PROXY_BASE_URL or self.WEBHOOK_URL or "").strip() - if not base_url: - return None - return base_url.rstrip('/') - - def get_happ_cryptolink_proxy_path(self) -> str: - path = (self.HAPP_CRYPTOLINK_PROXY_PATH or "").strip() - if not path: - path = "/happ-link" - if not path.startswith('/'): - path = f"/{path}" - return path - def is_happ_cryptolink_mode(self) -> bool: return self.CONNECT_BUTTON_MODE == "happ_cryptolink" - def is_happ_cryptolink_proxy_enabled(self) -> bool: - return self.is_happ_cryptolink_mode() and self.get_happ_cryptolink_proxy_base_url() is not None - def is_happ_download_button_enabled(self) -> bool: return self.is_happ_cryptolink_mode() and self.CONNECT_BUTTON_HAPP_DOWNLOAD_ENABLED diff --git a/app/external/webhook_server.py b/app/external/webhook_server.py index 7cef933d..9ea90945 100644 --- a/app/external/webhook_server.py +++ b/app/external/webhook_server.py @@ -8,11 +8,6 @@ from aiohttp import web from aiogram import Bot from app.config import settings -from app.utils.happ_links import ( - HAPP_LINK_QUERY_PARAM, - decode_happ_link, - render_happ_redirect_page, -) from app.services.tribute_service import TributeService from app.services.payment_service import PaymentService from app.database.database import get_db @@ -40,15 +35,9 @@ class WebhookServer: if settings.is_cryptobot_enabled(): self.app.router.add_post(settings.CRYPTOBOT_WEBHOOK_PATH, self._cryptobot_webhook_handler) - + self.app.router.add_get('/health', self._health_check) - - if settings.is_happ_cryptolink_proxy_enabled(): - proxy_path = settings.get_happ_cryptolink_proxy_path() - self.app.router.add_get(proxy_path, self._happ_cryptolink_handler) - self.app.router.add_head(proxy_path, self._happ_cryptolink_handler) - logger.info(f" - Happ cryptoLink proxy: GET {proxy_path}") - + self.app.router.add_options(settings.TRIBUTE_WEBHOOK_PATH, self._options_handler) if settings.is_mulenpay_enabled(): self.app.router.add_options(settings.MULENPAY_WEBHOOK_PATH, self._options_handler) @@ -61,10 +50,8 @@ class WebhookServer: logger.info(f" - Mulen Pay webhook: POST {settings.MULENPAY_WEBHOOK_PATH}") if settings.is_cryptobot_enabled(): logger.info(f" - CryptoBot webhook: POST {settings.CRYPTOBOT_WEBHOOK_PATH}") - if settings.is_happ_cryptolink_proxy_enabled(): - logger.info(f" - Happ cryptoLink proxy: GET {settings.get_happ_cryptolink_proxy_path()}") logger.info(f" - Health check: GET /health") - + return self.app async def start(self): @@ -190,19 +177,6 @@ class WebhookServer: logger.error("Отсутствует подпись Mulen Pay webhook") return False - async def _happ_cryptolink_handler(self, request: web.Request) -> web.Response: - if request.method == 'HEAD': - return web.Response(status=200) - - token = request.query.get(HAPP_LINK_QUERY_PARAM, "") - happ_link = decode_happ_link(token) - if not happ_link: - logger.warning("Получен некорректный запрос к Happ proxy: %s", request.query_string) - return web.Response(status=400, text="Invalid or missing link") - - html_page = render_happ_redirect_page(happ_link) - return web.Response(text=html_page, content_type='text/html; charset=utf-8') - async def _tribute_webhook_handler(self, request: web.Request) -> web.Response: try: diff --git a/app/utils/happ_links.py b/app/utils/happ_links.py deleted file mode 100644 index 75910368..00000000 --- a/app/utils/happ_links.py +++ /dev/null @@ -1,133 +0,0 @@ -import base64 -import html -import logging -from typing import Optional - -from app.config import settings - -logger = logging.getLogger(__name__) - -HAPP_LINK_QUERY_PARAM = "data" -_HAPP_SCHEME_PREFIX = "happ://" - - -def _encode_happ_link(link: str) -> str: - encoded = base64.urlsafe_b64encode(link.encode("utf-8")).decode("ascii") - return encoded.rstrip("=") - - -def decode_happ_link(token: str) -> Optional[str]: - if not token: - return None - - padding = "=" * (-len(token) % 4) - try: - decoded = base64.urlsafe_b64decode(f"{token}{padding}".encode("ascii")).decode("utf-8") - except (ValueError, UnicodeDecodeError): - logger.warning("Не удалось декодировать cryptoLink из токена") - return None - - if not decoded.startswith(_HAPP_SCHEME_PREFIX): - logger.warning("Попытка открыть ссылку с неподдерживаемым протоколом: %s", decoded) - return None - - return decoded - - -def build_happ_proxy_link(crypto_link: str) -> Optional[str]: - base_url = settings.get_happ_cryptolink_proxy_base_url() - if not base_url: - logger.error("Не задан базовый URL для прокси Happ cryptoLink") - return None - - path = settings.get_happ_cryptolink_proxy_path() - token = _encode_happ_link(crypto_link) - return f"{base_url}{path}?{HAPP_LINK_QUERY_PARAM}={token}" - - -def render_happ_redirect_page(happ_link: str) -> str: - escaped_link = html.escape(happ_link, quote=True) - return f""" - - - - - Открытие Happ - - - - -
-

Подключение Happ

-

Если приложение Happ не открылось автоматически, нажмите кнопку ниже или скопируйте ссылку вручную.

- Открыть в Happ -

Ссылка для копирования:
{escaped_link}

-
- - -""" diff --git a/app/utils/subscription_utils.py b/app/utils/subscription_utils.py index 8e30dcb8..62db4142 100644 --- a/app/utils/subscription_utils.py +++ b/app/utils/subscription_utils.py @@ -5,7 +5,6 @@ from sqlalchemy import select, delete, func from sqlalchemy.ext.asyncio import AsyncSession from app.database.models import Subscription, User from app.config import settings -from app.utils.happ_links import build_happ_proxy_link logger = logging.getLogger(__name__) @@ -107,11 +106,6 @@ def get_display_subscription_link(subscription: Optional[Subscription]) -> Optio if settings.is_happ_cryptolink_mode(): crypto_link = getattr(subscription, "subscription_crypto_link", None) - if crypto_link: - proxy_link = build_happ_proxy_link(crypto_link) - if proxy_link: - return proxy_link - logger.warning("Не удалось сформировать прокси-ссылку для Happ, возвращаем стандартную ссылку") - return base_link + return crypto_link or base_link return base_link diff --git a/main.py b/main.py index 99a7be23..254e5c5d 100644 --- a/main.py +++ b/main.py @@ -126,7 +126,6 @@ async def main(): settings.TRIBUTE_ENABLED or settings.is_cryptobot_enabled() or settings.is_mulenpay_enabled() - or settings.is_happ_cryptolink_proxy_enabled() ) if webhook_needed: @@ -137,9 +136,7 @@ async def main(): enabled_services.append("Mulen Pay") if settings.is_cryptobot_enabled(): enabled_services.append("CryptoBot") - if settings.is_happ_cryptolink_proxy_enabled(): - enabled_services.append("Happ cryptoLink proxy") - + logger.info(f"🌐 Запуск webhook сервера для: {', '.join(enabled_services)}...") webhook_server = WebhookServer(bot) await webhook_server.start()