Files
xieyi-weixin-/wecom_native_evidence.py
2026-09-21 10:56:48 +08:00

63 lines
2.8 KiB
Python

"""Require a confirmed manual send journal entry before enabling an unverified build.
UI flags and exported JSON reports are never accepted as activation evidence.
"""
import hashlib
import json
from pathlib import Path
import sqlite3
from runtime_paths import application_data_dir
TEST_TEXT = '协议通道测试,请忽略'
def local_send_receipt(profile, account, *, journal_path=None):
account = str(account or '')
if not profile or not account.isascii() or not account.isdecimal() or int(account) == 0:
return None
path = Path(journal_path) if journal_path else application_data_dir() / 'protocol_sends.sqlite3'
if not path.is_file():
return None
try:
connection = sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=1)
try:
rows = connection.execute(
"SELECT request_id,fingerprint,result FROM sends WHERE status='confirmed' "
"AND request_id LIKE ? ORDER BY created DESC LIMIT 20",
(f'manual-verification:%:{profile.version}:{account}:%',)).fetchall()
finally:
connection.close()
for request, fingerprint, encoded in rows:
if len(encoded) > 16000:
continue
try:
receipt = json.loads(encoded)
if not isinstance(receipt, dict):
continue
conversation = receipt.get('conversationId', '')
if not isinstance(conversation, str) or not conversation.startswith('S:'):
continue
if not request.endswith(f':{profile.version}:{account}:{conversation}'):
continue
if any(receipt.get(key) != value for key, value in (
('status', 'confirmed'), ('nativeCallback', 'success'), ('accountId', account),
('clientVersion', profile.version), ('clientSha256', profile.sha256),
('adapterRevision', profile.adapter_revision))):
continue
if receipt.get('senderVerified') is not True or receipt.get('textVerified') is not True:
continue
if any(type(receipt.get(key)) is not int or receipt[key] <= 0 for key in ('messageId', 'serverId')):
continue
expected = hashlib.sha256(json.dumps([account, conversation, TEST_TEXT], ensure_ascii=False).encode()).hexdigest()
if fingerprint == expected:
return receipt
except (ValueError, TypeError):
continue
except (OSError, sqlite3.Error, ValueError):
return None
return None
def send_authorized(profile, account):
return bool(profile and (profile.verified or local_send_receipt(profile, account)))