diff --git a/api_browser.py b/api_browser.py index 5025907..4a76a1d 100755 --- a/api_browser.py +++ b/api_browser.py @@ -117,7 +117,11 @@ def get_cookie_jar_path(username: str) -> str: """获取截图用的 cookies 文件路径(Netscape Cookie 格式)""" import hashlib - os.makedirs(COOKIES_DIR, exist_ok=True) + os.makedirs(COOKIES_DIR, mode=0o700, exist_ok=True) + try: + os.chmod(COOKIES_DIR, 0o700) + except Exception: + pass filename = hashlib.sha256(username.encode()).hexdigest()[:32] + ".cookies.txt" return os.path.join(COOKIES_DIR, filename) @@ -260,6 +264,10 @@ class APIBrowser: with open(cookies_path, "w", encoding="utf-8") as f: f.write("\n".join(lines) + "\n") + try: + os.chmod(cookies_path, 0o600) + except Exception: + pass self.log(f"[API] Cookies已保存供截图使用") return True diff --git a/app.py b/app.py index 831b28a..be6f0a2 100644 --- a/app.py +++ b/app.py @@ -212,11 +212,12 @@ def enforce_csrf_protection(): return if request.path.startswith("/static/"): return - # 登录相关路由豁免 CSRF 检查(登录本身就是建立 session 的过程) + # 登录挑战相关路由豁免 CSRF(会话尚未建立前需要可用) csrf_exempt_paths = { "/yuyx/api/login", "/api/login", "/api/auth/login", + "/api/generate_captcha", "/yuyx/api/passkeys/login/options", "/yuyx/api/passkeys/login/verify", "/api/passkeys/login/options", @@ -224,8 +225,6 @@ def enforce_csrf_protection(): } if request.path in csrf_exempt_paths: return - if not (current_user.is_authenticated or "admin_id" in session): - return token = request.headers.get("X-CSRF-Token") or request.form.get("csrf_token") if not token or not validate_csrf_token(token): return jsonify({"error": "CSRF token missing or invalid"}), 403 diff --git a/app_config.py b/app_config.py index a842447..ebe27f3 100755 --- a/app_config.py +++ b/app_config.py @@ -33,6 +33,23 @@ except ImportError: SECRET_KEY_FILE = "data/secret_key.txt" +def _ensure_private_dir(path: str) -> None: + if not path: + return + os.makedirs(path, mode=0o700, exist_ok=True) + try: + os.chmod(path, 0o700) + except Exception: + pass + + +def _ensure_private_file(path: str) -> None: + try: + os.chmod(path, 0o600) + except Exception: + pass + + def get_secret_key(): """获取SECRET_KEY(优先环境变量)""" # 优先从环境变量读取 @@ -42,14 +59,16 @@ def get_secret_key(): # 从文件读取 if os.path.exists(SECRET_KEY_FILE): + _ensure_private_file(SECRET_KEY_FILE) with open(SECRET_KEY_FILE, "r") as f: return f.read().strip() # 生成新的 new_key = os.urandom(24).hex() - os.makedirs("data", exist_ok=True) + _ensure_private_dir("data") with open(SECRET_KEY_FILE, "w") as f: f.write(new_key) + _ensure_private_file(SECRET_KEY_FILE) print(f"[OK] 已生成新的SECRET_KEY并保存到 {SECRET_KEY_FILE}") return new_key @@ -203,7 +222,7 @@ class Config: SERVER_PORT = int(os.environ.get("SERVER_PORT", "51233")) # ==================== SocketIO配置 ==================== - SOCKETIO_CORS_ALLOWED_ORIGINS = os.environ.get("SOCKETIO_CORS_ALLOWED_ORIGINS", "*") + SOCKETIO_CORS_ALLOWED_ORIGINS = os.environ.get("SOCKETIO_CORS_ALLOWED_ORIGINS", "") # ==================== 网站基础URL配置 ==================== # 用于生成邮件中的验证链接等 diff --git a/app_security.py b/app_security.py index 7b1b5b9..f281526 100755 --- a/app_security.py +++ b/app_security.py @@ -9,6 +9,7 @@ import os import re import time import hashlib +import hmac import secrets import ipaddress import socket @@ -78,7 +79,13 @@ def sanitize_filename(filename): class IPRateLimiter: """IP访问频率限制器""" - def __init__(self, max_attempts=10, window_seconds=3600, lock_duration=3600): + def __init__( + self, + max_attempts=10, + window_seconds=3600, + lock_duration=3600, + max_tracked_ips=20000, + ): """ 初始化限流器 @@ -90,6 +97,7 @@ class IPRateLimiter: self.max_attempts = max_attempts self.window_seconds = window_seconds self.lock_duration = lock_duration + self.max_tracked_ips = max(1000, int(max_tracked_ips or 0)) # IP访问记录: {ip: [(timestamp, success), ...]} self._attempts = defaultdict(list) @@ -97,6 +105,47 @@ class IPRateLimiter: self._locked = {} self._lock = threading.Lock() + def _prune_if_oversized(self, now_ts: float) -> None: + """限制内部映射大小,避免在高频随机IP攻击下持续膨胀。""" + tracked = len(self._attempts) + len(self._locked) + if tracked <= self.max_tracked_ips: + return + + cutoff_time = now_ts - self.window_seconds + for ip in list(self._attempts.keys()): + self._attempts[ip] = [ + (ts, succ) for ts, succ in self._attempts[ip] + if ts > cutoff_time + ] + if not self._attempts[ip]: + del self._attempts[ip] + + for ip in list(self._locked.keys()): + if now_ts >= self._locked[ip]: + del self._locked[ip] + + tracked = len(self._attempts) + len(self._locked) + if tracked <= self.max_tracked_ips: + return + + # 优先按“最近访问时间最早”淘汰 attempts 中的 IP 记录。 + overflow = tracked - self.max_tracked_ips + oldest = [] + for ip, attempt_items in self._attempts.items(): + if attempt_items: + oldest.append((attempt_items[-1][0], ip)) + else: + oldest.append((0.0, ip)) + oldest.sort(key=lambda item: item[0]) + + removed = 0 + for _, ip in oldest: + self._attempts.pop(ip, None) + self._locked.pop(ip, None) + removed += 1 + if removed >= overflow: + break + def is_locked(self, ip_address): """ 检查IP是否被锁定 @@ -129,6 +178,7 @@ class IPRateLimiter: """ with self._lock: now = time.time() + self._prune_if_oversized(now) # 清理过期记录 cutoff_time = now - self.window_seconds @@ -357,7 +407,19 @@ def generate_csrf_token(): def validate_csrf_token(token): """验证CSRF令牌""" - return token == session.get('csrf_token') + expected = session.get("csrf_token") + if (token is None) or (expected is None): + return False + + provided_text = str(token or "") + expected_text = str(expected or "") + if (not provided_text) or (not expected_text): + return False + + return hmac.compare_digest( + provided_text.encode("utf-8"), + expected_text.encode("utf-8"), + ) # ==================== 内容安全 ==================== diff --git a/crypto_utils.py b/crypto_utils.py index b937aad..cb8cee6 100644 --- a/crypto_utils.py +++ b/crypto_utils.py @@ -14,6 +14,7 @@ import os import sys import base64 +import threading from pathlib import Path from cryptography.fernet import Fernet from cryptography.hazmat.primitives import hashes @@ -27,18 +28,37 @@ ENCRYPTION_KEY_FILE = os.environ.get('ENCRYPTION_KEY_FILE', 'data/encryption_key ENCRYPTION_SALT_FILE = os.environ.get('ENCRYPTION_SALT_FILE', 'data/encryption_salt.bin') +def _ensure_private_dir(path: Path) -> None: + if not path: + return + os.makedirs(path, mode=0o700, exist_ok=True) + try: + os.chmod(path, 0o700) + except Exception: + pass + + +def _ensure_private_file(path: Path) -> None: + try: + os.chmod(path, 0o600) + except Exception: + pass + + def _get_or_create_salt(): """获取或创建盐值""" salt_path = Path(ENCRYPTION_SALT_FILE) if salt_path.exists(): + _ensure_private_file(salt_path) with open(salt_path, 'rb') as f: return f.read() # 生成新的盐值 salt = os.urandom(16) - os.makedirs(salt_path.parent, exist_ok=True) + _ensure_private_dir(salt_path.parent) with open(salt_path, 'wb') as f: f.write(salt) + _ensure_private_file(salt_path) return salt @@ -102,6 +122,7 @@ def get_encryption_key(): key_path = Path(ENCRYPTION_KEY_FILE) if key_path.exists(): logger.info(f"从文件 {ENCRYPTION_KEY_FILE} 读取加密密钥") + _ensure_private_file(key_path) with open(key_path, 'rb') as f: return f.read() @@ -127,9 +148,10 @@ def get_encryption_key(): # 生成新的密钥 key = Fernet.generate_key() - os.makedirs(key_path.parent, exist_ok=True) + _ensure_private_dir(key_path.parent) with open(key_path, 'wb') as f: f.write(key) + _ensure_private_file(key_path) logger.info(f"已生成新的加密密钥并保存到 {ENCRYPTION_KEY_FILE}") logger.warning("请立即备份此密钥文件,并建议设置 ENCRYPTION_KEY_RAW 环境变量!") return key @@ -137,14 +159,17 @@ def get_encryption_key(): # 全局Fernet实例 _fernet = None +_fernet_lock = threading.Lock() def _get_fernet(): """获取Fernet加密器(懒加载)""" global _fernet if _fernet is None: - key = get_encryption_key() - _fernet = Fernet(key) + with _fernet_lock: + if _fernet is None: + key = get_encryption_key() + _fernet = Fernet(key) return _fernet @@ -187,8 +212,8 @@ def decrypt_password(encrypted_password: str) -> str: # 解密失败,可能是旧的明文密码或密钥不匹配 if is_encrypted(encrypted_password): logger.error(f"密码解密失败(密钥可能不匹配): {e}") - else: - logger.warning(f"密码解密失败,可能是未加密的旧数据: {e}") + return '' + logger.warning(f"密码解密失败,可能是未加密的旧数据: {e}") return encrypted_password diff --git a/data/cookies/7bc1fcbb0be4d43e1351618100f9025a.cookies.txt b/data/cookies/7bc1fcbb0be4d43e1351618100f9025a.cookies.txt deleted file mode 100644 index 6b9fb99..0000000 --- a/data/cookies/7bc1fcbb0be4d43e1351618100f9025a.cookies.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Netscape HTTP Cookie File -# This file was generated by zsglpt -postoa.aidunsoft.com FALSE / FALSE 0 ASP.NET_SessionId xtjioeuz4yvk4bx3xqyt0pyp -postoa.aidunsoft.com FALSE / FALSE 1800092244 UserInfo userName=13974663700&Pwd=9B8DC766B11550651353D98805B4995B diff --git a/data/encryption_key.bin b/data/encryption_key.bin deleted file mode 100644 index d36e5d0..0000000 --- a/data/encryption_key.bin +++ /dev/null @@ -1 +0,0 @@ -_S5Vpk71XaK9bm5U8jHJe-x2ASm38YWNweVlmCcIauM= \ No newline at end of file diff --git a/data/kdocs_login_state.json b/data/kdocs_login_state.json deleted file mode 100644 index 5940458..0000000 --- a/data/kdocs_login_state.json +++ /dev/null @@ -1 +0,0 @@ -{"cookies": [{"name": "rtk", "value": "TKR-frr0SNeUB_QS8ImAqRZ88rIIK7IRTro0KK-HdtleKRYhArDIuI83_yIHbCa9_86BO9I937SA6ND1STCF__uQMAf11S186mcUrxyGSrkwR86kYz1wNf1FJQr0S7Sfc_4DhCvwVq33inxQAjzYnbzBwcZ7ehHp9kmpFACUUXbKCvLj5KuIKcIKWrIIKQ.4zFZDSBph3AeBLv864R_8wNMjn1JKxrvYyHWUP2k48a-JGAp04uWZQwInOdJnQfZi4SLjyo90P0rCRjHPQYvVr", "domain": ".wps.cn", "path": "/passport/secure", "expires": 1800091730.627293, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "rtk_p", "value": "TrDIKMfbcN8k007J7q9L0pITTKI_fKoAKQKSpCidtwf8A-IuTKS-IQPahV7n_VfEh5il46KgeN7beP2fWyL3k38O-_HogsMMbyrf.AN7sKhoA2uGQDU98uneV-YKt5ScQgz4bux_-CYk2jbJ3ExJ-YXiw2yjJCGuH6ccO2P3cYRL1mWt4C6UnXgeBNK", "domain": ".account.wps.cn", "path": "/passport/secure", "expires": 1800091730.627309, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "rtk", "value": "TKr-frr0SNeUB_QS8ImAqRZ88rIIK7IRTro0KK-HdtleKRYhArDIuI83_yIHbCa9_86BO9I937SA6ND1STCF__uQMAf11S186mcUrxyGSrkwR86kYz1wNfbKDieEpwpIKcoTTKS.7Cma6ScQx6aLnOByuIE1uX54EB1MvADa4KVQ-sRCdxnYvxY5XG182E8fl3JRFxpwBBX0QsNsGWgSfalV0JLVNr", "domain": ".kdocs.cn", "path": "/passport/secure", "expires": 1800091731.075305, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "reuse_session_id", "value": "edit/290978562164", "domain": ".www.kdocs.cn", "path": "/l/cpwEOo5ynKX4", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "xsr-fe-version", "value": "20260107165518-6fa9ffc102", "domain": ".www.kdocs.cn", "path": "/l/cpwEOo5ynKX4", "expires": 1769160534, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "docset_svg_info", "value": "%7B%22active_sheet%22%3A%22%E9%81%93%E5%8E%BF%22%2C%22topleft_cell%22%3A%7B%22col%22%3A0%2C%22row%22%3A0%7D%2C%22pane_info%22%3A%7B%22activePane%22%3A1%2C%22cellLeftTop%22%3A%7B%22row%22%3A2%2C%22col%22%3A0%7D%2C%22wndPos%22%3A%7B%22left%22%3A0%2C%22top%22%3A2%7D%7D%2C%22dpi%22%3A1%2C%22w%22%3A1280%2C%22h%22%3A720%2C%22device_type%22%3A%22pc%22%2C%22active_sheet_id%22%3A2%2C%22active_sheet_type%22%3A%22xlWorksheet%22%2C%22sheet_icon_status%22%3A%7B%22sheetBgColor%22%3Atrue%2C%22showCommentIcon%22%3Atrue%2C%22showSharedSheetIcon%22%3Atrue%2C%22showProtectIcon%22%3Atrue%2C%22showMergeIcon%22%3Atrue%2C%22firstSetNotShowCommentIcon%22%3Atrue%7D%7D", "domain": ".www.kdocs.cn", "path": "/l/cpwEOo5ynKX4", "expires": 1769160533, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "xsr-cache-revision", "value": "89975", "domain": ".www.kdocs.cn", "path": "/l/cpwEOo5ynKX4", "expires": 1769160973, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "xsr-cache-fileVersion", "value": "24382", "domain": ".www.kdocs.cn", "path": "/l/cpwEOo5ynKX4", "expires": 1769160973, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "itk", "value": "TKI-frr0SNeUB_QS8ImAqRZ88rIIK7IRTro0KK-HdtleKRYhArDIuI83_yIHbCa9_86BO9I937SA6ND1STCF__uQMAf11S186mcUrxyGSrkwR86kYz1wNf1FJQr0S7Sfc_4DhCvwVq33inxQAjzYnbzBwcZ7ehHp9kmpFACUUXbKCvLj5KuIKcIKWrIIKQ.jzgjDlO8-oUi_p9xUHhY1ioMQ61aiJYgFnfh1YrtkJlDLcWOnusRs-mvxR0SNWNgdgjNL4RfBTv7t5P84LzG7w", "domain": ".account.wps.cn", "path": "/passport", "expires": 1800091730.627249, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "swi_acc_redirect_limit", "value": "0", "domain": ".kdocs.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "weboffice_device_id", "value": "310c10b7b3e04a446c1f4d0bad52feac", "domain": "www.kdocs.cn", "path": "/", "expires": 1800091732.229481, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "visitorid", "value": "1178431222", "domain": "www.kdocs.cn", "path": "/", "expires": -1, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "weboffice_cdn", "value": "21", "domain": "www.kdocs.cn", "path": "/", "expires": 1771147731.209312, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "region", "value": "hwy", "domain": "www.kdocs.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "csrf", "value": "QGpKBAxDPkkzHrCi3M75YmZKX4rQysGQ", "domain": ".kdocs.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "wps_endcloud", "value": "1", "domain": ".kdocs.cn", "path": "/", "expires": 1771147735, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "ks_local_token", "value": "T6Fwfdr5N5YpTMWDyr6PY6PC4Dy6CBaX", "domain": ".wps.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": true, "sameSite": "None"}, {"name": "kso-wx-quick-login", "value": "459", "domain": ".kdocs.cn", "path": "/", "expires": 1800091727, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "cookieCheck", "value": "1768555727430", "domain": "account.wps.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": true, "sameSite": "None"}, {"name": "wpsqing_autoLoginV1", "value": "1", "domain": ".account.wps.cn", "path": "/", "expires": 1800091727, "httpOnly": false, "secure": true, "sameSite": "None"}, {"name": "csrf", "value": "4xHAfpRRjx5YHwwmp364TWPnG6GWta8a", "domain": ".wps.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": true, "sameSite": "None"}, {"name": "wpsqing_autoLoginV1", "value": "1", "domain": ".wps.cn", "path": "/", "expires": 1800091727, "httpOnly": false, "secure": true, "sameSite": "None"}, {"name": "_ku", "value": "1", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627096, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "cid", "value": "0", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627172, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "coa_id", "value": "0", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627189, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "cv", "value": "nJlxAem3IXytSJHctjMVk4Yxbu39vKPQ14UZEV2egPGSR9eLvG7ECrpzolni_4NweQheCvw.qfgM7k-U_uB", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627212, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "exp", "value": "259200", "domain": ".wps.cn", "path": "/", "expires": 1768814930.627225, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "kso_sid", "value": "TKS-f0fbcN8k007J7q9L0poTTKI7fKoAKQKSpCidtwf8A-oOTJ-0nmZ70ebuYCppbfoyIeopTp23H0KtlmmhUS-reH0H0pstaIR1v0IJRf0ps8ReRfQeO7UIKMIpKjWnEAbgGPFnnl5GUTv1CJe1jRNdItFMDY5Jo37tu66eQNgyV3QJ-KN-K6oTTKS.XYVv4mRIK-Iu7GN5_Pj0D012NPnu4tpFsj2gAg6IBOxJke8YsllIGQC4uRxEc3ODSBkKAjX6uKGAusapalGygQ", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627267, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "nexp", "value": "129600", "domain": ".wps.cn", "path": "/", "expires": 1768685330.627281, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "uid", "value": "224886932", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627342, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "wps_sid", "value": "V02S3hwQLbppqVBEoNxwRwYWbVSDHLw00adc7047000d678094", "domain": ".wps.cn", "path": "/", "expires": 1800091730.627364, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "_ku", "value": "1", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.075083, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "cid", "value": "0", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.075182, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "coa_id", "value": "0", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.075204, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "cv", "value": "8rgSwHUukilT-rFhTqJaujyk0rB6oTqBOaZkPO3h7ulwznQKcDXun0VIaVCa_zb1RuncjVk.xU9I9U-U_uB", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.075235, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "exp", "value": "259200", "domain": ".kdocs.cn", "path": "/", "expires": 1768814931.075262, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "kso_sid", "value": "TKS-f0fbcN8k007J7q9L0poTTKI7fKoAKQKSpCidtwf8A-oOTJ-0nmZ70ebuYCppbfoyIeopTp23H0KtlmmhUS-reH0H0pstaIR1v0IJRf0ps8ReRfQeQOOjVo1I-KN_Krr0.M5nkmD55djAU-x3iWZ0UNZsKx0vFOGhOe8P8R8L4Kp0q6-jyXdY4yfBCjTuAw-iBvcfzop61-kekCrECxN3jfw", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.075276, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "nexp", "value": "129600", "domain": ".kdocs.cn", "path": "/", "expires": 1768685331.075293, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "uid", "value": "224886932", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.075335, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "wps_sid", "value": "V02S3hwQLbppqVBEoNxwRwYWbVSDHLw00adc7047000d678094", "domain": ".kdocs.cn", "path": "/", "expires": 1800091731.07536, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "wpsua", "value": "V1BTVUEvMS4wICh3ZWIta2RvY3M6Q2hyb21lXzEzNC4wLjY5OTguMzU7IHdpbmRvd3M6V2luZG93cyAxMC4wOyBmdng0NU5IN1F2MnBSVEpFcVNYYWRRPT06UTJoeWIyMWxJQ0F4TXpRdU1DNDJPVGs0TGpNMSkgQ2hyb21lLzEzNC4wLjY5OTguMzU=", "domain": ".wps.cn", "path": "/", "expires": -1, "httpOnly": false, "secure": true, "sameSite": "None"}], "origins": [{"origin": "https://www.kdocs.cn", "localStorage": [{"name": "__M_ET_MAX_WIDTH__", "value": "1280"}, {"name": "dw_store_queen_data_events_baa1d7aef2927a8d_s", "value": "[]"}, {"name": "__M_ET_MAX_HEIGHT__", "value": "720"}, {"name": "jxm-operate-filter-ids", "value": "area_protection_pc,open-wps-browser-login"}, {"name": "dw_store_dynamic_data_f37b6da8ceddc9c7_kdocs_micro_dw_ordplugin_f37b6da8ceddc9c7", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555774012,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1768550280225,\"data\":[{\"name\":\"addmember_compelete\",\"disable\":true},{\"name\":\"addmember_permission\",\"disable\":true},{\"name\":\"addmember_search\",\"disable\":true},{\"name\":\"ai_createrequest\",\"sendTimely\":true},{\"name\":\"ai_paytiance\",\"disable\":true},{\"name\":\"ai_task\",\"disable\":true},{\"name\":\"api_point\",\"sendTimely\":true},{\"name\":\"appreciation_pdftools\",\"disable\":true},{\"name\":\"avatar_old\",\"disable\":true},{\"name\":\"avatar_panel\",\"disable\":true},{\"name\":\"avator_old\",\"disable\":true},{\"name\":\"backtohome_page\",\"disable\":true},{\"name\":\"click_action\",\"disable\":true},{\"name\":\"company_interfacetips\",\"disable\":true},{\"name\":\"company_service\",\"disable\":true},{\"name\":\"company_serviceoperation\",\"disable\":true},{\"name\":\"company_spaceoperation\",\"disable\":true},{\"name\":\"content_guidance\",\"sendTimely\":true},{\"name\":\"cooperation_function_switchtips_show\",\"disable\":true},{\"name\":\"doc_finished_reading\",\"sendTimely\":true},{\"name\":\"download_fail\",\"disable\":true},{\"name\":\"download_success\",\"disable\":true},{\"name\":\"enterprise_mycloud_show\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_guide\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_package\",\"disable\":true},{\"name\":\"et_decide\",\"encryptAttrs\":[\"response_content\"]},{\"name\":\"et_func\",\"encryptAttrs\":[\"display_content\",\"input_content\"]},{\"name\":\"et_funcshow\",\"encryptAttrs\":[\"display_content\"]},{\"name\":\"et_request\",\"encryptAttrs\":[\"instruction\"]},{\"name\":\"fileapp_package\",\"encryptAttrs\":[\"introductiontext\"]},{\"name\":\"file_share_entry\",\"disable\":true},{\"name\":\"function_guidance\",\"sendTimely\":true},{\"name\":\"func_upload\",\"disable\":true},{\"name\":\"group_assignvip\",\"disable\":true},{\"name\":\"group_createfinish\",\"disable\":true},{\"name\":\"group_createguide_addfile_click\",\"disable\":true},{\"name\":\"group_createguide_addfile_click_fail\",\"disable\":true},{\"name\":\"group_createguide_addfile_later\",\"disable\":true},{\"name\":\"group_createguide_addfile_noshow\",\"disable\":true},{\"name\":\"group_createguide_addfile_show\",\"disable\":true},{\"name\":\"group_createguide_addmember_click\",\"disable\":true},{\"name\":\"group_createguide_addmember_later\",\"disable\":true},{\"name\":\"group_createguide_addmember_noshow\",\"disable\":true},{\"name\":\"group_createguide_addmember_show\",\"disable\":true},{\"name\":\"group_createguide_autocreate\",\"disable\":true},{\"name\":\"group_createpanel\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_click\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_close\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_show\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_click\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_close\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_more\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_show\",\"disable\":true},{\"name\":\"group_enter\",\"disable\":true},{\"name\":\"group_fileselect_cloud\",\"disable\":true},{\"name\":\"group_fileselect_local\",\"disable\":true},{\"name\":\"group_invitepanel\",\"disable\":true},{\"name\":\"group_linkgroup_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_show\",\"disable\":true},{\"name\":\"group_linkgroup_fileoperate\",\"disable\":true},{\"name\":\"group_linkgroup_quit\",\"disable\":true},{\"name\":\"group_linkgroup_rightlistoperate\",\"disable\":true},{\"name\":\"group_mission_click\",\"disable\":true},{\"name\":\"group_mission_finish\",\"disable\":true},{\"name\":\"group_mission_hide\",\"disable\":true},{\"name\":\"group_mission_show\",\"disable\":true},{\"name\":\"group_setup\",\"sendTimely\":true},{\"name\":\"group_vipdetail\",\"disable\":true},{\"name\":\"group_vipguide\",\"disable\":true},{\"name\":\"group_vippay\",\"disable\":true},{\"name\":\"group_vipresult\",\"disable\":true},{\"name\":\"group_vipscan\",\"disable\":true},{\"name\":\"guidance_tipcrad\",\"disable\":true},{\"name\":\"header_openwps_appcheck\",\"disable\":true},{\"name\":\"index_exportlink\",\"disable\":true},{\"name\":\"info_panelsharefileupdate\",\"disable\":true},{\"name\":\"kuc_sdk_loader\",\"disable\":true},{\"name\":\"link_preview\",\"disable\":true},{\"name\":\"mainfest_api\",\"disable\":true},{\"name\":\"massagecontacts_page\",\"disable\":true},{\"name\":\"more_panelssharefileupdate\",\"disable\":true},{\"name\":\"newbuilt_fail\",\"disable\":true},{\"name\":\"newbuilt_success\",\"disable\":true},{\"name\":\"ocr_input\",\"disable\":true},{\"name\":\"offical_bottonclick\",\"disable\":true},{\"name\":\"offical_pageview\",\"disable\":true},{\"name\":\"operation_enhometop\",\"disable\":true},{\"name\":\"operation_kdocsserver\",\"disable\":true},{\"name\":\"pag_user\",\"disable\":true},{\"name\":\"pag_view\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_show\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_show\",\"disable\":true},{\"name\":\"qingupgrade_show\",\"disable\":true},{\"name\":\"qqlogin_guide\",\"disable\":true},{\"name\":\"remindmember_number\",\"disable\":true},{\"name\":\"search_click\",\"sendTimely\":true},{\"name\":\"search_count\",\"disable\":true},{\"name\":\"search_query\",\"sendTimely\":true},{\"name\":\"search_result\",\"sendTimely\":true},{\"name\":\"search_resultaction\",\"sendTimely\":true},{\"name\":\"sharefolder_info_topupdate\",\"disable\":true},{\"name\":\"sharefolder_list_tipsupdate\",\"disable\":true},{\"name\":\"sharefolder_setting_bottomupdate\",\"disable\":true},{\"name\":\"sharefolder_sharefolderselect\",\"disable\":true},{\"name\":\"share_copylink_click\",\"disable\":true},{\"name\":\"share_copylink_toast\",\"disable\":true},{\"name\":\"share_file_cooperater_status\",\"disable\":true},{\"name\":\"share_file_settings\",\"sendTimely\":true},{\"name\":\"share_v3_settings\",\"sendTimely\":true},{\"name\":\"spacefull_pop\",\"disable\":true},{\"name\":\"storage_management_tips\",\"disable\":true},{\"name\":\"tag_hover\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tag_recommend\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tiance_click\",\"sendTimely\":true},{\"name\":\"tiance_show\",\"sendTimely\":true},{\"name\":\"transfer_link\",\"disable\":true},{\"name\":\"vip_wxxcx_iospay\",\"disable\":true},{\"name\":\"welcome_wps\",\"sendTimely\":true},{\"name\":\"wps_send_softbusstracing\",\"disable\":true}]},\"localTime\":1768555719086}"}, {"name": "dw_store_dynamic_data_c2f09479185c91bb_kdocs_plugins_idw_newsdk_c2f09479185c91bb", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1673487839000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555789928,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1765358764138},\"localTime\":1768555735012}"}, {"name": "dw_store_cache_events_c2f09479185c91bb_kdocs_plugins_idw_newsdk_c2f09479185c91bb", "value": "[]"}, {"name": "KSO_CONFIG_sharePermission", "value": "{\"et\":\"Editable\",\"wps\":\"Editable\",\"wpp\":\"Editable\",\"pdf\":\"Editable\"}"}, {"name": "dw_store_queen_data_events_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_cache_events_c2f09479185c91bb_kdocs_micro_new_file_dw_c2f09479185c91bb", "value": "[]"}, {"name": "dw_store_cache_events_baa1d7aef2927a8d_s", "value": "[]"}, {"name": "dw_store_queen_data_events_f37b6da8ceddc9c7_kdocs_micro_dw_ordplugin_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_wait_send_events_f37b6da8ceddc9c7_kdocs_vas_main_entry_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_cache_events_65121e0c1197c405_kdocs_kso_ui_plus_65121e0c1197c405", "value": "[]"}, {"name": "_device_id2", "value": "23b76709-a6d3-5fce-3cf1-ebcde09ff144"}, {"name": "dw_store_first_item_token_baa1d7aef2927a8d_s", "value": "true"}, {"name": "weboffice_deviceid", "value": "2c213bfc-5089-4ca7-817f"}, {"name": "dw_store_queen_data_events_65121e0c1197c405_kdocs_kso_ui_plus_65121e0c1197c405", "value": "[]"}, {"name": "DEVICE_ID", "value": "1768555718545"}, {"name": "dw_store_cache_events_f37b6da8ceddc9c7_kdocs_micro_dw_ordplugin_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_queen_data_events_f37b6da8ceddc9c7_kdocs_vas_main_entry_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_dynamic_data_f37b6da8ceddc9c7_kdocs_micro_dw_f37b6da8ceddc9c7", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555773785,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1768550280225,\"data\":[{\"name\":\"addmember_compelete\",\"disable\":true},{\"name\":\"addmember_permission\",\"disable\":true},{\"name\":\"addmember_search\",\"disable\":true},{\"name\":\"ai_createrequest\",\"sendTimely\":true},{\"name\":\"ai_paytiance\",\"disable\":true},{\"name\":\"ai_task\",\"disable\":true},{\"name\":\"api_point\",\"sendTimely\":true},{\"name\":\"appreciation_pdftools\",\"disable\":true},{\"name\":\"avatar_old\",\"disable\":true},{\"name\":\"avatar_panel\",\"disable\":true},{\"name\":\"avator_old\",\"disable\":true},{\"name\":\"backtohome_page\",\"disable\":true},{\"name\":\"click_action\",\"disable\":true},{\"name\":\"company_interfacetips\",\"disable\":true},{\"name\":\"company_service\",\"disable\":true},{\"name\":\"company_serviceoperation\",\"disable\":true},{\"name\":\"company_spaceoperation\",\"disable\":true},{\"name\":\"content_guidance\",\"sendTimely\":true},{\"name\":\"cooperation_function_switchtips_show\",\"disable\":true},{\"name\":\"doc_finished_reading\",\"sendTimely\":true},{\"name\":\"download_fail\",\"disable\":true},{\"name\":\"download_success\",\"disable\":true},{\"name\":\"enterprise_mycloud_show\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_guide\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_package\",\"disable\":true},{\"name\":\"et_decide\",\"encryptAttrs\":[\"response_content\"]},{\"name\":\"et_func\",\"encryptAttrs\":[\"display_content\",\"input_content\"]},{\"name\":\"et_funcshow\",\"encryptAttrs\":[\"display_content\"]},{\"name\":\"et_request\",\"encryptAttrs\":[\"instruction\"]},{\"name\":\"fileapp_package\",\"encryptAttrs\":[\"introductiontext\"]},{\"name\":\"file_share_entry\",\"disable\":true},{\"name\":\"function_guidance\",\"sendTimely\":true},{\"name\":\"func_upload\",\"disable\":true},{\"name\":\"group_assignvip\",\"disable\":true},{\"name\":\"group_createfinish\",\"disable\":true},{\"name\":\"group_createguide_addfile_click\",\"disable\":true},{\"name\":\"group_createguide_addfile_click_fail\",\"disable\":true},{\"name\":\"group_createguide_addfile_later\",\"disable\":true},{\"name\":\"group_createguide_addfile_noshow\",\"disable\":true},{\"name\":\"group_createguide_addfile_show\",\"disable\":true},{\"name\":\"group_createguide_addmember_click\",\"disable\":true},{\"name\":\"group_createguide_addmember_later\",\"disable\":true},{\"name\":\"group_createguide_addmember_noshow\",\"disable\":true},{\"name\":\"group_createguide_addmember_show\",\"disable\":true},{\"name\":\"group_createguide_autocreate\",\"disable\":true},{\"name\":\"group_createpanel\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_click\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_close\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_show\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_click\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_close\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_more\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_show\",\"disable\":true},{\"name\":\"group_enter\",\"disable\":true},{\"name\":\"group_fileselect_cloud\",\"disable\":true},{\"name\":\"group_fileselect_local\",\"disable\":true},{\"name\":\"group_invitepanel\",\"disable\":true},{\"name\":\"group_linkgroup_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_show\",\"disable\":true},{\"name\":\"group_linkgroup_fileoperate\",\"disable\":true},{\"name\":\"group_linkgroup_quit\",\"disable\":true},{\"name\":\"group_linkgroup_rightlistoperate\",\"disable\":true},{\"name\":\"group_mission_click\",\"disable\":true},{\"name\":\"group_mission_finish\",\"disable\":true},{\"name\":\"group_mission_hide\",\"disable\":true},{\"name\":\"group_mission_show\",\"disable\":true},{\"name\":\"group_setup\",\"sendTimely\":true},{\"name\":\"group_vipdetail\",\"disable\":true},{\"name\":\"group_vipguide\",\"disable\":true},{\"name\":\"group_vippay\",\"disable\":true},{\"name\":\"group_vipresult\",\"disable\":true},{\"name\":\"group_vipscan\",\"disable\":true},{\"name\":\"guidance_tipcrad\",\"disable\":true},{\"name\":\"header_openwps_appcheck\",\"disable\":true},{\"name\":\"index_exportlink\",\"disable\":true},{\"name\":\"info_panelsharefileupdate\",\"disable\":true},{\"name\":\"kuc_sdk_loader\",\"disable\":true},{\"name\":\"link_preview\",\"disable\":true},{\"name\":\"mainfest_api\",\"disable\":true},{\"name\":\"massagecontacts_page\",\"disable\":true},{\"name\":\"more_panelssharefileupdate\",\"disable\":true},{\"name\":\"newbuilt_fail\",\"disable\":true},{\"name\":\"newbuilt_success\",\"disable\":true},{\"name\":\"ocr_input\",\"disable\":true},{\"name\":\"offical_bottonclick\",\"disable\":true},{\"name\":\"offical_pageview\",\"disable\":true},{\"name\":\"operation_enhometop\",\"disable\":true},{\"name\":\"operation_kdocsserver\",\"disable\":true},{\"name\":\"pag_user\",\"disable\":true},{\"name\":\"pag_view\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_show\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_show\",\"disable\":true},{\"name\":\"qingupgrade_show\",\"disable\":true},{\"name\":\"qqlogin_guide\",\"disable\":true},{\"name\":\"remindmember_number\",\"disable\":true},{\"name\":\"search_click\",\"sendTimely\":true},{\"name\":\"search_count\",\"disable\":true},{\"name\":\"search_query\",\"sendTimely\":true},{\"name\":\"search_result\",\"sendTimely\":true},{\"name\":\"search_resultaction\",\"sendTimely\":true},{\"name\":\"sharefolder_info_topupdate\",\"disable\":true},{\"name\":\"sharefolder_list_tipsupdate\",\"disable\":true},{\"name\":\"sharefolder_setting_bottomupdate\",\"disable\":true},{\"name\":\"sharefolder_sharefolderselect\",\"disable\":true},{\"name\":\"share_copylink_click\",\"disable\":true},{\"name\":\"share_copylink_toast\",\"disable\":true},{\"name\":\"share_file_cooperater_status\",\"disable\":true},{\"name\":\"share_file_settings\",\"sendTimely\":true},{\"name\":\"share_v3_settings\",\"sendTimely\":true},{\"name\":\"spacefull_pop\",\"disable\":true},{\"name\":\"storage_management_tips\",\"disable\":true},{\"name\":\"tag_hover\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tag_recommend\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tiance_click\",\"sendTimely\":true},{\"name\":\"tiance_show\",\"sendTimely\":true},{\"name\":\"transfer_link\",\"disable\":true},{\"name\":\"vip_wxxcx_iospay\",\"disable\":true},{\"name\":\"welcome_wps\",\"sendTimely\":true},{\"name\":\"wps_send_softbusstracing\",\"disable\":true}]},\"localTime\":1768555718867}"}, {"name": "ord_dc_decive_id", "value": "bf2569bb-a2ed-45a9-b59e-9e890371b0b1"}, {"name": "vronDialogCache_weboffice", "value": "{\"expireTime\":1768579199999}"}, {"name": "isSupportWoff2", "value": "true"}, {"name": "dw_store_wait_send_events", "value": "[]"}, {"name": "dw_store_time_sub_f37b6da8ceddc9c7", "value": "54904"}, {"name": "dw_store_dynamic_data_f37b6da8ceddc9c7_kdocs_vas_main_entry_f37b6da8ceddc9c7", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555773839,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1768550280225,\"data\":[{\"name\":\"addmember_compelete\",\"disable\":true},{\"name\":\"addmember_permission\",\"disable\":true},{\"name\":\"addmember_search\",\"disable\":true},{\"name\":\"ai_createrequest\",\"sendTimely\":true},{\"name\":\"ai_paytiance\",\"disable\":true},{\"name\":\"ai_task\",\"disable\":true},{\"name\":\"api_point\",\"sendTimely\":true},{\"name\":\"appreciation_pdftools\",\"disable\":true},{\"name\":\"avatar_old\",\"disable\":true},{\"name\":\"avatar_panel\",\"disable\":true},{\"name\":\"avator_old\",\"disable\":true},{\"name\":\"backtohome_page\",\"disable\":true},{\"name\":\"click_action\",\"disable\":true},{\"name\":\"company_interfacetips\",\"disable\":true},{\"name\":\"company_service\",\"disable\":true},{\"name\":\"company_serviceoperation\",\"disable\":true},{\"name\":\"company_spaceoperation\",\"disable\":true},{\"name\":\"content_guidance\",\"sendTimely\":true},{\"name\":\"cooperation_function_switchtips_show\",\"disable\":true},{\"name\":\"doc_finished_reading\",\"sendTimely\":true},{\"name\":\"download_fail\",\"disable\":true},{\"name\":\"download_success\",\"disable\":true},{\"name\":\"enterprise_mycloud_show\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_guide\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_package\",\"disable\":true},{\"name\":\"et_decide\",\"encryptAttrs\":[\"response_content\"]},{\"name\":\"et_func\",\"encryptAttrs\":[\"display_content\",\"input_content\"]},{\"name\":\"et_funcshow\",\"encryptAttrs\":[\"display_content\"]},{\"name\":\"et_request\",\"encryptAttrs\":[\"instruction\"]},{\"name\":\"fileapp_package\",\"encryptAttrs\":[\"introductiontext\"]},{\"name\":\"file_share_entry\",\"disable\":true},{\"name\":\"function_guidance\",\"sendTimely\":true},{\"name\":\"func_upload\",\"disable\":true},{\"name\":\"group_assignvip\",\"disable\":true},{\"name\":\"group_createfinish\",\"disable\":true},{\"name\":\"group_createguide_addfile_click\",\"disable\":true},{\"name\":\"group_createguide_addfile_click_fail\",\"disable\":true},{\"name\":\"group_createguide_addfile_later\",\"disable\":true},{\"name\":\"group_createguide_addfile_noshow\",\"disable\":true},{\"name\":\"group_createguide_addfile_show\",\"disable\":true},{\"name\":\"group_createguide_addmember_click\",\"disable\":true},{\"name\":\"group_createguide_addmember_later\",\"disable\":true},{\"name\":\"group_createguide_addmember_noshow\",\"disable\":true},{\"name\":\"group_createguide_addmember_show\",\"disable\":true},{\"name\":\"group_createguide_autocreate\",\"disable\":true},{\"name\":\"group_createpanel\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_click\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_close\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_show\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_click\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_close\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_more\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_show\",\"disable\":true},{\"name\":\"group_enter\",\"disable\":true},{\"name\":\"group_fileselect_cloud\",\"disable\":true},{\"name\":\"group_fileselect_local\",\"disable\":true},{\"name\":\"group_invitepanel\",\"disable\":true},{\"name\":\"group_linkgroup_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_show\",\"disable\":true},{\"name\":\"group_linkgroup_fileoperate\",\"disable\":true},{\"name\":\"group_linkgroup_quit\",\"disable\":true},{\"name\":\"group_linkgroup_rightlistoperate\",\"disable\":true},{\"name\":\"group_mission_click\",\"disable\":true},{\"name\":\"group_mission_finish\",\"disable\":true},{\"name\":\"group_mission_hide\",\"disable\":true},{\"name\":\"group_mission_show\",\"disable\":true},{\"name\":\"group_setup\",\"sendTimely\":true},{\"name\":\"group_vipdetail\",\"disable\":true},{\"name\":\"group_vipguide\",\"disable\":true},{\"name\":\"group_vippay\",\"disable\":true},{\"name\":\"group_vipresult\",\"disable\":true},{\"name\":\"group_vipscan\",\"disable\":true},{\"name\":\"guidance_tipcrad\",\"disable\":true},{\"name\":\"header_openwps_appcheck\",\"disable\":true},{\"name\":\"index_exportlink\",\"disable\":true},{\"name\":\"info_panelsharefileupdate\",\"disable\":true},{\"name\":\"kuc_sdk_loader\",\"disable\":true},{\"name\":\"link_preview\",\"disable\":true},{\"name\":\"mainfest_api\",\"disable\":true},{\"name\":\"massagecontacts_page\",\"disable\":true},{\"name\":\"more_panelssharefileupdate\",\"disable\":true},{\"name\":\"newbuilt_fail\",\"disable\":true},{\"name\":\"newbuilt_success\",\"disable\":true},{\"name\":\"ocr_input\",\"disable\":true},{\"name\":\"offical_bottonclick\",\"disable\":true},{\"name\":\"offical_pageview\",\"disable\":true},{\"name\":\"operation_enhometop\",\"disable\":true},{\"name\":\"operation_kdocsserver\",\"disable\":true},{\"name\":\"pag_user\",\"disable\":true},{\"name\":\"pag_view\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_show\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_show\",\"disable\":true},{\"name\":\"qingupgrade_show\",\"disable\":true},{\"name\":\"qqlogin_guide\",\"disable\":true},{\"name\":\"remindmember_number\",\"disable\":true},{\"name\":\"search_click\",\"sendTimely\":true},{\"name\":\"search_count\",\"disable\":true},{\"name\":\"search_query\",\"sendTimely\":true},{\"name\":\"search_result\",\"sendTimely\":true},{\"name\":\"search_resultaction\",\"sendTimely\":true},{\"name\":\"sharefolder_info_topupdate\",\"disable\":true},{\"name\":\"sharefolder_list_tipsupdate\",\"disable\":true},{\"name\":\"sharefolder_setting_bottomupdate\",\"disable\":true},{\"name\":\"sharefolder_sharefolderselect\",\"disable\":true},{\"name\":\"share_copylink_click\",\"disable\":true},{\"name\":\"share_copylink_toast\",\"disable\":true},{\"name\":\"share_file_cooperater_status\",\"disable\":true},{\"name\":\"share_file_settings\",\"sendTimely\":true},{\"name\":\"share_v3_settings\",\"sendTimely\":true},{\"name\":\"spacefull_pop\",\"disable\":true},{\"name\":\"storage_management_tips\",\"disable\":true},{\"name\":\"tag_hover\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tag_recommend\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tiance_click\",\"sendTimely\":true},{\"name\":\"tiance_show\",\"sendTimely\":true},{\"name\":\"transfer_link\",\"disable\":true},{\"name\":\"vip_wxxcx_iospay\",\"disable\":true},{\"name\":\"welcome_wps\",\"sendTimely\":true},{\"name\":\"wps_send_softbusstracing\",\"disable\":true}]},\"localTime\":1768555718921}"}, {"name": "dw_store_wait_send_events_f37b6da8ceddc9c7_kdocs_micro_dw_ordplugin_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_first_item_token_f37b6da8ceddc9c7_kdocs_micro_dw_f37b6da8ceddc9c7", "value": "true"}, {"name": "dw_store_time_sub_baa1d7aef2927a8d_s", "value": "54840"}, {"name": "micro_app_device_id", "value": "1768555727266"}, {"name": "dw_store_queen_data_events_c2f09479185c91bb_kdocs_plugins_idw_newsdk_c2f09479185c91bb", "value": "[]"}, {"name": "proofread_privileges", "value": "{\"value\":{\"doc_check\":{\"cache_available\":true,\"expire_time\":1971654588,\"value\":-1,\"consumed\":0}},\"expires\":1768556035132}"}, {"name": "dw_store_dynamic_data_baa1d7aef2927a8d_s", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555772132,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1768555680217,\"data\":[{\"name\":\"aiinstruction_action\",\"disable\":true},{\"name\":\"ai_createrequest\",\"sendTimely\":true,\"encryptAttrs\":[\"ai_request_content\",\"pre_ai_request_content\"]},{\"name\":\"ai_funcrequest\",\"encryptAttrs\":[\"ai_request_content\"]},{\"name\":\"ai_requestresult\",\"sendTimely\":true,\"encryptAttrs\":[\"ai_template_fail_reason\"]},{\"name\":\"ai_resultuse\",\"sendTimely\":true},{\"name\":\"db_backend_openfail\",\"disable\":true},{\"name\":\"doc_open\",\"encryptAttrs\":[\"filename\",\"filepath\"]},{\"name\":\"doc_pc\",\"disable\":true},{\"name\":\"et_calc_cache\",\"disable\":true},{\"name\":\"et_calc_fmla\",\"disable\":true},{\"name\":\"et_calc_func\",\"sendTimely\":true},{\"name\":\"et_decide\",\"encryptAttrs\":[\"response_content\"]},{\"name\":\"et_exportpic\",\"disable\":true},{\"name\":\"et_formula_calculate_diffusedirty\",\"disable\":true},{\"name\":\"et_formula_calculate_progresslasttimedur\",\"disable\":true},{\"name\":\"et_func\",\"encryptAttrs\":[\"display_content\",\"input_content\"]},{\"name\":\"et_funcshow\",\"encryptAttrs\":[\"display_content\"]},{\"name\":\"et_mergingcenter\",\"disable\":true},{\"name\":\"et_protect_openfile\",\"disable\":true},{\"name\":\"et_request\",\"encryptAttrs\":[\"instruction\"]},{\"name\":\"index_closeclick\",\"disable\":true},{\"name\":\"index_commenttextdetail\",\"disable\":true},{\"name\":\"index_deletecolumn\",\"disable\":true},{\"name\":\"index_deleterow\",\"disable\":true},{\"name\":\"index_editfile\",\"sendTimely\":true},{\"name\":\"index_findresult\",\"disable\":true},{\"name\":\"index_findstart\",\"disable\":true},{\"name\":\"index_floatingclick\",\"disable\":true},{\"name\":\"index_floatingshow\",\"disable\":true},{\"name\":\"index_h5exam01zhichang\",\"disable\":true},{\"name\":\"index_headermoremenu\",\"disable\":true},{\"name\":\"index_hidesheetrc\",\"disable\":true},{\"name\":\"index_htmlname\",\"encryptAttrs\":[\"url\"]},{\"name\":\"index_insertcolumnleft\",\"disable\":true},{\"name\":\"index_insertcolumnright\",\"disable\":true},{\"name\":\"index_loginreadonly\",\"disable\":true},{\"name\":\"index_monitor\",\"disable\":true},{\"name\":\"index_more\",\"disable\":true},{\"name\":\"index_moremenu\",\"disable\":true},{\"name\":\"index_newpic\",\"disable\":true},{\"name\":\"index_nologin\",\"disable\":true},{\"name\":\"index_offlinemode\",\"encryptAttrs\":[\"url\"]},{\"name\":\"index_openfile\",\"sendTimely\":true},{\"name\":\"index_openfiletime\",\"disable\":true},{\"name\":\"index_otlaiconfe\",\"sendTimely\":true},{\"name\":\"index_picdrag\",\"disable\":true},{\"name\":\"index_picenterview\",\"disable\":true},{\"name\":\"index_picinsertconfirm\",\"disable\":true},{\"name\":\"index_picmove\",\"disable\":true},{\"name\":\"index_python\",\"sendTimely\":true},{\"name\":\"index_sharebtnclick\",\"disable\":true},{\"name\":\"index_showsheetrc\",\"disable\":true},{\"name\":\"index_tablebutton\",\"disable\":true},{\"name\":\"index_tableedit\",\"disable\":true},{\"name\":\"index_tableinsert\",\"disable\":true},{\"name\":\"index_textedittouch\",\"disable\":true},{\"name\":\"index_urlcard\",\"disable\":true},{\"name\":\"index_urledit\",\"disable\":true},{\"name\":\"index_urlinsert\",\"disable\":true},{\"name\":\"index_webcsp\",\"disable\":true},{\"name\":\"index_webmode\",\"disable\":true},{\"name\":\"index_wpsfile\",\"disable\":true},{\"name\":\"index_wpsinfo\",\"disable\":true},{\"name\":\"mpublic_h5exam01zhichang\",\"disable\":true},{\"name\":\"mpublic_loginimprove\",\"disable\":true},{\"name\":\"mpublic_menumore\",\"disable\":true},{\"name\":\"mpublic_moremenu\",\"disable\":true},{\"name\":\"nps_collection_show_web\",\"disable\":true},{\"name\":\"server_openfile\",\"encryptAttrs\":[\"fileid\",\"id\",\"userid\"]},{\"name\":\"svr_contentpermission_getuserpermission\",\"disable\":true},{\"name\":\"svr_copypasteclipboard\",\"disable\":true},{\"name\":\"svr_coreexit\",\"disable\":true},{\"name\":\"svr_demotest\",\"disable\":true},{\"name\":\"svr_editifile\",\"disable\":true},{\"name\":\"svr_etfileopenbookfileinfo\",\"sendTimely\":true},{\"name\":\"svr_etfileopensheetfileinfo\",\"sendTimely\":true},{\"name\":\"svr_etperformancepasteinfo\",\"sendTimely\":true},{\"name\":\"svr_meeting\",\"disable\":true},{\"name\":\"svr_meetinguser\",\"disable\":true},{\"name\":\"svr_openfile\",\"sendTimely\":true},{\"name\":\"svr_slowcommand\",\"disable\":true},{\"name\":\"svr_sqlslotparse\",\"disable\":true},{\"name\":\"svr_versionprune\",\"disable\":true},{\"name\":\"tiance_click\",\"sendTimely\":true},{\"name\":\"tiance_show\",\"sendTimely\":true}]},\"localTime\":1768555717292}"}, {"name": "dw_store_time_sub_65121e0c1197c405_kdocs_kso_ui_plus_65121e0c1197c405", "value": "54912"}, {"name": "dw_store_time_sub_f37b6da8ceddc9c7_kdocs_micro_dw_f37b6da8ceddc9c7", "value": "54918"}, {"name": "open_wps_head_224886932", "value": "{\"config\":{\"xDays\":7,\"yTimes\":1,\"closedNoShowDays\":7},\"lastCloseTimestamp\":0,\"firstShowTimestamp\":1768555735098,\"showTimes\":1,\"popupHasShown\":false}"}, {"name": "290978562164_fake_821071167_sheet_icon_status", "value": "{\"sheetBgColor\":true,\"showCommentIcon\":true,\"showSharedSheetIcon\":true,\"showProtectIcon\":true,\"showMergeIcon\":true,\"firstSetNotShowCommentIcon\":true}"}, {"name": "dw_store_dynamic_data_f37b6da8ceddc9c7", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555772370,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1768550280225,\"data\":[{\"name\":\"addmember_compelete\",\"disable\":true},{\"name\":\"addmember_permission\",\"disable\":true},{\"name\":\"addmember_search\",\"disable\":true},{\"name\":\"ai_createrequest\",\"sendTimely\":true},{\"name\":\"ai_paytiance\",\"disable\":true},{\"name\":\"ai_task\",\"disable\":true},{\"name\":\"api_point\",\"sendTimely\":true},{\"name\":\"appreciation_pdftools\",\"disable\":true},{\"name\":\"avatar_old\",\"disable\":true},{\"name\":\"avatar_panel\",\"disable\":true},{\"name\":\"avator_old\",\"disable\":true},{\"name\":\"backtohome_page\",\"disable\":true},{\"name\":\"click_action\",\"disable\":true},{\"name\":\"company_interfacetips\",\"disable\":true},{\"name\":\"company_service\",\"disable\":true},{\"name\":\"company_serviceoperation\",\"disable\":true},{\"name\":\"company_spaceoperation\",\"disable\":true},{\"name\":\"content_guidance\",\"sendTimely\":true},{\"name\":\"cooperation_function_switchtips_show\",\"disable\":true},{\"name\":\"doc_finished_reading\",\"sendTimely\":true},{\"name\":\"download_fail\",\"disable\":true},{\"name\":\"download_success\",\"disable\":true},{\"name\":\"enterprise_mycloud_show\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_guide\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_package\",\"disable\":true},{\"name\":\"et_decide\",\"encryptAttrs\":[\"response_content\"]},{\"name\":\"et_func\",\"encryptAttrs\":[\"display_content\",\"input_content\"]},{\"name\":\"et_funcshow\",\"encryptAttrs\":[\"display_content\"]},{\"name\":\"et_request\",\"encryptAttrs\":[\"instruction\"]},{\"name\":\"fileapp_package\",\"encryptAttrs\":[\"introductiontext\"]},{\"name\":\"file_share_entry\",\"disable\":true},{\"name\":\"function_guidance\",\"sendTimely\":true},{\"name\":\"func_upload\",\"disable\":true},{\"name\":\"group_assignvip\",\"disable\":true},{\"name\":\"group_createfinish\",\"disable\":true},{\"name\":\"group_createguide_addfile_click\",\"disable\":true},{\"name\":\"group_createguide_addfile_click_fail\",\"disable\":true},{\"name\":\"group_createguide_addfile_later\",\"disable\":true},{\"name\":\"group_createguide_addfile_noshow\",\"disable\":true},{\"name\":\"group_createguide_addfile_show\",\"disable\":true},{\"name\":\"group_createguide_addmember_click\",\"disable\":true},{\"name\":\"group_createguide_addmember_later\",\"disable\":true},{\"name\":\"group_createguide_addmember_noshow\",\"disable\":true},{\"name\":\"group_createguide_addmember_show\",\"disable\":true},{\"name\":\"group_createguide_autocreate\",\"disable\":true},{\"name\":\"group_createpanel\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_click\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_close\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_show\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_click\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_close\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_more\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_show\",\"disable\":true},{\"name\":\"group_enter\",\"disable\":true},{\"name\":\"group_fileselect_cloud\",\"disable\":true},{\"name\":\"group_fileselect_local\",\"disable\":true},{\"name\":\"group_invitepanel\",\"disable\":true},{\"name\":\"group_linkgroup_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_show\",\"disable\":true},{\"name\":\"group_linkgroup_fileoperate\",\"disable\":true},{\"name\":\"group_linkgroup_quit\",\"disable\":true},{\"name\":\"group_linkgroup_rightlistoperate\",\"disable\":true},{\"name\":\"group_mission_click\",\"disable\":true},{\"name\":\"group_mission_finish\",\"disable\":true},{\"name\":\"group_mission_hide\",\"disable\":true},{\"name\":\"group_mission_show\",\"disable\":true},{\"name\":\"group_setup\",\"sendTimely\":true},{\"name\":\"group_vipdetail\",\"disable\":true},{\"name\":\"group_vipguide\",\"disable\":true},{\"name\":\"group_vippay\",\"disable\":true},{\"name\":\"group_vipresult\",\"disable\":true},{\"name\":\"group_vipscan\",\"disable\":true},{\"name\":\"guidance_tipcrad\",\"disable\":true},{\"name\":\"header_openwps_appcheck\",\"disable\":true},{\"name\":\"index_exportlink\",\"disable\":true},{\"name\":\"info_panelsharefileupdate\",\"disable\":true},{\"name\":\"kuc_sdk_loader\",\"disable\":true},{\"name\":\"link_preview\",\"disable\":true},{\"name\":\"mainfest_api\",\"disable\":true},{\"name\":\"massagecontacts_page\",\"disable\":true},{\"name\":\"more_panelssharefileupdate\",\"disable\":true},{\"name\":\"newbuilt_fail\",\"disable\":true},{\"name\":\"newbuilt_success\",\"disable\":true},{\"name\":\"ocr_input\",\"disable\":true},{\"name\":\"offical_bottonclick\",\"disable\":true},{\"name\":\"offical_pageview\",\"disable\":true},{\"name\":\"operation_enhometop\",\"disable\":true},{\"name\":\"operation_kdocsserver\",\"disable\":true},{\"name\":\"pag_user\",\"disable\":true},{\"name\":\"pag_view\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_show\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_show\",\"disable\":true},{\"name\":\"qingupgrade_show\",\"disable\":true},{\"name\":\"qqlogin_guide\",\"disable\":true},{\"name\":\"remindmember_number\",\"disable\":true},{\"name\":\"search_click\",\"sendTimely\":true},{\"name\":\"search_count\",\"disable\":true},{\"name\":\"search_query\",\"sendTimely\":true},{\"name\":\"search_result\",\"sendTimely\":true},{\"name\":\"search_resultaction\",\"sendTimely\":true},{\"name\":\"sharefolder_info_topupdate\",\"disable\":true},{\"name\":\"sharefolder_list_tipsupdate\",\"disable\":true},{\"name\":\"sharefolder_setting_bottomupdate\",\"disable\":true},{\"name\":\"sharefolder_sharefolderselect\",\"disable\":true},{\"name\":\"share_copylink_click\",\"disable\":true},{\"name\":\"share_copylink_toast\",\"disable\":true},{\"name\":\"share_file_cooperater_status\",\"disable\":true},{\"name\":\"share_file_settings\",\"sendTimely\":true},{\"name\":\"share_v3_settings\",\"sendTimely\":true},{\"name\":\"spacefull_pop\",\"disable\":true},{\"name\":\"storage_management_tips\",\"disable\":true},{\"name\":\"tag_hover\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tag_recommend\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tiance_click\",\"sendTimely\":true},{\"name\":\"tiance_show\",\"sendTimely\":true},{\"name\":\"transfer_link\",\"disable\":true},{\"name\":\"vip_wxxcx_iospay\",\"disable\":true},{\"name\":\"welcome_wps\",\"sendTimely\":true},{\"name\":\"wps_send_softbusstracing\",\"disable\":true}]},\"localTime\":1768555717466}"}, {"name": "nps-last-Plugin-Activation-Time", "value": "1768492800000"}, {"name": "dw_store_dynamic_data_c2f09479185c91bb_kdocs_micro_new_file_dw_c2f09479185c91bb", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1673487839000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555773721,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1765358764138},\"localTime\":1768555718811}"}, {"name": "dw_store_wait_send_events_f37b6da8ceddc9c7_kdocs_kso_ui_f37b6da8ceddc9c7", "value": "[]"}, {"name": "__M_ET_KEYBOARD_HEIGHT__", "value": "720"}, {"name": "dw_store_wait_send_events_f37b6da8ceddc9c7", "value": "[]"}, {"name": "cpwEOo5ynKX4_active_sheet_type", "value": "xlWorksheet"}, {"name": "dw_store_wait_send_events_f37b6da8ceddc9c7_kdocs_micro_dw_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_queen_data_events_c2f09479185c91bb_kdocs_micro_new_file_dw_c2f09479185c91bb", "value": "[]"}, {"name": "dw_store_dynamic_data_65121e0c1197c405_kdocs_kso_ui_plus_65121e0c1197c405", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555791336,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1765358764418,\"data\":[{\"name\":\"common_insert\",\"disable\":true},{\"name\":\"common_panel\",\"disable\":true},{\"name\":\"contactcard_action\",\"disable\":true},{\"name\":\"contactselector_closeevent\",\"disable\":true},{\"name\":\"contactselector_loadingtime\",\"disable\":true},{\"name\":\"contactselector_onescreentime\",\"disable\":true},{\"name\":\"contactselector_searchtime\",\"disable\":true},{\"name\":\"contactselector_selectobject\",\"disable\":true},{\"name\":\"contact_selector_abnormal\",\"disable\":true},{\"name\":\"contact_selector_addcontacts\",\"disable\":true},{\"name\":\"contact_selector_loadtime\",\"disable\":true},{\"name\":\"contact_selector_selectobjects\",\"disable\":true},{\"name\":\"groupsetting_aiteamturnon_duration\",\"disable\":true},{\"name\":\"groupsetting_session_duration\",\"disable\":true},{\"name\":\"selectorfile_breadcrumb\",\"disable\":true},{\"name\":\"selectorfile_show\",\"disable\":true}]},\"localTime\":1768555736424}"}, {"name": "kshare_et_sharePermission", "value": "Editable"}, {"name": "cpwEOo5ynKX4_sheet\u9053\u53bf_topleft_cell", "value": "{\"cellLeftTop\":{\"col\":0,\"row\":0},\"paneInfo\":{\"activePane\":1,\"cellLeftTop\":{\"row\":2,\"col\":0},\"wndPos\":{\"left\":0,\"top\":2}}}"}, {"name": "dw_store_time_sub_c2f09479185c91bb_kdocs_micro_new_file_dw_c2f09479185c91bb", "value": "54910"}, {"name": "dw_store_dynamic_data_f37b6da8ceddc9c7_kdocs_kso_ui_f37b6da8ceddc9c7", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555774815,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1768550280225,\"data\":[{\"name\":\"addmember_compelete\",\"disable\":true},{\"name\":\"addmember_permission\",\"disable\":true},{\"name\":\"addmember_search\",\"disable\":true},{\"name\":\"ai_createrequest\",\"sendTimely\":true},{\"name\":\"ai_paytiance\",\"disable\":true},{\"name\":\"ai_task\",\"disable\":true},{\"name\":\"api_point\",\"sendTimely\":true},{\"name\":\"appreciation_pdftools\",\"disable\":true},{\"name\":\"avatar_old\",\"disable\":true},{\"name\":\"avatar_panel\",\"disable\":true},{\"name\":\"avator_old\",\"disable\":true},{\"name\":\"backtohome_page\",\"disable\":true},{\"name\":\"click_action\",\"disable\":true},{\"name\":\"company_interfacetips\",\"disable\":true},{\"name\":\"company_service\",\"disable\":true},{\"name\":\"company_serviceoperation\",\"disable\":true},{\"name\":\"company_spaceoperation\",\"disable\":true},{\"name\":\"content_guidance\",\"sendTimely\":true},{\"name\":\"cooperation_function_switchtips_show\",\"disable\":true},{\"name\":\"doc_finished_reading\",\"sendTimely\":true},{\"name\":\"download_fail\",\"disable\":true},{\"name\":\"download_success\",\"disable\":true},{\"name\":\"enterprise_mycloud_show\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_guide\",\"disable\":true},{\"name\":\"enterprise_sharefolderupgrade_package\",\"disable\":true},{\"name\":\"et_decide\",\"encryptAttrs\":[\"response_content\"]},{\"name\":\"et_func\",\"encryptAttrs\":[\"display_content\",\"input_content\"]},{\"name\":\"et_funcshow\",\"encryptAttrs\":[\"display_content\"]},{\"name\":\"et_request\",\"encryptAttrs\":[\"instruction\"]},{\"name\":\"fileapp_package\",\"encryptAttrs\":[\"introductiontext\"]},{\"name\":\"file_share_entry\",\"disable\":true},{\"name\":\"function_guidance\",\"sendTimely\":true},{\"name\":\"func_upload\",\"disable\":true},{\"name\":\"group_assignvip\",\"disable\":true},{\"name\":\"group_createfinish\",\"disable\":true},{\"name\":\"group_createguide_addfile_click\",\"disable\":true},{\"name\":\"group_createguide_addfile_click_fail\",\"disable\":true},{\"name\":\"group_createguide_addfile_later\",\"disable\":true},{\"name\":\"group_createguide_addfile_noshow\",\"disable\":true},{\"name\":\"group_createguide_addfile_show\",\"disable\":true},{\"name\":\"group_createguide_addmember_click\",\"disable\":true},{\"name\":\"group_createguide_addmember_later\",\"disable\":true},{\"name\":\"group_createguide_addmember_noshow\",\"disable\":true},{\"name\":\"group_createguide_addmember_show\",\"disable\":true},{\"name\":\"group_createguide_autocreate\",\"disable\":true},{\"name\":\"group_createpanel\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_click\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_close\",\"disable\":true},{\"name\":\"group_emptyguide_addfile_show\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_click\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_close\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_more\",\"disable\":true},{\"name\":\"group_emptyguide_addmember_show\",\"disable\":true},{\"name\":\"group_enter\",\"disable\":true},{\"name\":\"group_fileselect_cloud\",\"disable\":true},{\"name\":\"group_fileselect_local\",\"disable\":true},{\"name\":\"group_invitepanel\",\"disable\":true},{\"name\":\"group_linkgroup_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_click\",\"disable\":true},{\"name\":\"group_linkgroup_entrance_show\",\"disable\":true},{\"name\":\"group_linkgroup_fileoperate\",\"disable\":true},{\"name\":\"group_linkgroup_quit\",\"disable\":true},{\"name\":\"group_linkgroup_rightlistoperate\",\"disable\":true},{\"name\":\"group_mission_click\",\"disable\":true},{\"name\":\"group_mission_finish\",\"disable\":true},{\"name\":\"group_mission_hide\",\"disable\":true},{\"name\":\"group_mission_show\",\"disable\":true},{\"name\":\"group_setup\",\"sendTimely\":true},{\"name\":\"group_vipdetail\",\"disable\":true},{\"name\":\"group_vipguide\",\"disable\":true},{\"name\":\"group_vippay\",\"disable\":true},{\"name\":\"group_vipresult\",\"disable\":true},{\"name\":\"group_vipscan\",\"disable\":true},{\"name\":\"guidance_tipcrad\",\"disable\":true},{\"name\":\"header_openwps_appcheck\",\"disable\":true},{\"name\":\"index_exportlink\",\"disable\":true},{\"name\":\"info_panelsharefileupdate\",\"disable\":true},{\"name\":\"kuc_sdk_loader\",\"disable\":true},{\"name\":\"link_preview\",\"disable\":true},{\"name\":\"mainfest_api\",\"disable\":true},{\"name\":\"massagecontacts_page\",\"disable\":true},{\"name\":\"more_panelssharefileupdate\",\"disable\":true},{\"name\":\"newbuilt_fail\",\"disable\":true},{\"name\":\"newbuilt_success\",\"disable\":true},{\"name\":\"ocr_input\",\"disable\":true},{\"name\":\"offical_bottonclick\",\"disable\":true},{\"name\":\"offical_pageview\",\"disable\":true},{\"name\":\"operation_enhometop\",\"disable\":true},{\"name\":\"operation_kdocsserver\",\"disable\":true},{\"name\":\"pag_user\",\"disable\":true},{\"name\":\"pag_view\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_qqloginguide_show\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_click\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_close\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_loginsucess\",\"disable\":true},{\"name\":\"preview_mdrive_wechatloginguide_show\",\"disable\":true},{\"name\":\"qingupgrade_show\",\"disable\":true},{\"name\":\"qqlogin_guide\",\"disable\":true},{\"name\":\"remindmember_number\",\"disable\":true},{\"name\":\"search_click\",\"sendTimely\":true},{\"name\":\"search_count\",\"disable\":true},{\"name\":\"search_query\",\"sendTimely\":true},{\"name\":\"search_result\",\"sendTimely\":true},{\"name\":\"search_resultaction\",\"sendTimely\":true},{\"name\":\"sharefolder_info_topupdate\",\"disable\":true},{\"name\":\"sharefolder_list_tipsupdate\",\"disable\":true},{\"name\":\"sharefolder_setting_bottomupdate\",\"disable\":true},{\"name\":\"sharefolder_sharefolderselect\",\"disable\":true},{\"name\":\"share_copylink_click\",\"disable\":true},{\"name\":\"share_copylink_toast\",\"disable\":true},{\"name\":\"share_file_cooperater_status\",\"disable\":true},{\"name\":\"share_file_settings\",\"sendTimely\":true},{\"name\":\"share_v3_settings\",\"sendTimely\":true},{\"name\":\"spacefull_pop\",\"disable\":true},{\"name\":\"storage_management_tips\",\"disable\":true},{\"name\":\"tag_hover\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tag_recommend\",\"encryptAttrs\":[\"filename\",\"tagname\"]},{\"name\":\"tiance_click\",\"sendTimely\":true},{\"name\":\"tiance_show\",\"sendTimely\":true},{\"name\":\"transfer_link\",\"disable\":true},{\"name\":\"vip_wxxcx_iospay\",\"disable\":true},{\"name\":\"welcome_wps\",\"sendTimely\":true},{\"name\":\"wps_send_softbusstracing\",\"disable\":true}]},\"localTime\":1768555719889}"}, {"name": "290978562164_224886932_sheet_icon_status", "value": "{\"sheetBgColor\":true,\"showCommentIcon\":true,\"showSharedSheetIcon\":true,\"showProtectIcon\":true,\"showMergeIcon\":true,\"firstSetNotShowCommentIcon\":true}"}, {"name": "dw_store_first_item_token_f37b6da8ceddc9c7", "value": "true"}, {"name": "dw_store_first_item_token_c2f09479185c91bb_kdocs_micro_new_file_dw_c2f09479185c91bb", "value": "true"}, {"name": "dw_store_cache_events_f37b6da8ceddc9c7_kdocs_micro_dw_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_time_sub_f37b6da8ceddc9c7_kdocs_vas_main_entry_f37b6da8ceddc9c7", "value": "54918"}, {"name": "et_system_font_state_update", "value": "1768555732886"}, {"name": "doc-encryptor-iv-1.0_290978562164-224886932", "value": "$MkZszjSw6x:EG)p"}, {"name": "dw_store_time_sub_f37b6da8ceddc9c7_kdocs_micro_dw_ordplugin_f37b6da8ceddc9c7", "value": "54926"}, {"name": "dw_store_wait_send_events_c2f09479185c91bb_kdocs_micro_new_file_dw_c2f09479185c91bb", "value": "[]"}, {"name": "dw_store_wait_send_events_c2f09479185c91bb_kdocs_plugins_idw_newsdk_c2f09479185c91bb", "value": "[]"}, {"name": "cpwEOo5ynKX4_accdate", "value": "1768555733956"}, {"name": "dw_store_first_item_token_f37b6da8ceddc9c7_kdocs_vas_main_entry_f37b6da8ceddc9c7", "value": "true"}, {"name": "dw_store_wait_send_events_baa1d7aef2927a8d_s", "value": "[]"}, {"name": "dw_store_first_item_token_65121e0c1197c405_kdocs_kso_ui_plus_65121e0c1197c405", "value": "true"}, {"name": "et_ai_device_id", "value": "fgz0licpfoaou21y5ikgwkosmlv6muhk"}, {"name": "cpwEOo5ynKX4_active_sheet", "value": "\u9053\u53bf"}, {"name": "master_tab_records", "value": "[{\"key\":\"master_tab_id_290978562164_224886932\",\"tabId\":\"e0bd8565\",\"time\":1768555732151},{\"key\":\"master_tab_id_290978562164_fake_821071167\",\"tabId\":\"512a1218\",\"time\":1768555715052}]"}, {"name": "dw_store_queen_data_events_f37b6da8ceddc9c7_kdocs_micro_dw_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_cache_events", "value": "[]"}, {"name": "dw_store_cache_events_f37b6da8ceddc9c7_kdocs_vas_main_entry_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_time_sub_c2f09479185c91bb_kdocs_plugins_idw_newsdk_c2f09479185c91bb", "value": "54916"}, {"name": "cpwEOo5ynKX4_sheet_icon_status", "value": "{\"sheetBgColor\":true,\"showCommentIcon\":true,\"showSharedSheetIcon\":true,\"showProtectIcon\":true,\"showMergeIcon\":true,\"firstSetNotShowCommentIcon\":true}"}, {"name": "dw_store_wait_send_events_65121e0c1197c405_kdocs_kso_ui_plus_65121e0c1197c405", "value": "[]"}, {"name": "cpwEOo5ynKX4_active_sheet_id", "value": "2"}, {"name": "dw_store_time_sub_f37b6da8ceddc9c7_kdocs_kso_ui_f37b6da8ceddc9c7", "value": "54926"}, {"name": "dw_store_first_item_token_c2f09479185c91bb_kdocs_plugins_idw_newsdk_c2f09479185c91bb", "value": "true"}, {"name": "dw_store_first_item_token_f37b6da8ceddc9c7_kdocs_micro_dw_ordplugin_f37b6da8ceddc9c7", "value": "true"}, {"name": "dw_store_device_id_key@65121e0c1197c405", "value": "4f3a09da-895a-63c2-97d0-6a263b39abce"}, {"name": "ET_SHOW_AI_AUTOFILL_TIP", "value": "1"}, {"name": "dw_store_cache_events_f37b6da8ceddc9c7_kdocs_kso_ui_f37b6da8ceddc9c7", "value": "[]"}, {"name": "dw_store_cache_events_f37b6da8ceddc9c7", "value": "[]"}, {"name": "sendRequest", "value": "true"}, {"name": "dw_store_device_id_key", "value": "4f3a09da-895a-63c2-97d0-6a263b39abce"}, {"name": "et_system_font_state", "value": "{\"\u5fae\u8f6f\u96c5\u9ed1\":true,\"Arial\":true,\"Calibri\":true,\"Batang\":false,\"BatangChe\":false,\"Times New Roman\":true,\"Arial Unicode MS\":false,\"SimSun-ExtB\":true,\"\u65b9\u6b63\u8212\u4f53\":false,\"\u65b9\u6b63\u59da\u4f53\":false,\"\u4eff\u5b8b\":true,\"\u9ed1\u4f53\":true,\"\u6977\u4f53\":true,\"\u96b6\u4e66\":false,\"\u65b0\u5b8b\u4f53\":false,\"\u5e7c\u5706\":false,\"misans\":false,\"misans demibold\":false,\"misans extralight\":false,\"misans heavy\":false,\"misans light\":false,\"misans medium\":false,\"misans normal\":false,\"misans semibold\":false,\"misans thin\":false,\"wps\u7075\u79c0\u9ed1\":false,\"\u534e\u6587\u4e2d\u5b8b\":false,\"\u534e\u6587\u4eff\u5b8b\":false,\"\u534e\u6587\u5b8b\u4f53\":false,\"\u534e\u6587\u5f69\u4e91\":false,\"\u534e\u6587\u65b0\u9b4f\":false,\"\u534e\u6587\u6977\u4f53\":false,\"\u534e\u6587\u7425\u73c0\":false,\"\u534e\u6587\u7ec6\u9ed1\":false,\"\u534e\u6587\u884c\u6977\":false,\"\u534e\u6587\u96b6\u4e66\":false}"}, {"name": "_HAS_OPEN_DOCS_s", "value": "20260107165518-6fa9ffc102"}, {"name": "dw_store_first_item_token_f37b6da8ceddc9c7_kdocs_kso_ui_f37b6da8ceddc9c7", "value": "true"}, {"name": "dw_store_device_id_key@c2f09479185c91bb", "value": "4f3a09da-895a-63c2-97d0-6a263b39abce"}, {"name": "dw_store_device_id_key@f37b6da8ceddc9c7", "value": "4f3a09da-895a-63c2-97d0-6a263b39abce"}, {"name": "dw_store_queen_data_events", "value": "[]"}, {"name": "dw_store_queen_data_events_f37b6da8ceddc9c7_kdocs_kso_ui_f37b6da8ceddc9c7", "value": "[]"}, {"name": "theme_mode", "value": "{\"base\":\"light\",\"aid\":\"default\"}"}, {"name": "dw_store_device_id_key@baa1d7aef2927a8d", "value": "4f3a09da-895a-63c2-97d0-6a263b39abce"}]}, {"origin": "https://account.kdocs.cn", "localStorage": [{"name": "kso_acct_code_challenge@8yI_vWjD1p33STrx41heF__hjNBo5m5UH7RkNEO4GHU", "value": "3qZy-4pxQBUZzQRffoHmhXMrj4Yg2.40Q~hK0c2yZwx8KUPzk-ZZdigsoP2tCDRwj6mce3brZtg5MT1SWiSZz6aduZn0e0lPZC5S1aR6"}]}, {"origin": "https://account.wps.cn", "localStorage": [{"name": "dw_store_device_id_key@cd74cafb92f3c9a8", "value": "7b29bc7a-0fbb-89ef-a766-26d8dcfa2d0e"}, {"name": "dw_store_device_id_key", "value": "7b29bc7a-0fbb-89ef-a766-26d8dcfa2d0e"}, {"name": "dw_store_cache_events_cd74cafb92f3c9a8", "value": "[]"}, {"name": "dw_store_first_item_token_cd74cafb92f3c9a8", "value": "true"}, {"name": "dw_store_time_sub_cd74cafb92f3c9a8", "value": "54926"}, {"name": "dw_store_wait_send_events_cd74cafb92f3c9a8", "value": "[]"}, {"name": "dw_store_dynamic_data_cd74cafb92f3c9a8", "value": "{\"uploadStrategy\":{\"version\":1590138000000,\"transportControl\":{\"splitSize\":50,\"gzipSize\":10}},\"sendUrls\":{\"version\":1590138000000,\"urls\":\"(https://shuc-js.ksord.com/bat/js/cors)\",\"debugUrls\":\"(https://dw-collect-debug.ksord.com)\"},\"dnsParseIp\":\"120.92.114.92\",\"abTestTag\":{\"version\":-3},\"serverTime\":1768555782442,\"dynamicUrl\":\"https://dw-online.ksosoft.com\",\"events\":{\"version\":1767922320053,\"data\":[{\"name\":\"cloudplatform_accountwebapirealtime\",\"disable\":true},{\"name\":\"cloudplatform_accountwebjsrealtime\",\"disable\":true},{\"name\":\"cloudplatform_accountwxpluginapirealtime\",\"disable\":true},{\"name\":\"cloudplatform_accountwxpluginjs\",\"disable\":true},{\"name\":\"cloudplatform_accountwxpluginjsrealtime\",\"disable\":true},{\"name\":\"cloudplatform_login_select_click\",\"disable\":true},{\"name\":\"cloudplatform_login_select_show\",\"disable\":true},{\"name\":\"cloudplatform_wxapplets_element_authorizeclick\",\"disable\":true},{\"name\":\"cloudplatform_wxapplets_element_authorizeshow\",\"disable\":true},{\"name\":\"cloudplatform_wxapplets_element_call\",\"disable\":true},{\"name\":\"cloudplatform_wxapplets_element_loginresult\",\"disable\":true},{\"name\":\"cloudplatform_wxapplets_element_registrationresult\",\"disable\":true},{\"name\":\"enterprise_create\",\"disable\":true},{\"name\":\"login_bindphone\",\"disable\":true},{\"name\":\"login_click\",\"disable\":true},{\"name\":\"login_loadtime\",\"disable\":true},{\"name\":\"login_performance\",\"disable\":true},{\"name\":\"login_scan_quick\",\"disable\":true},{\"name\":\"login_show\",\"disable\":true},{\"name\":\"login_supportcrypto\",\"disable\":true},{\"name\":\"wechat_h5authorize_click\",\"disable\":true},{\"name\":\"wechat_h5authorize_show\",\"disable\":true}]},\"localTime\":1768555727516}"}, {"name": "dw_store_queen_data_events_cd74cafb92f3c9a8", "value": "[]"}]}]} \ No newline at end of file diff --git a/data/secret_key.txt b/data/secret_key.txt deleted file mode 100644 index c31cbdb..0000000 --- a/data/secret_key.txt +++ /dev/null @@ -1 +0,0 @@ -4abccefe523ed05bdbb717d1153e202d25ade95458c4d78e \ No newline at end of file diff --git a/database.py b/database.py index 64a3406..575e508 100644 --- a/database.py +++ b/database.py @@ -109,6 +109,7 @@ from db.users import ( delete_user, extend_user_vip, get_all_users, + get_users_count, get_pending_users, get_user_by_id, get_user_by_username, diff --git a/db/users.py b/db/users.py index 81b343f..1a6e49c 100644 --- a/db/users.py +++ b/db/users.py @@ -25,6 +25,20 @@ _USER_LOOKUP_SQL = { "id": "SELECT * FROM users WHERE id = ?", "username": "SELECT * FROM users WHERE username = ?", } +_USER_ADMIN_SAFE_COLUMNS = ( + "id", + "username", + "email", + "email_verified", + "email_notify_enabled", + "kdocs_unit", + "kdocs_auto_upload", + "status", + "vip_expire_time", + "created_at", + "approved_at", +) +_USER_ADMIN_SAFE_COLUMNS_SQL = ", ".join(_USER_ADMIN_SAFE_COLUMNS) def _row_to_dict(row): @@ -283,19 +297,63 @@ def get_user_by_username(username): return _get_user_by_field("username", username) -def get_all_users(): - """获取所有用户""" +def _normalize_limit_offset(limit, offset, *, max_limit: int = 500): + normalized_limit = None + if limit is not None: + try: + normalized_limit = int(limit) + except (TypeError, ValueError): + normalized_limit = 50 + normalized_limit = max(1, min(normalized_limit, max_limit)) + + try: + normalized_offset = int(offset or 0) + except (TypeError, ValueError): + normalized_offset = 0 + normalized_offset = max(0, normalized_offset) + + return normalized_limit, normalized_offset + + +def get_users_count(*, status: str | None = None) -> int: with db_pool.get_db() as conn: cursor = conn.cursor() - cursor.execute("SELECT * FROM users ORDER BY created_at DESC") + if status: + cursor.execute("SELECT COUNT(*) AS count FROM users WHERE status = ?", (status,)) + else: + cursor.execute("SELECT COUNT(*) AS count FROM users") + row = cursor.fetchone() + return int((row["count"] if row else 0) or 0) + + +def get_all_users(*, limit=None, offset=0): + """获取所有用户""" + limit, offset = _normalize_limit_offset(limit, offset) + with db_pool.get_db() as conn: + cursor = conn.cursor() + sql = f"SELECT {_USER_ADMIN_SAFE_COLUMNS_SQL} FROM users ORDER BY created_at DESC" + params = [] + if limit is not None: + sql += " LIMIT ? OFFSET ?" + params.extend([limit, offset]) + cursor.execute(sql, params) return [dict(row) for row in cursor.fetchall()] -def get_pending_users(): +def get_pending_users(*, limit=None, offset=0): """获取待审核用户""" + limit, offset = _normalize_limit_offset(limit, offset) with db_pool.get_db() as conn: cursor = conn.cursor() - cursor.execute("SELECT * FROM users WHERE status = 'pending' ORDER BY created_at DESC") + sql = ( + f"SELECT {_USER_ADMIN_SAFE_COLUMNS_SQL} " + "FROM users WHERE status = 'pending' ORDER BY created_at DESC" + ) + params = [] + if limit is not None: + sql += " LIMIT ? OFFSET ?" + params.extend([limit, offset]) + cursor.execute(sql, params) return [dict(row) for row in cursor.fetchall()] diff --git a/requirements.txt b/requirements.txt index 76e5960..8c926dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ schedule==1.2.0 psutil==5.9.6 pytz==2024.1 bcrypt==4.0.1 -requests==2.31.0 +requests==2.32.3 python-dotenv==1.0.0 beautifulsoup4==4.12.2 cryptography>=41.0.0 diff --git a/routes/admin_api/core.py b/routes/admin_api/core.py index 292bde0..8f3f232 100644 --- a/routes/admin_api/core.py +++ b/routes/admin_api/core.py @@ -355,9 +355,6 @@ def admin_logout(): session.pop("admin_id", None) session.pop("admin_username", None) session.pop("admin_reauth_until", None) - session.pop("_user_id", None) - session.pop("_fresh", None) - session.pop("_id", None) return jsonify({"success": True}) diff --git a/routes/admin_api/email_api.py b/routes/admin_api/email_api.py index d4aaa5f..94786c7 100644 --- a/routes/admin_api/email_api.py +++ b/routes/admin_api/email_api.py @@ -21,7 +21,7 @@ def get_email_settings_api(): return jsonify(settings) except Exception as e: logger.error(f"获取邮件设置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "获取邮件设置失败"}), 500 @admin_api_bp.route("/email/settings", methods=["POST"]) @@ -48,7 +48,7 @@ def update_email_settings_api(): return jsonify({"success": True}) except Exception as e: logger.error(f"更新邮件设置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "更新邮件设置失败"}), 500 @admin_api_bp.route("/smtp/configs", methods=["GET"]) @@ -60,7 +60,7 @@ def get_smtp_configs_api(): return jsonify(configs) except Exception as e: logger.error(f"获取SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "获取SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs", methods=["POST"]) @@ -78,7 +78,7 @@ def create_smtp_config_api(): return jsonify({"success": True, "id": config_id}) except Exception as e: logger.error(f"创建SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "创建SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs/", methods=["GET"]) @@ -92,7 +92,7 @@ def get_smtp_config_api(config_id): return jsonify(config_data) except Exception as e: logger.error(f"获取SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "获取SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs/", methods=["PUT"]) @@ -106,7 +106,7 @@ def update_smtp_config_api(config_id): return jsonify({"error": "更新失败"}), 400 except Exception as e: logger.error(f"更新SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "更新SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs/", methods=["DELETE"]) @@ -119,7 +119,7 @@ def delete_smtp_config_api(config_id): return jsonify({"error": "删除失败"}), 400 except Exception as e: logger.error(f"删除SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "删除SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs//test", methods=["POST"]) @@ -140,7 +140,7 @@ def test_smtp_config_api(config_id): return jsonify(result) except Exception as e: logger.error(f"测试SMTP配置失败: {e}") - return jsonify({"success": False, "error": str(e)}), 500 + return jsonify({"success": False, "error": "测试SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs//primary", methods=["POST"]) @@ -153,7 +153,7 @@ def set_primary_smtp_config_api(config_id): return jsonify({"error": "设置失败"}), 400 except Exception as e: logger.error(f"设置主SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "设置主SMTP配置失败"}), 500 @admin_api_bp.route("/smtp/configs/primary/clear", methods=["POST"]) @@ -165,7 +165,7 @@ def clear_primary_smtp_config_api(): return jsonify({"success": True}) except Exception as e: logger.error(f"取消主SMTP配置失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "取消主SMTP配置失败"}), 500 @admin_api_bp.route("/email/stats", methods=["GET"]) @@ -177,7 +177,7 @@ def get_email_stats_api(): return jsonify(stats) except Exception as e: logger.error(f"获取邮件统计失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "获取邮件统计失败"}), 500 @admin_api_bp.route("/email/logs", methods=["GET"]) @@ -195,7 +195,7 @@ def get_email_logs_api(): return jsonify(result) except Exception as e: logger.error(f"获取邮件日志失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "获取邮件日志失败"}), 500 @admin_api_bp.route("/email/logs/cleanup", methods=["POST"]) @@ -211,4 +211,4 @@ def cleanup_email_logs_api(): return jsonify({"success": True, "deleted": deleted}) except Exception as e: logger.error(f"清理邮件日志失败: {e}") - return jsonify({"error": str(e)}), 500 + return jsonify({"error": "清理邮件日志失败"}), 500 diff --git a/routes/admin_api/system_config_api.py b/routes/admin_api/system_config_api.py index 7daa56e..aaa4663 100644 --- a/routes/admin_api/system_config_api.py +++ b/routes/admin_api/system_config_api.py @@ -80,7 +80,7 @@ def update_system_config_api(): if schedule_time is not None: import re - if not re.match(r"^([01]\\d|2[0-3]):([0-5]\\d)$", schedule_time): + if not re.match(r"^([01]\d|2[0-3]):([0-5]\d)$", schedule_time): return jsonify({"error": "时间格式错误,应为 HH:MM"}), 400 if schedule_browse_type is not None: diff --git a/routes/admin_api/users_api.py b/routes/admin_api/users_api.py index 8357d43..5af3484 100644 --- a/routes/admin_api/users_api.py +++ b/routes/admin_api/users_api.py @@ -13,20 +13,52 @@ from services.state import safe_clear_user_logs, safe_remove_user_accounts # ==================== 用户管理/统计(管理员) ==================== +def _parse_optional_pagination(default_limit: int = 50, max_limit: int = 500) -> tuple[int | None, int]: + limit_raw = request.args.get("limit") + offset_raw = request.args.get("offset") + if (limit_raw is None) and (offset_raw is None): + return None, 0 + + try: + limit = int(limit_raw if limit_raw is not None else default_limit) + except (TypeError, ValueError): + limit = default_limit + limit = max(1, min(limit, max_limit)) + + try: + offset = int(offset_raw if offset_raw is not None else 0) + except (TypeError, ValueError): + offset = 0 + offset = max(0, offset) + return limit, offset + + @admin_api_bp.route("/users", methods=["GET"]) @admin_required def get_all_users(): """获取所有用户""" - users = database.get_all_users() - return jsonify(users) + limit, offset = _parse_optional_pagination() + if limit is None: + users = database.get_all_users() + return jsonify(users) + + users = database.get_all_users(limit=limit, offset=offset) + total = database.get_users_count() + return jsonify({"items": users, "total": total, "limit": limit, "offset": offset}) @admin_api_bp.route("/users/pending", methods=["GET"]) @admin_required def get_pending_users(): """获取待审核用户""" - users = database.get_pending_users() - return jsonify(users) + limit, offset = _parse_optional_pagination(default_limit=30, max_limit=200) + if limit is None: + users = database.get_pending_users() + return jsonify(users) + + users = database.get_pending_users(limit=limit, offset=offset) + total = database.get_users_count(status="pending") + return jsonify({"items": users, "total": total, "limit": limit, "offset": offset}) @admin_api_bp.route("/users//approve", methods=["POST"]) diff --git a/routes/api_accounts.py b/routes/api_accounts.py index 0c733d9..3040b3d 100644 --- a/routes/api_accounts.py +++ b/routes/api_accounts.py @@ -164,11 +164,13 @@ def update_account(account_id): """ UPDATE accounts SET password = ?, remember = ? - WHERE id = ? + WHERE id = ? AND user_id = ? """, - (encrypted_password, new_remember, account_id), + (encrypted_password, new_remember, account_id, user_id), ) conn.commit() + if cursor.rowcount <= 0: + return jsonify({"error": "账号不存在或无权限"}), 404 database.reset_account_login_status(account_id) logger.info(f"[账号更新] 用户 {user_id} 修改了账号 {account.username} 的密码,已重置登录状态") diff --git a/routes/api_schedules.py b/routes/api_schedules.py index b240928..659abb6 100644 --- a/routes/api_schedules.py +++ b/routes/api_schedules.py @@ -9,6 +9,7 @@ import time as time_mod import uuid import database +from app_logger import get_logger from flask import Blueprint, jsonify, request from flask_login import current_user, login_required from services.accounts_service import load_user_accounts @@ -17,6 +18,7 @@ from services.state import safe_get_account, safe_get_user_accounts_snapshot from services.tasks import submit_account_task api_schedules_bp = Blueprint("api_schedules", __name__) +logger = get_logger("app") _HHMM_RE = re.compile(r"^(\d{1,2}):(\d{2})$") @@ -391,4 +393,5 @@ def delete_schedule_logs_api(schedule_id): deleted = database.delete_schedule_logs(schedule_id, current_user.id) return jsonify({"success": True, "deleted": deleted}) except Exception as e: - return jsonify({"error": str(e)}), 500 + logger.warning(f"[schedules] 清空定时任务日志失败(schedule_id={schedule_id}): {e}") + return jsonify({"error": "清空日志失败,请稍后重试"}), 500 diff --git a/routes/api_screenshots.py b/routes/api_screenshots.py index 77531eb..7fa4978 100644 --- a/routes/api_screenshots.py +++ b/routes/api_screenshots.py @@ -8,6 +8,7 @@ from typing import Iterator import database from app_config import get_config +from app_logger import get_logger from app_security import is_safe_path from flask import Blueprint, jsonify, request, send_from_directory from flask_login import current_user, login_required @@ -28,33 +29,89 @@ except AttributeError: # Pillow<9 fallback _RESAMPLE_FILTER = Image.LANCZOS api_screenshots_bp = Blueprint("api_screenshots", __name__) +logger = get_logger("app") def _get_user_prefix(user_id: int) -> str: + return f"u{int(user_id)}" + + +def _get_username(user_id: int) -> str: user_info = database.get_user_by_id(user_id) - return user_info["username"] if user_info else f"user{user_id}" + return str(user_info.get("username") or "") if user_info else "" -def _is_user_screenshot(filename: str, username_prefix: str) -> bool: - return filename.startswith(username_prefix + "_") and filename.lower().endswith(_IMAGE_EXTENSIONS) +def _list_all_usernames() -> list[str]: + users = database.get_all_users() + result = [] + for row in users: + username = str(row.get("username") or "").strip() + if username: + result.append(username) + return result -def _iter_user_screenshot_entries(username_prefix: str) -> Iterator[os.DirEntry]: +def _resolve_user_owned_prefix( + filename: str, + *, + user_id: int, + username: str, + all_usernames: list[str] | None = None, +) -> str | None: + lower_name = filename.lower() + if not lower_name.endswith(_IMAGE_EXTENSIONS): + return None + + # 新版命名:u{user_id}_... + id_prefix = _get_user_prefix(user_id) + if filename.startswith(id_prefix + "_"): + return id_prefix + + # 兼容旧版命名:{username}_... + username = str(username or "").strip() + if not username: + return None + + if all_usernames is None: + all_usernames = _list_all_usernames() + + matched_usernames = [item for item in all_usernames if filename.startswith(item + "_")] + if not matched_usernames: + return None + + # 取“最长匹配用户名”,避免 foo 越权读取 foo_bar 的截图。 + max_len = max(len(item) for item in matched_usernames) + winners = [item for item in matched_usernames if len(item) == max_len] + if len(winners) != 1: + return None + if winners[0] != username: + return None + return winners[0] + + +def _iter_user_screenshot_entries(user_id: int, username: str, all_usernames: list[str]) -> Iterator[tuple[os.DirEntry, str]]: if not os.path.exists(SCREENSHOTS_DIR): return with os.scandir(SCREENSHOTS_DIR) as entries: for entry in entries: - if (not entry.is_file()) or (not _is_user_screenshot(entry.name, username_prefix)): + if not entry.is_file(): continue - yield entry + matched_prefix = _resolve_user_owned_prefix( + entry.name, + user_id=user_id, + username=username, + all_usernames=all_usernames, + ) + if not matched_prefix: + continue + yield entry, matched_prefix -def _build_display_name(filename: str) -> str: - base_name, ext = filename.rsplit(".", 1) - parts = base_name.split("_", 1) - if len(parts) > 1: - return f"{parts[1]}.{ext}" +def _build_display_name(filename: str, owner_prefix: str) -> str: + prefix = f"{owner_prefix}_" + if filename.startswith(prefix): + return filename[len(prefix) :] return filename @@ -126,11 +183,12 @@ def _parse_optional_pagination(default_limit: int = 24, *, max_limit: int = 100) def get_screenshots(): """获取当前用户的截图列表""" user_id = current_user.id - username_prefix = _get_user_prefix(user_id) + username = _get_username(user_id) try: screenshots = [] - for entry in _iter_user_screenshot_entries(username_prefix): + all_usernames = _list_all_usernames() + for entry, matched_prefix in _iter_user_screenshot_entries(user_id, username, all_usernames): filename = entry.name stat = entry.stat() created_time = datetime.fromtimestamp(stat.st_mtime, tz=BEIJING_TZ) @@ -138,7 +196,7 @@ def get_screenshots(): screenshots.append( { "filename": filename, - "display_name": _build_display_name(filename), + "display_name": _build_display_name(filename, matched_prefix), "size": stat.st_size, "created": created_time.strftime("%Y-%m-%d %H:%M:%S"), "_created_ts": stat.st_mtime, @@ -157,7 +215,8 @@ def get_screenshots(): return jsonify(screenshots) except Exception as e: - return jsonify({"error": str(e)}), 500 + logger.warning(f"[screenshots] 获取截图列表失败(user_id={user_id}): {e}") + return jsonify({"error": "获取截图列表失败"}), 500 @api_screenshots_bp.route("/screenshots/") @@ -165,9 +224,8 @@ def get_screenshots(): def serve_screenshot(filename): """提供原图文件访问""" user_id = current_user.id - username_prefix = _get_user_prefix(user_id) - - if not _is_user_screenshot(filename, username_prefix): + username = _get_username(user_id) + if not _resolve_user_owned_prefix(filename, user_id=user_id, username=username): return jsonify({"error": "无权访问"}), 403 if not is_safe_path(SCREENSHOTS_DIR, filename): @@ -181,9 +239,8 @@ def serve_screenshot(filename): def serve_screenshot_thumbnail(filename): """提供缩略图访问(失败时自动回退原图)""" user_id = current_user.id - username_prefix = _get_user_prefix(user_id) - - if not _is_user_screenshot(filename, username_prefix): + username = _get_username(user_id) + if not _resolve_user_owned_prefix(filename, user_id=user_id, username=username): return jsonify({"error": "无权访问"}), 403 if not is_safe_path(SCREENSHOTS_DIR, filename): @@ -209,9 +266,8 @@ def serve_screenshot_thumbnail(filename): def delete_screenshot(filename): """删除指定截图""" user_id = current_user.id - username_prefix = _get_user_prefix(user_id) - - if not _is_user_screenshot(filename, username_prefix): + username = _get_username(user_id) + if not _resolve_user_owned_prefix(filename, user_id=user_id, username=username): return jsonify({"error": "无权删除"}), 403 if not is_safe_path(SCREENSHOTS_DIR, filename): @@ -226,7 +282,8 @@ def delete_screenshot(filename): return jsonify({"success": True}) return jsonify({"error": "文件不存在"}), 404 except Exception as e: - return jsonify({"error": str(e)}), 500 + logger.warning(f"[screenshots] 删除截图失败(user_id={user_id}, filename={filename}): {e}") + return jsonify({"error": "删除截图失败"}), 500 @api_screenshots_bp.route("/api/screenshots/clear", methods=["POST"]) @@ -234,11 +291,12 @@ def delete_screenshot(filename): def clear_all_screenshots(): """清空当前用户的所有截图""" user_id = current_user.id - username_prefix = _get_user_prefix(user_id) + username = _get_username(user_id) try: deleted_count = 0 - for entry in _iter_user_screenshot_entries(username_prefix): + all_usernames = _list_all_usernames() + for entry, _ in _iter_user_screenshot_entries(user_id, username, all_usernames): os.remove(entry.path) _remove_thumbnail(entry.name) deleted_count += 1 @@ -246,4 +304,5 @@ def clear_all_screenshots(): log_to_client(f"清理了 {deleted_count} 个截图文件", user_id) return jsonify({"success": True, "deleted": deleted_count}) except Exception as e: - return jsonify({"error": str(e)}), 500 + logger.warning(f"[screenshots] 清空截图失败(user_id={user_id}): {e}") + return jsonify({"error": "清空截图失败"}), 500 diff --git a/services/kdocs_uploader.py b/services/kdocs_uploader.py index 4d25fc5..17c0f39 100644 --- a/services/kdocs_uploader.py +++ b/services/kdocs_uploader.py @@ -325,6 +325,10 @@ class KDocsUploader: if self._context is None: storage_state = getattr(config, "KDOCS_LOGIN_STATE_FILE", "data/kdocs_login_state.json") if use_storage_state and os.path.exists(storage_state): + try: + os.chmod(storage_state, 0o600) + except Exception: + pass self._context = self._browser.new_context(storage_state=storage_state) else: self._context = self._browser.new_context() @@ -837,8 +841,18 @@ class KDocsUploader: def _save_login_state(self) -> None: try: storage_state = getattr(config, "KDOCS_LOGIN_STATE_FILE", "data/kdocs_login_state.json") - os.makedirs(os.path.dirname(storage_state), exist_ok=True) + state_dir = os.path.dirname(storage_state) + if state_dir: + os.makedirs(state_dir, mode=0o700, exist_ok=True) + try: + os.chmod(state_dir, 0o700) + except Exception: + pass self._context.storage_state(path=storage_state) + try: + os.chmod(storage_state, 0o600) + except Exception: + pass except Exception as e: logger.warning(f"[KDocs] 保存登录态失败: {e}") diff --git a/services/screenshots.py b/services/screenshots.py index f0b2fbf..0c2717a 100644 --- a/services/screenshots.py +++ b/services/screenshots.py @@ -538,9 +538,8 @@ def take_screenshot_for_account( # 标记账号正在截图(防止重复提交截图任务) account.is_running = True - user_info = database.get_user_by_id(user_id) - username_prefix = user_info["username"] if user_info else f"user{user_id}" + username_prefix = f"u{int(user_id)}" def screenshot_task( browser_instance, user_id, account_id, account, browse_type, source, task_start_time, browse_result diff --git a/tests/test_security_hardening.py b/tests/test_security_hardening.py index bf32e09..21bfe05 100644 --- a/tests/test_security_hardening.py +++ b/tests/test_security_hardening.py @@ -3,7 +3,7 @@ import sys from pathlib import Path import pytest -from flask import Flask +from flask import Flask, session PROJECT_ROOT = Path(__file__).resolve().parents[1] if str(PROJECT_ROOT) not in sys.path: @@ -56,3 +56,24 @@ def test_get_encryption_key_refuses_regeneration_when_encrypted_data_exists(monk with pytest.raises(RuntimeError): crypto_utils.get_encryption_key() + + +def test_validate_csrf_token_requires_matching_session_token(): + app = Flask(__name__) + app.secret_key = "test-secret-key" + + with app.test_request_context("/", method="POST"): + session["csrf_token"] = "fixed-token" + assert app_security.validate_csrf_token("fixed-token") is True + assert app_security.validate_csrf_token("wrong-token") is False + assert app_security.validate_csrf_token("") is False + + +def test_decrypt_password_returns_empty_for_unreadable_encrypted_payload(monkeypatch): + class BrokenFernet: + def decrypt(self, *_args, **_kwargs): + raise ValueError("bad token") + + monkeypatch.setattr(crypto_utils, "_get_fernet", lambda: BrokenFernet()) + encrypted_like_value = "gAAAAABrokenPayload" + assert crypto_utils.decrypt_password(encrypted_like_value) == ""