mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-08 22:10:13 +08:00
Compare commits
3 Commits
refactor-d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0be821afc6 | ||
|
|
dcc40ede1d | ||
|
|
adebd2958e |
62
README.md
62
README.md
@@ -75,6 +75,10 @@ AstrBot is an open-source all-in-one Agent chatbot platform that integrates with
|
||||
|
||||
### One-Click Deployment
|
||||
|
||||
> [!NOTE]
|
||||
> Requires [uv](https://docs.astral.sh/uv/) to be installed.
|
||||
> For macOS users: due to macOS security checks, the first run of the `astrbot` command may take longer (about 10-20s).
|
||||
|
||||
For users who want to quickly experience AstrBot, are familiar with command-line usage, and can install a `uv` environment on their own, we recommend the `uv` one-click deployment method ⚡️:
|
||||
|
||||
```bash
|
||||
@@ -83,20 +87,17 @@ astrbot init # Only execute this command for the first time to initialize the en
|
||||
astrbot run
|
||||
```
|
||||
|
||||
> Requires [uv](https://docs.astral.sh/uv/) to be installed.
|
||||
> AstrBot requires Python 3.12 or later. The `--python 3.12` option ensures that `uv` creates the tool environment with Python 3.12.
|
||||
|
||||
> [!NOTE]
|
||||
> For macOS users: due to macOS security checks, the first run of the `astrbot` command may take longer (about 10-20s).
|
||||
|
||||
Update `astrbot`:
|
||||
|
||||
```bash
|
||||
uv tool upgrade astrbot --python 3.12
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> AstrBot deployed via `uv` **does not support upgrading through the WebUI**. To update, please run the command above from the command line.
|
||||
### One-Click Cloud Deployment (RainYun)
|
||||
|
||||
For users who want one-click deployment and do not want to manage servers themselves, we recommend RainYun's one-click cloud deployment service ☁️:
|
||||
|
||||
[](https://app.rainyun.com/apps/rca/store/5994?ref=NjU1ODg0)
|
||||
|
||||
### Docker Deployment
|
||||
|
||||
@@ -104,12 +105,6 @@ For users familiar with containers and looking for a more stable, production-rea
|
||||
|
||||
Please refer to the official documentation: [Deploy AstrBot with Docker](https://docs.astrbot.app/deploy/astrbot/docker.html#%E4%BD%BF%E7%94%A8-docker-%E9%83%A8%E7%BD%B2-astrbot).
|
||||
|
||||
### Deploy on RainYun
|
||||
|
||||
For users who want one-click deployment and do not want to manage servers themselves, we recommend RainYun's one-click cloud deployment service ☁️:
|
||||
|
||||
[](https://app.rainyun.com/apps/rca/store/5994?ref=NjU1ODg0)
|
||||
|
||||
### Desktop Application Deployment
|
||||
|
||||
For users who want to use AstrBot on desktop and mainly use ChatUI, we recommend AstrBot App.
|
||||
@@ -142,6 +137,18 @@ yay -S astrbot-git
|
||||
|
||||
If you need panel-based management or deeper customization, see [BT-Panel Deployment](https://docs.astrbot.app/deploy/astrbot/btpanel.html) for BT Panel app-store setup, [1Panel Deployment](https://docs.astrbot.app/deploy/astrbot/1panel.html) for 1Panel app-market deployment, [CasaOS Deployment](https://docs.astrbot.app/deploy/astrbot/casaos.html) for NAS/home-server visual deployment, and [Manual Deployment](https://docs.astrbot.app/deploy/astrbot/cli.html) for fully custom source-based installation with `uv`.
|
||||
|
||||
|
||||
## ❤️ Sponsors
|
||||
|
||||
Welcome to sponsor us via [Afdian](https://afdian.com/a/astrbot_team) or [contact us](mailto:community@astrbot.app).
|
||||
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://astrbot.app/#/sponsors">
|
||||
<img alt="sponsors" src="https://sponsors.astrbot.app/?v=1">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
## Supported Messaging Platforms
|
||||
|
||||
Connect AstrBot to your favorite chat platform.
|
||||
@@ -205,13 +212,6 @@ Connect AstrBot to your favorite chat platform.
|
||||
| Xiaomi MiMo TTS | Text-to-Speech Services |
|
||||
| Volcano Engine TTS | Text-to-Speech Services |
|
||||
|
||||
## ❤️ Sponsors
|
||||
|
||||
<p align="center">
|
||||
<img alt="sponsors" src="https://sponsors.astrbot.app/?v=1">
|
||||
</p>
|
||||
|
||||
|
||||
## ❤️ Contributing
|
||||
|
||||
Issues and Pull Requests are always welcome! Feel free to submit your changes to this project :)
|
||||
@@ -235,22 +235,7 @@ pre-commit install
|
||||
|
||||
### QQ Groups
|
||||
|
||||
- Group 1: 322154837 (Full)
|
||||
- Group 3: 630166526 (Full)
|
||||
- Group 4: 1077826412 (Full)
|
||||
- Group 5: 822130018 (Full)
|
||||
- Group 6: 753075035 (Full)
|
||||
- Group 7: 743746109 (Full)
|
||||
- Group 8: 1030353265 (Full)
|
||||
- Group 9: 1076659624 (Full)
|
||||
- Group 10: 1078079676 (Full)
|
||||
- Group 11: 704659519 (Full)
|
||||
- Group 12: 916228568 (Full)
|
||||
- Group 13: 1092185289
|
||||
- Group 14: 1103419483
|
||||
|
||||
- Developer Group(Chit-chat): 975206796
|
||||
- Developer Group(Formal): 1039761811
|
||||
We have 15+ chat groups, please see: [Community](https://docs.astrbot.app/community.html) for details.
|
||||
|
||||
### Discord Server
|
||||
|
||||
@@ -264,9 +249,10 @@ Special thanks to all Contributors and plugin developers for their contributions
|
||||
<img src="https://contrib.rocks/image?repo=AstrBotDevs/AstrBot&max=300&columns=15" />
|
||||
</a>
|
||||
|
||||
Additionally, the birth of this project would not have been possible without the help of the following open-source projects:
|
||||
Open Source Friends ❤️
|
||||
|
||||
- [NapNeko/NapCatQQ](https://github.com/NapNeko/NapCatQQ) - The amazing cat framework
|
||||
- [Mai-with-u/MaiBot](https://github.com/Mai-with-u/MaiBot) - The powerful "digital life" in your QQ!
|
||||
|
||||
## ⭐ Star History
|
||||
|
||||
|
||||
@@ -369,6 +369,12 @@ class AuthService:
|
||||
if not new_pwd and not new_username:
|
||||
return self.error("新用户名和新密码不能同时为空")
|
||||
|
||||
username_to_save = None
|
||||
if new_username is not None and new_username != "":
|
||||
if not isinstance(new_username, str) or len(new_username.strip()) < 3:
|
||||
return self.error("用户名长度至少3位")
|
||||
username_to_save = new_username.strip()
|
||||
|
||||
if new_pwd:
|
||||
if not isinstance(new_pwd, str):
|
||||
return self.error("新密码无效")
|
||||
@@ -384,8 +390,8 @@ class AuthService:
|
||||
await set_password_change_required(self.db, self.config, False)
|
||||
if is_totp_enabled(self.config):
|
||||
await revoke_user_trusted_devices(self.db)
|
||||
if new_username:
|
||||
self.config["dashboard"]["username"] = new_username
|
||||
if username_to_save:
|
||||
self.config["dashboard"]["username"] = username_to_save
|
||||
|
||||
self.config.save_config()
|
||||
|
||||
|
||||
@@ -1360,6 +1360,105 @@ async def test_generated_password_requires_password_change_until_changed(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("endpoint", "method"),
|
||||
[
|
||||
("/api/auth/account/edit", "post"),
|
||||
("/api/v1/auth/account", "patch"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("new_username", ["ab", " "])
|
||||
async def test_account_edit_rejects_invalid_username(
|
||||
app: FastAPIAppAdapter,
|
||||
core_lifecycle_td: AstrBotCoreLifecycle,
|
||||
endpoint: str,
|
||||
method: str,
|
||||
new_username: str,
|
||||
):
|
||||
original_dashboard_config = copy.deepcopy(
|
||||
core_lifecycle_td.astrbot_config["dashboard"]
|
||||
)
|
||||
test_client = app.test_client()
|
||||
current_username = core_lifecycle_td.astrbot_config["dashboard"]["username"]
|
||||
current_password = _resolve_dashboard_password(core_lifecycle_td)
|
||||
|
||||
try:
|
||||
login_response = await test_client.post(
|
||||
"/api/auth/login",
|
||||
json={"username": current_username, "password": current_password},
|
||||
)
|
||||
login_data = await login_response.get_json()
|
||||
assert login_data["status"] == "ok"
|
||||
headers = {"Authorization": f"Bearer {login_data['data']['token']}"}
|
||||
|
||||
payload = {
|
||||
"password": current_password,
|
||||
"new_password": "",
|
||||
"confirm_password": "",
|
||||
"new_username": new_username,
|
||||
}
|
||||
request = getattr(test_client, method)
|
||||
response = await request(endpoint, headers=headers, json=payload)
|
||||
data = await response.get_json()
|
||||
|
||||
assert data["status"] == "error"
|
||||
assert data["message"] == "用户名长度至少3位"
|
||||
assert (
|
||||
core_lifecycle_td.astrbot_config["dashboard"]["username"]
|
||||
== (original_dashboard_config["username"])
|
||||
)
|
||||
finally:
|
||||
await _restore_dashboard_password_state(
|
||||
core_lifecycle_td,
|
||||
original_dashboard_config,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_account_edit_trims_valid_username(
|
||||
app: FastAPIAppAdapter,
|
||||
core_lifecycle_td: AstrBotCoreLifecycle,
|
||||
):
|
||||
original_dashboard_config = copy.deepcopy(
|
||||
core_lifecycle_td.astrbot_config["dashboard"]
|
||||
)
|
||||
test_client = app.test_client()
|
||||
current_username = core_lifecycle_td.astrbot_config["dashboard"]["username"]
|
||||
current_password = _resolve_dashboard_password(core_lifecycle_td)
|
||||
|
||||
try:
|
||||
login_response = await test_client.post(
|
||||
"/api/auth/login",
|
||||
json={"username": current_username, "password": current_password},
|
||||
)
|
||||
login_data = await login_response.get_json()
|
||||
assert login_data["status"] == "ok"
|
||||
headers = {"Authorization": f"Bearer {login_data['data']['token']}"}
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/auth/account/edit",
|
||||
headers=headers,
|
||||
json={
|
||||
"password": current_password,
|
||||
"new_password": "",
|
||||
"confirm_password": "",
|
||||
"new_username": " astrbot-admin ",
|
||||
},
|
||||
)
|
||||
data = await response.get_json()
|
||||
|
||||
assert data["status"] == "ok"
|
||||
assert core_lifecycle_td.astrbot_config["dashboard"]["username"] == (
|
||||
"astrbot-admin"
|
||||
)
|
||||
finally:
|
||||
await _restore_dashboard_password_state(
|
||||
core_lifecycle_td,
|
||||
original_dashboard_config,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_local_setup_can_skip_default_password_auth(
|
||||
app: FastAPIAppAdapter,
|
||||
|
||||
Reference in New Issue
Block a user