refactor(admin): удалить мёртвый updater/config-write API и его UI
Маршруты, операциями которых продукт не владеет, отвечали заглушкой "managed by orchestrator" или пустым списком: POST /hysteria2ChangeVersion GET /listRelease POST /config/updateHysteria2Config POST /config/importHysteria2Config POST /config/restartServer POST /config/uploadCertFile GET /config/hysteria2AcmePath (не имел потребителя вовсе) Они удалены, а не оставлены заглушками. Причины две. API-контракт не должен обещать updater, которого у продукта принципиально нет: маршрут, всегда возвращающий отказ, вводит в заблуждение. И это лишняя attack surface плюс технический мусор от прежней архитектуры. Вместе с маршрутами убраны мёртвые сервисы (StartHysteria2, StopHysteria2, RestartHysteria2, SetHysteria2Config, UpdateHysteria2Config, GetAuthHttpUrl, Hysteria2AcmePath), неиспользуемые типы и клиентские функции фронтенда. Отдельно - кнопки. "Перезапустить панель" и загрузка сертификатов обращались к заглушкам, то есть гарантированно возвращали ошибку. Кнопка, которая всегда падает, - не точка расширения на будущее, а дефект UX. Удалены вместе со строками i18n. Конфигурация Hysteria остаётся доступной панели на чтение и на выгрузку: getHysteria2Config и exportHysteria2Config.
This commit is contained in:
@@ -5,10 +5,13 @@ import {
|
||||
ConfigsDto,
|
||||
ConfigUpdateDto,
|
||||
ConfigVo,
|
||||
Hysteria2AcmePathVo,
|
||||
Hysteria2ServerConfig,
|
||||
} from "@/api/config/types";
|
||||
|
||||
// Серверный конфиг Hysteria доступен панели только на чтение и на выгрузку:
|
||||
// им владеет install-оркестратор. Клиентов записи, импорта, перезапуска и
|
||||
// загрузки сертификатов здесь нет — соответствующих маршрутов не существует.
|
||||
|
||||
export function getHysteria2ConfigApi(): AxiosPromise<Hysteria2ServerConfig> {
|
||||
return request({
|
||||
url: "/config/getHysteria2Config",
|
||||
@@ -16,16 +19,6 @@ export function getHysteria2ConfigApi(): AxiosPromise<Hysteria2ServerConfig> {
|
||||
});
|
||||
}
|
||||
|
||||
export function updateHysteria2ConfigApi(
|
||||
data: Hysteria2ServerConfig
|
||||
): AxiosPromise {
|
||||
return request({
|
||||
url: "/config/updateHysteria2Config",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
export function getConfigApi(data: ConfigDto): AxiosPromise<ConfigVo> {
|
||||
return request({
|
||||
url: "/config/getConfig",
|
||||
@@ -77,36 +70,3 @@ export function exportHysteria2ConfigApi(): AxiosPromise {
|
||||
});
|
||||
}
|
||||
|
||||
export function importHysteria2ConfigApi(data: FormData): AxiosPromise {
|
||||
return request({
|
||||
url: "/config/importHysteria2Config",
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
export function hysteria2AcmePathApi(): AxiosPromise<Hysteria2AcmePathVo> {
|
||||
return request({
|
||||
url: "/config/hysteria2AcmePath",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
export function restartServerApi(): AxiosPromise {
|
||||
return request({
|
||||
url: "/config/restartServer",
|
||||
method: "post",
|
||||
});
|
||||
}
|
||||
|
||||
export function uploadCertFileApi(data: FormData): AxiosPromise<string> {
|
||||
return request({
|
||||
url: "/config/uploadCertFile",
|
||||
method: "post",
|
||||
data,
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -340,8 +340,3 @@ export interface Tab {
|
||||
name: string;
|
||||
desc: string;
|
||||
}
|
||||
|
||||
export interface Hysteria2AcmePathVo {
|
||||
crtPath: string;
|
||||
keyPath: string;
|
||||
}
|
||||
|
||||
@@ -185,10 +185,6 @@ export default {
|
||||
hysteria2TrafficTime: "Hysteria2 Traffic Time",
|
||||
huiCrtPath: "HY2XS admin CRT File Path",
|
||||
huiKeyPath: "HY2XS admin KEY File Path",
|
||||
uploadCrtFile: "Upload CRT File",
|
||||
uploadKeyFile: "Upload KEY File",
|
||||
restartServer: "Restart Panel",
|
||||
restartTip: "Restarting, please refresh",
|
||||
useHysteria2Cert: "Use Hysteria2 cert",
|
||||
huiHttps: "Open https on the panel",
|
||||
resetTrafficCron: "Reset traffic schedule task",
|
||||
@@ -237,7 +233,6 @@ export default {
|
||||
addConfigItem: "Add Config Item",
|
||||
hysteria2Version: "Hysteria2 Version",
|
||||
hysteria2Running: "Hysteria2 Status",
|
||||
hysteria2ChangeVersion: "Change",
|
||||
addOutbound: "Add Outbound",
|
||||
extension: "Extension",
|
||||
listen: "Listen",
|
||||
|
||||
@@ -181,10 +181,6 @@ export default {
|
||||
hysteria2TrafficTime: "Период учёта трафика Hysteria2",
|
||||
huiCrtPath: "Путь к CRT HY2XS admin",
|
||||
huiKeyPath: "Путь к KEY HY2XS admin",
|
||||
uploadCrtFile: "Загрузить CRT",
|
||||
uploadKeyFile: "Загрузить KEY",
|
||||
restartServer: "Перезапустить панель",
|
||||
restartTip: "Перезапуск, обновите страницу",
|
||||
useHysteria2Cert: "Использовать сертификат Hysteria2",
|
||||
huiHttps: "Включить HTTPS панели",
|
||||
resetTrafficCron: "Расписание сброса трафика",
|
||||
@@ -233,7 +229,6 @@ export default {
|
||||
addConfigItem: "Добавить параметр",
|
||||
hysteria2Version: "Версия Hysteria2",
|
||||
hysteria2Running: "Статус Hysteria2",
|
||||
hysteria2ChangeVersion: "Сменить",
|
||||
addOutbound: "Добавить outbound",
|
||||
extension: "Расширение",
|
||||
listen: "Адрес прослушивания",
|
||||
|
||||
@@ -7,14 +7,6 @@
|
||||
{{ $t("common.save") }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleRestartServer">
|
||||
<template #icon>
|
||||
<i-ep-refreshRight />
|
||||
</template>
|
||||
{{ $t("config.restartServer") }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-model:file-list="fileList"
|
||||
@@ -166,7 +158,6 @@ import {
|
||||
exportConfigApi,
|
||||
importConfigApi,
|
||||
listConfigApi,
|
||||
restartServerApi,
|
||||
updateConfigsApi,
|
||||
} from "@/api/config";
|
||||
import { ConfigsUpdateDto } from "@/api/config/types";
|
||||
@@ -352,21 +343,6 @@ const handleExport = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleRestartServer = async () => {
|
||||
try {
|
||||
ElMessageBox.confirm(t("config.restartTip"), t("common.warning"), {
|
||||
confirmButtonText: t("common.confirm"),
|
||||
cancelButtonText: t("common.cancel"),
|
||||
type: "warning",
|
||||
}).then(() => {
|
||||
restartServerApi();
|
||||
ElMessage.success(t("config.restartTip"));
|
||||
});
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
setConfig();
|
||||
if (route.query.focus === "huiHttps") {
|
||||
|
||||
@@ -95,28 +95,9 @@
|
||||
<el-form-item label="cert" prop="tls.cert">
|
||||
<el-input
|
||||
v-model="dataForm.tls.cert"
|
||||
style="width: 50%"
|
||||
style="width: 100%"
|
||||
clearable
|
||||
/>
|
||||
<el-upload
|
||||
style="height: 32px"
|
||||
ref="uploadCrtFile"
|
||||
action=""
|
||||
:file-list="crtFileList"
|
||||
:http-request="uploadCertFile"
|
||||
accept=".crt"
|
||||
:before-upload="
|
||||
() => {
|
||||
crtFileList = [];
|
||||
}
|
||||
"
|
||||
:show-file-list="false"
|
||||
:limit="1"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button>{{ t("config.uploadCrtFile") }}</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
@@ -127,28 +108,9 @@
|
||||
<el-form-item label="key" prop="tls.key">
|
||||
<el-input
|
||||
v-model="dataForm.tls.key"
|
||||
style="width: 50%"
|
||||
style="width: 100%"
|
||||
clearable
|
||||
/>
|
||||
<el-upload
|
||||
style="height: 32px"
|
||||
ref="uploadKeyFile"
|
||||
action=""
|
||||
:file-list="keyFileList"
|
||||
:http-request="uploadCertFile"
|
||||
accept=".key"
|
||||
:before-upload="
|
||||
() => {
|
||||
keyFileList = [];
|
||||
}
|
||||
"
|
||||
:show-file-list="false"
|
||||
:limit="1"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button>{{ t("config.uploadKeyFile") }}</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
@@ -1104,13 +1066,10 @@ import {
|
||||
exportHysteria2ConfigApi,
|
||||
getHysteria2ConfigApi,
|
||||
listConfigApi,
|
||||
uploadCertFileApi,
|
||||
} from "@/api/config";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { assignWith, deepCopy } from "@/utils/copy";
|
||||
import { UploadRequestOptions } from "element-plus";
|
||||
import { dashboardSummaryApi } from "@/api/dashboard";
|
||||
import { UploadUserFile } from "element-plus";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -1181,8 +1140,6 @@ const state = reactive({
|
||||
version: "",
|
||||
running: false,
|
||||
},
|
||||
crtFileList: [] as UploadUserFile[],
|
||||
keyFileList: [] as UploadUserFile[],
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -1203,8 +1160,6 @@ const {
|
||||
outbounds,
|
||||
masquerade,
|
||||
hysteria2Monitor,
|
||||
crtFileList,
|
||||
keyFileList,
|
||||
} = toRefs(state);
|
||||
|
||||
const handleExport = async () => {
|
||||
@@ -1287,33 +1242,6 @@ const setHysteria2Monitor = async () => {
|
||||
state.hysteria2Monitor.running = data.hysteria.running;
|
||||
};
|
||||
|
||||
const uploadCertFile = async (params: UploadRequestOptions) => {
|
||||
try {
|
||||
if (!state.dataForm.tls) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!params.file.name.endsWith(".crt") &&
|
||||
!params.file.name.endsWith(".key")
|
||||
) {
|
||||
ElMessage.error(t("common.fileFormatUnsupported"));
|
||||
}
|
||||
if (params.file.size > 1024 * 1024) {
|
||||
ElMessage.error(t("common.fileTooLarge"));
|
||||
}
|
||||
let formData = new FormData();
|
||||
formData.append("file", params.file);
|
||||
const { data } = await uploadCertFileApi(formData);
|
||||
if (params.file.name.endsWith(".crt")) {
|
||||
state.dataForm.tls.cert = data;
|
||||
} else if (params.file.name.endsWith(".key")) {
|
||||
state.dataForm.tls.key = data;
|
||||
}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
setConfig();
|
||||
setHysteria2Monitor();
|
||||
|
||||
Reference in New Issue
Block a user