feat(client): expose secret-free profile summary

This commit is contained in:
QiuSW
2026-08-05 01:59:35 +08:00
parent 404d0d3ca4
commit 20112dbd61
3 changed files with 53 additions and 1 deletions
@@ -51,6 +51,18 @@ class LoadedProfile:
return f"LoadedProfile(settings={self.settings!r}, credentials=[已隐藏])"
@dataclass(frozen=True)
class ProfileSummary:
"""不解密、不返回任何 token 数据的配置页只读摘要。"""
settings: ProfileSettings
has_stored_device_token: bool
def __post_init__(self) -> None:
if type(self.has_stored_device_token) is not bool:
raise ValueError("invalid_token_presence")
@dataclass(frozen=True)
class PollingSession:
profile_id: str
+17 -1
View File
@@ -31,7 +31,7 @@ from cmbuyer_client.core.models import (
)
from cmbuyer_client.core.validation import datetime_nanoseconds, require_rfc3339_z, require_uuid4, rfc3339_z_nanoseconds
from .models import LoadedProfile, PendingEvidence, PollingSession, ProfileSettings, RecoverySnapshot
from .models import LoadedProfile, PendingEvidence, PollingSession, ProfileSettings, ProfileSummary, RecoverySnapshot
from .protection import SecretProtector
@@ -346,6 +346,22 @@ class LocalStateStore:
token = self._unprotect_token(bytes(row[2]), purpose=_device_token_purpose(profile_id, settings.device_id))
return LoadedProfile(settings, DeviceCredentials(settings.device_id, token))
def load_profile_summary(self, profile_id: str) -> ProfileSummary:
"""读取非秘密设置与 token 存在性,绝不经过 SecretProtector。"""
with self._read_transaction() as connection:
row = connection.execute(
"""SELECT service_url,device_id,adb_path,adb_serial,transport,
poll_interval_seconds,failure_threshold,http_timeout_seconds,step_timeout_seconds,
CASE WHEN length(device_token_cipher) > 0 THEN 1 ELSE 0 END
FROM profiles WHERE profile_id=?""",
(profile_id,),
).fetchone()
if row is None:
raise StateError("profile_not_found")
settings = ProfileSettings(profile_id, *row[:9])
return ProfileSummary(settings, bool(row[9]))
def start_or_resume_polling(self, profile_id: str) -> PollingSession:
now = self._utc_now()
with self._transaction() as connection: