feat: add install guide share tokens and animations

This commit is contained in:
3252a8
2026-05-22 23:20:25 +03:00
parent d3925cad22
commit d9a4a007e2
14 changed files with 403 additions and 150 deletions
+75
View File
@@ -1,4 +1,6 @@
import logging
import re
import secrets
from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional
@@ -9,6 +11,8 @@ from sqlalchemy.orm import selectinload
from db.models import Subscription
INSTALL_SHARE_TOKEN_BYTES = 16
def _subscription_model_payload(sub_payload: Dict[str, Any]) -> Dict[str, Any]:
model_columns = Subscription.__mapper__.columns.keys()
@@ -42,6 +46,77 @@ async def get_subscription_by_panel_subscription_uuid(
return result.scalar_one_or_none()
def normalize_install_share_token(value: Any) -> str:
token = str(value or "").strip().lower()
if not re.fullmatch(r"[a-f0-9]{32}", token):
return ""
return token
async def get_subscription_by_install_share_token(
session: AsyncSession,
token: str,
) -> Optional[Subscription]:
normalized = normalize_install_share_token(token)
if not normalized:
return None
stmt = select(Subscription).where(Subscription.install_share_token == normalized)
result = await session.execute(stmt)
return result.scalar_one_or_none()
async def ensure_install_share_token(
session: AsyncSession,
subscription: Subscription,
) -> str:
raw_existing = str(getattr(subscription, "install_share_token", "") or "").strip()
existing = normalize_install_share_token(raw_existing)
if existing:
if existing != getattr(subscription, "install_share_token", None):
subscription.install_share_token = existing
await session.flush()
return existing
subscription_id = getattr(subscription, "subscription_id", None)
for _attempt in range(10):
token = secrets.token_hex(INSTALL_SHARE_TOKEN_BYTES)
if await get_subscription_by_install_share_token(session, token):
continue
if subscription_id:
result = await session.execute(
update(Subscription)
.where(
Subscription.subscription_id == subscription_id,
or_(
Subscription.install_share_token.is_(None),
Subscription.install_share_token == "",
Subscription.install_share_token == raw_existing,
),
)
.values(install_share_token=token)
)
await session.flush()
if result.rowcount:
await session.refresh(subscription)
return normalize_install_share_token(
getattr(subscription, "install_share_token", None)
) or token
await session.refresh(subscription)
raw_existing = str(getattr(subscription, "install_share_token", "") or "").strip()
existing = normalize_install_share_token(raw_existing)
if existing:
return existing
continue
subscription.install_share_token = token
await session.flush()
await session.refresh(subscription)
return token
raise RuntimeError("Failed to generate a unique install share token")
async def get_active_subscriptions_for_user(
session: AsyncSession, user_id: int
) -> List[Subscription]:
+25
View File
@@ -882,6 +882,26 @@ def _migration_0026_add_lifetime_traffic_synced_at(connection: Connection) -> No
)
def _migration_0027_add_subscription_install_share_token(connection: Connection) -> None:
inspector = inspect(connection)
columns: Set[str] = {col["name"] for col in inspector.get_columns("subscriptions")}
if "install_share_token" not in columns:
connection.execute(
text("ALTER TABLE subscriptions ADD COLUMN install_share_token VARCHAR(32)")
)
connection.execute(
text(
"""
CREATE UNIQUE INDEX IF NOT EXISTS uq_subscriptions_install_share_token
ON subscriptions (install_share_token)
WHERE install_share_token IS NOT NULL
"""
)
)
MIGRATIONS: List[Migration] = [
Migration(
id="0001_add_channel_subscription_fields",
@@ -1024,6 +1044,11 @@ MIGRATIONS: List[Migration] = [
description="Track when lifetime traffic usage was last synced from panel",
upgrade=_migration_0026_add_lifetime_traffic_synced_at,
),
Migration(
id="0027_add_subscription_install_share_token",
description="Add stable public share tokens for install instructions",
upgrade=_migration_0027_add_subscription_install_share_token,
),
]
+1
View File
@@ -106,6 +106,7 @@ class Subscription(Base):
user_id = Column(BigInteger, ForeignKey("users.user_id"), nullable=False, index=True)
panel_user_uuid = Column(String, nullable=False, index=True)
panel_subscription_uuid = Column(String, unique=True, index=True, nullable=True)
install_share_token = Column(String(32), unique=True, index=True, nullable=True)
start_date = Column(DateTime(timezone=True), nullable=True)
end_date = Column(DateTime(timezone=True), nullable=False, index=True)
duration_months = Column(Integer, nullable=True)