Files
AstrBot/astrbot/dashboard/routes/auth.py
T
eason dd6bc1dcdb fix: add missing spaces in cron prompt and replace deprecated utcnow() (#6192)
1. Fix missing spaces in cron job wake prompt string concatenation.
   Python implicit string concatenation produced:
   "...scheduled taskProceed..." and "...conversation.After..."
   which sent garbled instructions to the LLM agent, causing unreliable
   cron job execution.

2. Replace deprecated datetime.utcnow() with
   datetime.now(datetime.timezone.utc) in JWT generation.
   utcnow() is deprecated since Python 3.12 and returns naive datetime
   which can cause incorrect token expiry on non-UTC systems.

Closes #6103
Closes #6165

Co-authored-by: easonysliu <easonysliu@tencent.com>
2026-03-14 20:52:00 +08:00

92 lines
3.1 KiB
Python

import asyncio
import datetime
import jwt
from quart import request
from astrbot import logger
from astrbot.core import DEMO_MODE
from .route import Response, Route, RouteContext
class AuthRoute(Route):
def __init__(self, context: RouteContext) -> None:
super().__init__(context)
self.routes = {
"/auth/login": ("POST", self.login),
"/auth/account/edit": ("POST", self.edit_account),
}
self.register_routes()
async def login(self):
username = self.config["dashboard"]["username"]
password = self.config["dashboard"]["password"]
post_data = await request.json
if post_data["username"] == username and post_data["password"] == password:
change_pwd_hint = False
if (
username == "astrbot"
and password == "77b90590a8945a7d36c963981a307dc9"
and not DEMO_MODE
):
change_pwd_hint = True
logger.warning("为了保证安全,请尽快修改默认密码。")
return (
Response()
.ok(
{
"token": self.generate_jwt(username),
"username": username,
"change_pwd_hint": change_pwd_hint,
},
)
.__dict__
)
await asyncio.sleep(3)
return Response().error("用户名或密码错误").__dict__
async def edit_account(self):
if DEMO_MODE:
return (
Response()
.error("You are not permitted to do this operation in demo mode")
.__dict__
)
password = self.config["dashboard"]["password"]
post_data = await request.json
if post_data["password"] != password:
return Response().error("原密码错误").__dict__
new_pwd = post_data.get("new_password", None)
new_username = post_data.get("new_username", None)
if not new_pwd and not new_username:
return Response().error("新用户名和新密码不能同时为空").__dict__
# Verify password confirmation
if new_pwd:
confirm_pwd = post_data.get("confirm_password", None)
if confirm_pwd != new_pwd:
return Response().error("两次输入的新密码不一致").__dict__
self.config["dashboard"]["password"] = new_pwd
if new_username:
self.config["dashboard"]["username"] = new_username
self.config.save_config()
return Response().ok(None, "修改成功").__dict__
def generate_jwt(self, username):
payload = {
"username": username,
"exp": datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=7),
}
jwt_token = self.config["dashboard"].get("jwt_secret", None)
if not jwt_token:
raise ValueError("JWT secret is not set in the cmd_config.")
token = jwt.encode(payload, jwt_token, algorithm="HS256")
return token