「历史范围」原本放在设置页,却只对同步页的一个按钮起作用;而同步页最 显眼的主按钮「同步最新数据」写死 2 天,根本不看这个设置。选了「全部 历史」再点主按钮,表现就是应用无视你 —— 这正是反复出现的「只同步下来 两天」。 现在两条链路各管各的: * 自动同步:只在设置页配置(开关 + 频率),窗口固定 SYNC_DAYS,不再 读 history_days。措辞也改成「拉取最近几天」,不再暗示会补历史。 * 手动同步:范围就在同步页当场选,紧挨着用它的按钮,并标出每个范围的 实际代价(自上次同步 / 7 天 / … / 全部历史约 730 天、20-40 分钟)。 两个按钮合成一个「开始同步」,写死 2 天的那个删掉。 history_days 保留为「上次手动选的范围」,只有同步页读它;默认值改成 -1(自上次同步),对日常使用是正确的起点。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
"""
|
|
JWT signing/verification and the require_auth decorator used by route
|
|
blueprints. Accounts come from auth-hub (see services/auth_hub_client.py);
|
|
this module only handles this app's own session token.
|
|
"""
|
|
import datetime
|
|
|
|
import jwt
|
|
from flask import request, g, jsonify
|
|
from functools import wraps
|
|
|
|
from config import JWT_SECRET, JWT_EXPIRY_DAYS
|
|
from db import query_one
|
|
|
|
|
|
def sign_token(user_id: str) -> str:
|
|
now = datetime.datetime.utcnow()
|
|
payload = {
|
|
"sub": user_id,
|
|
"iat": now,
|
|
"exp": now + datetime.timedelta(days=JWT_EXPIRY_DAYS),
|
|
}
|
|
return jwt.encode(payload, JWT_SECRET, algorithm="HS256")
|
|
|
|
|
|
def verify_token(token: str) -> dict:
|
|
payload = jwt.decode(token, JWT_SECRET, algorithms=["HS256"])
|
|
return {"user_id": payload["sub"]}
|
|
|
|
|
|
def require_auth(f):
|
|
@wraps(f)
|
|
def wrapper(*args, **kwargs):
|
|
auth = request.headers.get("Authorization", "")
|
|
if not auth.startswith("Bearer "):
|
|
return jsonify({"error": "missing or malformed Authorization header"}), 401
|
|
token = auth[7:].strip()
|
|
try:
|
|
data = verify_token(token)
|
|
except jwt.ExpiredSignatureError:
|
|
return jsonify({"error": "token expired"}), 401
|
|
except jwt.InvalidTokenError:
|
|
return jsonify({"error": "invalid token"}), 401
|
|
g.user_id = data["user_id"]
|
|
# Ensure the user record still exists in the database (it may have been
|
|
# deleted by a database reset). If not, ask the user to re-login.
|
|
if not query_one("SELECT 1 FROM users WHERE id = ?", [g.user_id]):
|
|
return jsonify({"error": "user not found — please re-login"}), 401
|
|
return f(*args, **kwargs)
|
|
|
|
return wrapper
|