mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 13:40:45 +00:00
手表端 - 功能页从 10 个杂项精简到 7 个(屏幕/鼠标/媒体/文件/电脑/语音/电源) - 删掉:游戏封锁、待办、掷骰子、抽奖、壁纸、显示器开关、定时关机、 剪贴板历史、性能/磁盘/电量、文件夹浏览、教室限制等 - 改成显式列按钮,不再把电脑端所有功能组无脑铺到表盘 - 远程鼠标控制重做:滑动区 + 左键/滚轮/右键三按钮 滚轮点按=中键、上下滑=滚动 - 新增视频/音乐播放器(手表本地播放):进度拖动、左右滑快进退10秒、 点画面播放暂停、上一/下一、播完自动下一首 电脑端 - 新增 kill_all(结束所有进程),白名单保护系统关键进程和自身 - 新增 media_list / media_pull(播放器数据源) 安全边界:只允许媒体目录,用 relative_to 判断,防同前缀兄弟目录绕过 中转站 - known_devices 从 ID 集合改成「设备ID -> 配对码」映射 - 修复:管理员改码后关机超过 6 小时,改码会被超时清理冲掉 - 老格式 state 文件平滑升级
117 lines
3.9 KiB
Python
117 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
r'''走 Halo 的「邮箱找回密码」流程。
|
|
|
|
== 流程长什么样 ==
|
|
|
|
Halo 2.x 的重置密码分两步:
|
|
|
|
1. POST /password/restore/email {"email": "..."}
|
|
-> 服务器往这个邮箱发一个验证码(6 位数字)
|
|
|
|
2. POST /password/restore/email/verify {"email": "...", "code": "..."}
|
|
-> 校验验证码
|
|
|
|
3. PUT /password/restore {"password": "新密码"}
|
|
-> 用上一步换来的临时凭据改密码
|
|
|
|
**⚠ 但前提是 Halo 配了 SMTP** —— 没配的话邮件根本发不出去,
|
|
用户等半天收不到码,白折腾。
|
|
|
|
所以这个脚本**先查 SMTP 配置**,再决定要不要发。
|
|
|
|
== 为什么不用令牌 ==
|
|
|
|
用户先提邮箱这个方案,就按他的来。但两个方案其实可以并行:
|
|
* 邮箱重置:能改密码 → 然后我用新密码登录
|
|
* 个人令牌:不用改密码,更安全
|
|
|
|
**改密码有个副作用**:用户自己也得记住新密码。
|
|
所以我会把新密码**明确告诉用户**。
|
|
|
|
== 关于验证码 ==
|
|
|
|
用户会把验证码发给我。验证码有时效(Halo 默认 10 分钟),
|
|
所以拿到之后要**立刻**用。
|
|
'''
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(ROOT / "_build"))
|
|
from lssh import run # noqa: E402
|
|
|
|
EMAIL = "3235109770@qq.com"
|
|
|
|
|
|
def main() -> int:
|
|
print("=" * 62)
|
|
print(" Halo 邮箱找回密码 —— 先确认能不能发邮件")
|
|
print("=" * 62)
|
|
print()
|
|
|
|
print("── 1. 重置接口存在吗 ──")
|
|
out = run(r'''
|
|
BASE=http://127.0.0.1:3001
|
|
for ep in \
|
|
"/password/restore/email" \
|
|
"/apis/api.halo.run/v1alpha1/password/restore/email" \
|
|
"/apis/uc.api.auth.halo.run/v1alpha1/password/restore/email" \
|
|
"/apis/api.console.halo.run/v1alpha1/indices/-/users" \
|
|
; do
|
|
printf " %-64s " "$ep"
|
|
curl -s -o /dev/null -w "%{http_code}\n" --max-time 8 "$BASE$ep"
|
|
done
|
|
|
|
echo
|
|
echo "── 2. 探测一下 POST 的形状(不发真请求,只看方法是否允许)──"
|
|
curl -s -o /dev/null -w " POST /password/restore/email -> %{http_code}\n" \
|
|
--max-time 10 -X POST "http://127.0.0.1:3001/password/restore/email" \
|
|
-H "Content-Type: application/json" -d '{}'
|
|
|
|
echo
|
|
echo "── 3. Halo 的 SMTP 配了吗(数据库里找)──"
|
|
sudo docker exec halo sh -c "
|
|
find /root/.halo2 -name '*.mv.db' -o -name '*.db' 2>/dev/null | head -3
|
|
" 2>/dev/null | sed 's/^/ /'
|
|
|
|
echo " 从设置接口看(需要登录,先看看会不会泄露结构):"
|
|
curl -s --max-time 8 "http://127.0.0.1:3001/apis/api.halo.run/v1alpha1/configmaps" | head -c 200
|
|
echo
|
|
|
|
echo
|
|
echo "── 4. 邮件相关的日志(有没有发信记录/报错)──"
|
|
sudo docker logs halo 2>&1 | grep -iE "mail|smtp|email|JavaMail" | tail -10 | sed 's/^/ /' || echo " (日志里没提邮件)"
|
|
|
|
echo
|
|
echo "── 5. 用户的邮箱地址(确认收件人)──"
|
|
curl -s --max-time 8 "http://127.0.0.1:3001/apis/api.halo.run/v1alpha1/users" | head -c 300
|
|
echo
|
|
''', timeout=300, quiet=True)
|
|
print(out[1] if isinstance(out, tuple) else out)
|
|
|
|
print()
|
|
print("── 6. 试发一次(如果接口在)──")
|
|
out = run(r'''
|
|
curl -s -w "\n HTTP %{http_code}\n" --max-time 20 \
|
|
-X POST "http://127.0.0.1:3001/password/restore/email" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"__EMAIL__"}' 2>&1 | head -20
|
|
'''.replace("__EMAIL__", EMAIL), timeout=200, quiet=True)
|
|
print(out[1] if isinstance(out, tuple) else out)
|
|
|
|
print()
|
|
print("── 7. 发完之后看日志(有没有真发出去)──")
|
|
out = run(r'''
|
|
sleep 3
|
|
sudo docker logs --tail 40 halo 2>&1 | grep -iE "mail|smtp|email|restore|code|error|exception" | tail -15 | sed 's/^/ /' || echo " (没有相关日志)"
|
|
''', timeout=200, quiet=True)
|
|
print(out[1] if isinstance(out, tuple) else out)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|