feat: 增加 OneBot 服务 Token 为空时的安全提醒 (#2648)

This commit is contained in:
Soulter
2025-09-07 00:51:46 +08:00
committed by GitHub
parent b31b520c7c
commit 905eef48e3
3 changed files with 101 additions and 14 deletions
@@ -29,6 +29,11 @@
"title": "ID Conflict Warning",
"message": "Detected duplicate ID \"{id}\". Please use a new ID.",
"confirm": "OK"
},
"securityWarning": {
"title": "Security Warning",
"aiocqhttpTokenMissing": "To enhance connection security, it is strongly recommended to set ws_reverse_token. Not setting a token may lead to security risks.",
"learnMore": "Learn More"
}
},
"messages": {
@@ -29,6 +29,11 @@
"title": "ID 冲突警告",
"message": "检测到 ID \"{id}\" 重复。请使用一个新的 ID。",
"confirm": "好的"
},
"securityWarning": {
"title": "安全提醒",
"aiocqhttpTokenMissing": "为了增强连接安全性,强烈建议您设置 ws_reverse_token。未设置 Token 可能导致安全风险。",
"learnMore": "了解更多"
}
},
"messages": {
+91 -14
View File
@@ -168,6 +168,28 @@
</v-card-actions>
</v-card>
</v-dialog>
<!-- 安全警告对话框 -->
<v-dialog v-model="showOneBotEmptyTokenWarnDialog" max-width="600" persistent>
<v-card>
<v-card-title>
{{ tm('dialog.securityWarning.title') }}
</v-card-title>
<v-card-text class="py-4">
<p>{{ tm('dialog.securityWarning.aiocqhttpTokenMissing') }}</p>
<span><a href="https://docs.astrbot.app/deploy/platform/aiocqhttp/napcat.html#%E9%99%84%E5%BD%95-%E5%A2%9E%E5%BC%BA%E8%BF%9E%E6%8E%A5%E5%AE%89%E5%85%A8%E6%80%A7" target="_blank">{{ tm('dialog.securityWarning.learnMore') }}</a></span>
</v-card-text>
<v-card-actions class="px-4 pb-4">
<v-spacer></v-spacer>
<v-btn color="error" @click="handleOneBotEmptyTokenWarningDismiss(true)">
无视警告并继续创建
</v-btn>
<v-btn color="primary" @click="handleOneBotEmptyTokenWarningDismiss(false)">
重新修改
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
@@ -234,17 +256,27 @@ export default {
conflictId: '',
idConflictResolve: null,
// OneBot Empty Token Warning #2639
showOneBotEmptyTokenWarnDialog: false,
oneBotEmptyTokenWarningResolve: null,
store: useCommonStore()
}
},
watch: {
showIdConflictDialog(newValue) {
// 当对话框关闭时,如果 Promise 还在等待,则拒绝它以防止内存泄漏
if (!newValue && this.idConflictResolve) {
this.idConflictResolve(false);
this.idConflictResolve = null;
}
},
showOneBotEmptyTokenWarnDialog(newValue) {
if (!newValue && this.oneBotEmptyTokenWarningResolve) {
this.oneBotEmptyTokenWarningResolve(true);
this.oneBotEmptyTokenWarningResolve = null;
}
}
},
@@ -353,24 +385,39 @@ export default {
newPlatform() {
this.loading = true;
if (this.updatingMode) {
axios.post('/api/config/platform/update', {
id: this.newSelectedPlatformName,
config: this.newSelectedPlatformConfig
}).then((res) => {
this.loading = false;
this.showPlatformCfg = false;
this.getConfig();
this.showSuccess(res.data.message || this.messages.updateSuccess);
}).catch((err) => {
this.loading = false;
this.showError(err.response?.data?.message || err.message);
});
this.updatingMode = false;
if (this.newSelectedPlatformConfig.type === 'aiocqhttp') {
const token = this.newSelectedPlatformConfig.ws_reverse_token;
if (!token || token.trim() === '') {
this.showOneBotEmptyTokenWarning().then((continueWithWarning) => {
if (continueWithWarning) {
this.updatePlatform();
}
});
return;
}
}
this.updatePlatform();
} else {
this.savePlatform();
}
},
updatePlatform() {
axios.post('/api/config/platform/update', {
id: this.newSelectedPlatformName,
config: this.newSelectedPlatformConfig
}).then((res) => {
this.loading = false;
this.showPlatformCfg = false;
this.getConfig();
this.showSuccess(res.data.message || this.messages.updateSuccess);
}).catch((err) => {
this.loading = false;
this.showError(err.response?.data?.message || err.message);
});
this.updatingMode = false;
},
async savePlatform() {
// 检查 ID 是否已存在
const existingPlatform = this.config_data.platform?.find(p => p.id === this.newSelectedPlatformConfig.id);
@@ -382,6 +429,17 @@ export default {
}
}
// 检查 aiocqhttp 适配器的安全设置
if (this.newSelectedPlatformConfig.type === 'aiocqhttp') {
const token = this.newSelectedPlatformConfig.ws_reverse_token;
if (!token || token.trim() === '') {
const continueWithWarning = await this.showOneBotEmptyTokenWarning();
if (!continueWithWarning) {
return;
}
}
}
try {
const res = await axios.post('/api/config/platform/new', this.newSelectedPlatformConfig);
this.loading = false;
@@ -409,6 +467,25 @@ export default {
this.showIdConflictDialog = false;
},
showOneBotEmptyTokenWarning() {
this.showOneBotEmptyTokenWarnDialog = true;
return new Promise((resolve) => {
this.oneBotEmptyTokenWarningResolve = resolve;
});
},
handleOneBotEmptyTokenWarningDismiss(continueWithWarning) {
this.showOneBotEmptyTokenWarnDialog = false;
if (this.oneBotEmptyTokenWarningResolve) {
this.oneBotEmptyTokenWarningResolve(continueWithWarning);
this.oneBotEmptyTokenWarningResolve = null;
}
if (!continueWithWarning) {
this.loading = false;
}
},
deletePlatform(platform) {
if (confirm(`${this.messages.deleteConfirm} ${platform.id}?`)) {
axios.post('/api/config/platform/delete', { id: platform.id }).then((res) => {