MAX & TT: теперь в качестве страны локации используется настоящая страна пользователя, а также зафиксировал версии библиотек в зависимостях

This commit is contained in:
Alexey Polyakov
2026-04-28 18:22:16 +03:00
parent c716520ca4
commit 89f1fefa31
11 changed files with 61 additions and 28 deletions

View File

@@ -28,3 +28,4 @@ telegram_whitelist_ids = "1,2,3"
origins="http://127.0.0.1,https://web.openmax.su"
sms_gateway_url = "http://127.0.0.1:8100/sms-gateway"
firebase_credentials_path = ""
geo_db_path = ""

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@ __pycache__
*.sqlite
*.crt
*-adminsdk-*.json
*.mmdb

View File

@@ -1,11 +1,12 @@
aiogram
aiomysql
msgpack
lz4
websockets
pydantic
aiosqlite
aiohttp
python-dotenv
cryptography
firebase-admin
aiogram==3.26.0
aiomysql==0.3.2
msgpack==1.1.2
lz4==4.4.5
websockets==16.0
pydantic==2.12.5
aiosqlite==0.22.1
aiohttp==3.13.5
python-dotenv==1.2.2
cryptography==46.0.6
firebase-admin==7.4.0
geoip2==5.2.0

View File

@@ -54,3 +54,6 @@ class ServerConfig:
### Firebase
firebase_credentials_path = os.getenv("firebase_credentials_path", "")
### Путь к гео бд
geo_db_path = os.getenv("geo_db_path", "")

View File

@@ -1,5 +1,8 @@
import json
import time
import os
import geoip2.database
class Tools:
@@ -546,3 +549,15 @@ class Tools:
presence[int(contact_id)] = {"seen": int(lastseen)}
return presence
def get_geo(self, ip, db_path):
"""
Получение страны пользователя по его айпи адресу
Используется во время запуска сессии
"""
try:
with geoip2.database.Reader(db_path) as reader:
response = reader.country(ip)
return response.country.name or "Localhost Federation"
except Exception:
return "Localhost Federation"

View File

@@ -197,7 +197,7 @@ class AuthProcessors(BaseProcessor):
await self._send(writer, packet)
self.logger.debug(f"Код для {phone}: {code} (существующий={user_exists})")
async def auth(self, payload, seq, writer, deviceType, deviceName, appVersion):
async def auth(self, payload, seq, writer, deviceType, deviceName, appVersion, ip):
"""Обработчик проверки кода"""
try:
VerifyCodePayloadModel.model_validate(payload)
@@ -285,8 +285,10 @@ class AuthProcessors(BaseProcessor):
hashed_login,
deviceType,
deviceName,
"Little Saint James Island",
int(time.time()),
self.tools.get_geo(
ip=ip, db_path=self.config.geo_db_path
),
int(time.time() * 1000),
), # весь покрытый зеленью, абсолютно весь, остров невезения в океане есть
)
@@ -333,7 +335,7 @@ class AuthProcessors(BaseProcessor):
# Отправляем
await self._send(writer, packet)
async def auth_confirm(self, payload, seq, writer, deviceType, deviceName, appVersion):
async def auth_confirm(self, payload, seq, writer, deviceType, deviceName, appVersion, ip):
"""Обработчик подтверждения регистрации нового пользователя"""
# Валидируем данные пакета
try:
@@ -456,8 +458,10 @@ class AuthProcessors(BaseProcessor):
hashed_login,
deviceType or "ANDROID",
deviceName or "Unknown",
"Little Saint James Island",
now_s,
self.tools.get_geo(
ip=ip, db_path=self.config.geo_db_path
),
now_ms,
),
)

View File

@@ -114,7 +114,7 @@ class OnemeMobile:
)
else:
await self.processors.auth(
payload, seq, writer, deviceType, deviceName, appVersion
payload, seq, writer, deviceType, deviceName, appVersion, address[0]
)
case self.opcodes.AUTH_CONFIRM:
if not self.auth_rate_limiter.is_allowed(address[0]):
@@ -126,7 +126,7 @@ class OnemeMobile:
)
elif payload and payload.get("tokenType") == "REGISTER":
await self.processors.auth_confirm(
payload, seq, writer, deviceType, deviceName, appVersion
payload, seq, writer, deviceType, deviceName, appVersion, address[0]
)
else:
self.logger.warning(

View File

@@ -88,7 +88,7 @@ class OnemeWS:
)
else:
await self.processors.auth(
payload, seq, websocket, deviceType, deviceName, appVersion
payload, seq, websocket, deviceType, deviceName, appVersion, address[0]
)
case self.opcodes.AUTH_CONFIRM:
if not self.auth_rate_limiter.is_allowed(address[0]):
@@ -100,7 +100,7 @@ class OnemeWS:
)
elif payload and payload.get("tokenType") == "REGISTER":
await self.processors.auth_confirm(
payload, seq, websocket, deviceType, deviceName, appVersion
payload, seq, websocket, deviceType, deviceName, appVersion, address[0]
)
else:
self.logger.warning(

View File

@@ -158,7 +158,7 @@ class AuthProcessors(BaseProcessor):
await self._send(writer, packet)
async def auth_confirm(self, payload, seq, writer, deviceType, deviceName):
async def auth_confirm(self, payload, seq, writer, deviceType, deviceName, ip):
"""Обработчик финальной аутентификации"""
# Валидируем данные пакета
try:
@@ -212,8 +212,16 @@ class AuthProcessors(BaseProcessor):
# Создаем сессию
await cursor.execute(
"INSERT INTO tokens (phone, token_hash, device_type, device_name, location, time) VALUES (%s, %s, %s, %s, %s, %s)",
(stored_token.get("phone"), hashed_login, deviceType, deviceName,
"Epstein Island", int(time.time()))
(
stored_token.get("phone"),
hashed_login,
deviceType,
deviceName,
self.tools.get_geo(
ip=ip, db_path=self.config.geo_db_path
),
int(time.time() * 1000)
)
)
# Аватарка с биографией

View File

@@ -96,7 +96,7 @@ class TamTamMobile:
if not self.auth_rate_limiter.is_allowed(address[0]):
await self.processors._send_error(seq, self.opcodes.AUTH_CONFIRM, self.processors.error_types.RATE_LIMITED, writer)
else:
await self.processors.auth_confirm(payload, seq, writer, deviceType, deviceName)
await self.processors.auth_confirm(payload, seq, writer, deviceType, deviceName, address[0])
case self.opcodes.LOGIN:
if not self.auth_rate_limiter.is_allowed(address[0]):
await self.processors._send_error(seq, self.opcodes.LOGIN, self.processors.error_types.RATE_LIMITED, writer)

View File

@@ -82,7 +82,7 @@ class TamTamWS:
if not self.auth_rate_limiter.is_allowed(address[0]):
await self.processors._send_error(seq, self.opcodes.AUTH_CONFIRM, self.processors.error_types.RATE_LIMITED, websocket)
else:
await self.processors.auth_confirm(payload, seq, websocket, deviceType, deviceName)
await self.processors.auth_confirm(payload, seq, websocket, deviceType, deviceName, address[0])
case self.opcodes.LOGIN:
if not self.auth_rate_limiter.is_allowed(address[0]):
await self.processors._send_error(seq, self.opcodes.LOGIN, self.processors.error_types.RATE_LIMITED, websocket)