feat(bot): доступ по QR-приглашениям, раздел «Участники», отзыв доступа
- AccessService: одноразовые приглашения (128 бит, в БД только sha256, TTL 24 ч), атомарный захват приглашения (условный UPDATE — из двух сканов одного QR проходит один), антиперебор (> 5 неудач в час — молчание), отзыв (черновик и FSM удаляются), повторное приглашение - ADMIN_IDS заводятся в БД при старте; дальше — только по приглашению - AccessMiddleware: участники из БД (+ last_seen раз в 5 мин), новичкам — только /start <токен> - «👥 Участники» для админов: список, QR (segno) + ссылка, отзыв с подтверждением - один ответ на неверный/истёкший/использованный токен — без подсказок Refs #25 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import io
|
||||
|
||||
import segno
|
||||
|
||||
|
||||
def invite_link(bot_username: str, token: str) -> str:
|
||||
return f"https://t.me/{bot_username}?start={token}"
|
||||
|
||||
|
||||
def qr_png(data: str) -> bytes:
|
||||
buf = io.BytesIO()
|
||||
segno.make(data, error="m").save(buf, kind="png", scale=10, border=2)
|
||||
return buf.getvalue()
|
||||
Reference in New Issue
Block a user