Skip to content

Feat/desktop passwordless auth - #160

Merged
Fridemn merged 4 commits into
mainfrom
feat/desktop-passwordless-auth
Jul 31, 2026
Merged

Feat/desktop passwordless auth#160
Fridemn merged 4 commits into
mainfrom
feat/desktop-passwordless-auth

Conversation

@Fridemn

@Fridemn Fridemn commented Jul 30, 2026

Copy link
Copy Markdown
Member

Desktop Dashboard 当前沿用浏览器端登录流程。首次安装时,用户无法方便地获知 AstrBot 自动生成的初始密码,导致进入 Desktop 后仍可能被登录页阻塞。

此外,Dashboard 更新后 WebView 可能继续使用旧版入口缓存,使旧 JS 请求新版构建中已经删除的 SetupPage-*.js,最终显示动态模块加载错误。

本 PR 将 Desktop 调整为自动建立 JWT 会话,移除仅面向浏览器登录流程的页面和账户密码 UI,同时解决 Dashboard 更新后的旧资源缓存问题。AstrBot 后端鉴权机制仍然保留,并未改为无鉴权访问。

Summary / 改动概述

  • 新增 Desktop JWT 会话桥:
    • 从 AstrBot Dashboard 配置读取用户名和 JWT Secret。
    • 由 Rust Desktop 端生成短期 HS256 JWT。
    • Dashboard 启动后自动获取并保存会话,无需用户输入密码。
  • 移除 Desktop Dashboard 登录相关 UI:
    • 删除 /auth/login/auth/setup 路由。
    • 删除登录页、初始化账户页、账户密码修改弹窗及密码提示逻辑。
    • 删除相关表单 Schema、样式、多语言资源和不再使用的依赖。
  • 保留后端鉴权与必要的账户安全能力:
    • API 请求仍携带 Bearer Token。
    • 401 时清理失效会话,并由 Desktop 会话桥重新签发 JWT。
    • 保留 TOTP 配置和恢复接口。
  • 修复更新后的动态模块加载错误:
    • Desktop 每次导航到后端 Dashboard 时增加唯一 _desktop_boot 参数,避免 WebView 使用旧版 index.html
    • 添加路由级错误页,资源加载失败时可强制刷新当前文档。
  • 未修改 AstrBot Python 源码或 vendor 目录,所有能力均在 Desktop Rust 桥和独立 Dashboard 中实现。
  • 同步更新 Cargo.lockdashboard/pnpm-lock.yaml

Verification / 验证方式

  • Dashboard TypeScript 类型检查通过。
  • Dashboard 完整 Vitest:
    • 83 个测试文件通过。
    • 308 项测试通过。
  • Desktop JWT、导航缓存戳相关 Rust 单元测试通过。
  • Dashboard 路由、Desktop 自动会话及 401 会话处理回归测试通过。
  • 修改涉及的 TypeScript/TSX 文件通过 ESLint。
  • 修改涉及的 SCSS 文件通过 Stylelint。
  • cargo fmt --check 通过。
  • git diff --cached --check 通过。
  • Action 构建成功

Checklist / 检查清单

  • This change is not a breaking change. / 此改动不是破坏性变更。
  • I have verified the change locally (and provided logs/screenshots above). / 我已在本地验证并在上方提供验证结果。
  • Workflows are not changed. / 本 PR 未修改工作流。
  • If dependencies are updated, lockfiles are updated accordingly (src-tauri/Cargo.lock, dashboard/pnpm-lock.yaml). / 依赖变更已同步更新相关锁文件。
  • This PR does not include malicious code. / 此 PR 不包含恶意代码。

Summary by Sourcery

Introduce passwordless desktop authentication for AstrBot Dashboard and harden desktop navigation against stale frontend bundles.

New Features:

  • Add a desktop JWT session bridge that issues short-lived HS256 tokens from dashboard configuration and exposes them to the web UI via a Tauri command.
  • Gate the desktop dashboard UI behind an automatic desktop auth session initializer so users can access managed Desktop without entering credentials.
  • Provide a route-level error page that allows reloading the dashboard document when route loading fails.

Bug Fixes:

  • Ensure desktop navigation to the backend always includes a cache-busting parameter to avoid loading outdated index.html and removed dynamic modules.
  • Simplify unauthorized API handling so every 401 response expires the session without redirect loops.

Enhancements:

  • Remove browser-centric authentication flows, routes, forms, and account/password management UI from the dashboard when used in Desktop mode.
  • Streamline auth storage and compatibility code to only persist the token and username used by API requests.
  • Refine upgrade recovery handling to rely on version information from stats APIs and improve warning styling.
  • Adjust routing layouts to treat all dashboard routes as protected while still supporting chatbox in a blank layout.
  • Update dashboard bootstrap UX to show desktop auth progress and recovery actions, including retry on desktop auth failures.

Build:

  • Remove unused form and validation dependencies from the dashboard package.json and update lockfiles to match new dependency graph.

Tests:

  • Add unit tests for desktop JWT generation, navigation cache busting, and the desktop auth gate, and update existing tests to reflect the new auth and routing behavior.

@Fridemn
Fridemn requested a review from zouyonghe July 30, 2026 16:02

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • RouteErrorPage currently hardcodes English strings and bypasses the i18n system; consider wiring it into the existing translation keys so error messaging is localized and consistent with the rest of the dashboard.
  • DesktopAuthGate swallows the desktop auth failure reason and displays only a generic error; you could surface response.reason (or a mapped translation key) to help users diagnose why passwordless desktop auth failed before retrying.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- RouteErrorPage currently hardcodes English strings and bypasses the i18n system; consider wiring it into the existing translation keys so error messaging is localized and consistent with the rest of the dashboard.
- DesktopAuthGate swallows the desktop auth failure reason and displays only a generic error; you could surface `response.reason` (or a mapped translation key) to help users diagnose why passwordless desktop auth failed before retrying.

## Individual Comments

### Comment 1
<location path="dashboard/src/desktop/DesktopAuthGate.tsx" line_range="18" />
<code_context>
-  const setReturnUrl = useAuthStore((state) => state.setReturnUrl);
-  const returnUrl = `${location.pathname}${location.search}${location.hash}`;
-
-  useEffect(() => {
-    if (!hasToken) setReturnUrl(returnUrl);
-  }, [hasToken, returnUrl, setReturnUrl]);
</code_context>
<issue_to_address>
**suggestion:** Desktop auth failures are surfaced as a generic error without diagnostic detail.

In the current effect, any `bridge.getAuthSession()` failure (non-OK response or missing token/username) is reduced to `status = 'error'`, and the UI only shows `desktopAuthFailed` with a retry. Consider logging `response.reason` or the thrown error to `console.error` (or a central logger) before handling it, so desktop bridge or JWT issues can be diagnosed without additional instrumentation later.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

const [attempt, setAttempt] = useState(0);
const [status, setStatus] = useState<DesktopAuthStatus>('waiting');

useEffect(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Desktop auth failures are surfaced as a generic error without diagnostic detail.

In the current effect, any bridge.getAuthSession() failure (non-OK response or missing token/username) is reduced to status = 'error', and the UI only shows desktopAuthFailed with a retry. Consider logging response.reason or the thrown error to console.error (or a central logger) before handling it, so desktop bridge or JWT issues can be diagnosed without additional instrumentation later.

@Fridemn
Fridemn merged commit f94e375 into main Jul 31, 2026
5 checks passed
@Fridemn
Fridemn deleted the feat/desktop-passwordless-auth branch July 31, 2026 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant