feat: supports one-time-token login and logout from webui#8589
Conversation
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- Instead of using
// @ts-ignoreinsyncReturnUrl, consider definingreturnUrlwith a proper type on the auth store so the component can assign to it without suppressing type checking. - The error-handling behavior for
loginandloginWithTemporaryTokendiffers (customvalidateStatusvs default Axios behavior), which may lead to inconsistent error messages at the UI layer; it would be cleaner to align their status validation and error shaping. - The
/api/auth/setup-statuscall is made directly fromAuthLogin.vue; consider moving this into a store or shared composable so that login-related API concerns remain centralized and easier to reuse.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Instead of using `// @ts-ignore` in `syncReturnUrl`, consider defining `returnUrl` with a proper type on the auth store so the component can assign to it without suppressing type checking.
- The error-handling behavior for `login` and `loginWithTemporaryToken` differs (custom `validateStatus` vs default Axios behavior), which may lead to inconsistent error messages at the UI layer; it would be cleaner to align their status validation and error shaping.
- The `/api/auth/setup-status` call is made directly from `AuthLogin.vue`; consider moving this into a store or shared composable so that login-related API concerns remain centralized and easier to reuse.
## Individual Comments
### Comment 1
<location path="dashboard/src/stores/auth.ts" line_range="83-74" />
<code_context>
+ return Promise.reject(error);
+ }
+ },
+ async loginWithTemporaryToken(token: string): Promise<void> {
+ try {
+ const res = await axios.post("/api/auth/login", {
+ login_type: "temporary_token",
+ temporary_token: token,
+ });
+
+ if (res.data.status === "error") {
return Promise.reject(res.data.message);
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Align temporary token login error handling with password login to surface API error messages reliably.
Because `loginWithTemporaryToken` relies on Axios’ default `validateStatus`, 4xx responses (like the 401 for invalid tokens) throw before you can read `res.data`, so the UI only sees a generic AxiosError instead of the backend message.
To match the main `login` behavior and surface the server error string, either:
- Override `validateStatus` so 401 responses pass through and you can `Promise.reject(res.data.message)`, or
- In `catch`, map `error.response.data.message` to the rejected error.
This keeps temporary token failures consistent with regular login errors from a UX standpoint.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| return "totp_required"; | ||
| } | ||
|
|
||
| if (res.data.status === "error") { |
There was a problem hiding this comment.
issue (bug_risk): Align temporary token login error handling with password login to surface API error messages reliably.
Because loginWithTemporaryToken relies on Axios’ default validateStatus, 4xx responses (like the 401 for invalid tokens) throw before you can read res.data, so the UI only sees a generic AxiosError instead of the backend message.
To match the main login behavior and surface the server error string, either:
- Override
validateStatusso 401 responses pass through and you canPromise.reject(res.data.message), or - In
catch, maperror.response.data.messageto the rejected error.
This keeps temporary token failures consistent with regular login errors from a UX standpoint.
There was a problem hiding this comment.
Code Review
This pull request introduces a temporary login token feature for the AstrBot dashboard, allowing users to log in using a token printed in the startup logs (enabled via the --print-login-token CLI flag). This includes backend support for hashing, verifying, and issuing shorter-lived JWTs for temporary token sessions, as well as frontend UI updates to support the temporary token login flow, translation updates, and documentation. A review comment points out a usability issue where users logged in via a temporary token cannot reset their password because the account edit endpoint still requires verifying the original password. It is recommended to add a claim to the JWT indicating a temporary session and bypass the original password check in this scenario.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| return await self._create_login_response( | ||
| username, | ||
| storage_upgraded, | ||
| password, | ||
| jwt_max_age=DASHBOARD_TEMPORARY_LOGIN_JWT_MAX_AGE, | ||
| ) |
There was a problem hiding this comment.
⚠️ Password Reset Usability Trap when Logged in via Temporary Token
When a user logs in using a temporary token (typically to recover access after forgetting their password), they are issued a standard JWT. However, if they attempt to reset or update their password via the WebUI (which calls the /api/auth/account/edit endpoint), the request will fail because edit_account strictly requires the original password to be verified:
if not verify_dashboard_password(password, req_password):
return Response().error("原密码错误").__dict__Since the user logged in via the temporary token precisely because they do not know or want to bypass the original password, they are trapped and cannot set a new password through the UI.
Suggested Solution:
- Add an
is_temporary: bool = Falseclaim to the JWT payload when generated via temporary token login. - Propagate this claim to
g.is_temporaryin the authentication middleware (server.py). - In
edit_account, bypass the original password verification ifgetattr(g, "is_temporary", False)isTrue.
Modifications / 改动点
Screenshots or Test Results / 运行截图或测试结果
Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by Sourcery
Add support for logging into the dashboard with a one-time temporary token alongside existing username/password and TOTP flows.
New Features:
Enhancements:
Documentation:
Tests: