mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-26 13:07:14 +00:00
fix(nodes): Set Cert from Panel uses the node's own web cert for node inbounds
For an inbound deployed to a node, the button read the central panel's webCertFile/webKeyFile and inserted paths that don't exist on the node, crashing the node's Xray on startup. Add a token-accessible GET /panel/api/server/getWebCertFiles that returns a panel's own web cert/key paths, Remote.GetWebCertFiles to fetch it from a node, and GET /panel/api/nodes/webCert/:id to proxy it. setCertFromPanel now calls the node endpoint for a node-assigned inbound and the local settings otherwise, warning instead of inserting wrong paths on error/empty. Fixes #4854
This commit is contained in:
@@ -194,7 +194,7 @@ export default function InboundFormModal({
|
||||
setCertFromPanel,
|
||||
clearCertFiles,
|
||||
onSecurityChange,
|
||||
} = useSecurityActions({ form, setSaving, messageApi });
|
||||
} = useSecurityActions({ form, setSaving, messageApi, nodeId: typeof wNodeId === 'number' ? wNodeId : null });
|
||||
|
||||
const toggleExternalProxy = (on: boolean) => {
|
||||
if (on) {
|
||||
|
||||
@@ -13,13 +13,17 @@ interface UseSecurityActionsArgs {
|
||||
form: FormInstance<InboundFormValues>;
|
||||
setSaving: Dispatch<SetStateAction<boolean>>;
|
||||
messageApi: MessageInstance;
|
||||
// Node the inbound is deployed to (null = central panel). "Set Cert from
|
||||
// Panel" must read the node's own cert paths for a node-assigned inbound —
|
||||
// the central panel's paths don't exist on the node. See issue #4854.
|
||||
nodeId: number | null;
|
||||
}
|
||||
|
||||
// Server-side TLS / Reality key + certificate generation handlers for the
|
||||
// inbound modal's security tab. Each talks to a /panel server endpoint and
|
||||
// writes the result back into the form. Lifted out of InboundFormModal so
|
||||
// the modal body stays focused on orchestration.
|
||||
export function useSecurityActions({ form, setSaving, messageApi }: UseSecurityActionsArgs) {
|
||||
export function useSecurityActions({ form, setSaving, messageApi, nodeId }: UseSecurityActionsArgs) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const genRealityKeypair = async () => {
|
||||
@@ -112,22 +116,28 @@ export function useSecurityActions({ form, setSaving, messageApi }: UseSecurityA
|
||||
const setCertFromPanel = async (certName: number) => {
|
||||
setSaving(true);
|
||||
try {
|
||||
const msg = await HttpUtil.post('/panel/setting/all', undefined, { silent: true });
|
||||
if (msg?.success) {
|
||||
const obj = msg.obj as { webCertFile?: string; webKeyFile?: string };
|
||||
if (!obj.webCertFile && !obj.webKeyFile) {
|
||||
messageApi.warning(t('pages.inbounds.setDefaultCertEmpty'));
|
||||
return;
|
||||
}
|
||||
form.setFieldValue(
|
||||
['streamSettings', 'tlsSettings', 'certificates', certName, 'certificateFile'],
|
||||
obj.webCertFile ?? '',
|
||||
);
|
||||
form.setFieldValue(
|
||||
['streamSettings', 'tlsSettings', 'certificates', certName, 'keyFile'],
|
||||
obj.webKeyFile ?? '',
|
||||
);
|
||||
// Node-assigned inbounds run on the node, so their cert files must be the
|
||||
// node's own paths (fetched through the central panel), not this panel's.
|
||||
const msg = typeof nodeId === 'number'
|
||||
? await HttpUtil.get(`/panel/api/nodes/webCert/${nodeId}`, undefined, { silent: true })
|
||||
: await HttpUtil.post('/panel/setting/all', undefined, { silent: true });
|
||||
if (!msg?.success) {
|
||||
messageApi.warning(msg?.msg || t('pages.inbounds.setDefaultCertEmpty'));
|
||||
return;
|
||||
}
|
||||
const obj = msg.obj as { webCertFile?: string; webKeyFile?: string };
|
||||
if (!obj?.webCertFile && !obj?.webKeyFile) {
|
||||
messageApi.warning(t('pages.inbounds.setDefaultCertEmpty'));
|
||||
return;
|
||||
}
|
||||
form.setFieldValue(
|
||||
['streamSettings', 'tlsSettings', 'certificates', certName, 'certificateFile'],
|
||||
obj.webCertFile ?? '',
|
||||
);
|
||||
form.setFieldValue(
|
||||
['streamSettings', 'tlsSettings', 'certificates', certName, 'keyFile'],
|
||||
obj.webKeyFile ?? '',
|
||||
);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user