This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new d2a8992b fix: encode API path segments (#639)
d2a8992b is described below

commit d2a8992bc35687649354fc44912d9f221e55d029
Author: aias00 <[email protected]>
AuthorDate: Tue Jul 28 07:21:14 2026 -0700

    fix: encode API path segments (#639)
---
 web/src/api/cluster.test.ts | 29 +++++++++++++++++++++++++++++
 web/src/api/cluster.ts      |  6 ++++--
 web/src/api/message.test.ts | 10 ++++++++++
 web/src/api/message.ts      |  2 +-
 4 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/web/src/api/cluster.test.ts b/web/src/api/cluster.test.ts
index 7019f8b0..65eea44e 100644
--- a/web/src/api/cluster.test.ts
+++ b/web/src/api/cluster.test.ts
@@ -23,8 +23,10 @@ import {
   createNameServer,
   deleteK8sCert,
   deleteNameServer,
+  getCluster,
   listK8sCerts,
   renewK8sCert,
+  restartBroker,
   restartNameServer,
   restartProxy,
   updateK8sCert,
@@ -103,6 +105,33 @@ describe('K8s certificate API', () => {
     await expect(deleteK8sCert(cert.id)).resolves.toBeUndefined();
   });
 
+  it('encodes cluster path parameters', async () => {
+    const cluster = {
+      id: 'cloud/prod cluster:1',
+      name: 'prod',
+    };
+    mock.onGet('/clusters/cloud%2Fprod%20cluster%3A1').reply(200, {
+      code: 200,
+      data: cluster,
+    });
+
+    await expect(getCluster(cluster.id)).resolves.toEqual(cluster);
+  });
+
+  it('encodes broker restart path parameters', async () => {
+    mock
+      
.onPost('/clusters/cloud%2Fprod%20cluster%3A1/brokers/broker%2Fmain%3A10911/restart')
+      .reply(200, {
+        code: 200,
+        data: { success: true, message: 'restarted' },
+      });
+
+    await expect(restartBroker('cloud/prod cluster:1', 
'broker/main:10911')).resolves.toEqual({
+      success: true,
+      message: 'restarted',
+    });
+  });
+
   it('sends NameServer operation payloads to their endpoints', async () => {
     const target = { clusterId: 'cluster-1', addr: '127.0.0.1:9876' };
     const requests = [
diff --git a/web/src/api/cluster.ts b/web/src/api/cluster.ts
index b8de22fa..5ea7912d 100644
--- a/web/src/api/cluster.ts
+++ b/web/src/api/cluster.ts
@@ -17,6 +17,8 @@
 
 import client from './client';
 
+const pathSegment = (value: string): string => encodeURIComponent(value);
+
 // ─── Types ──────────────────────────────────────────────────────
 export interface ClusterInfo {
   id: string;
@@ -92,7 +94,7 @@ export async function listClusters() {
 }
 
 export async function getCluster(id: string) {
-  const res = await client.get<{ data: ClusterInfo }>(`/clusters/${id}`);
+  const res = await client.get<{ data: ClusterInfo 
}>(`/clusters/${pathSegment(id)}`);
   return res.data.data;
 }
 
@@ -102,7 +104,7 @@ export async function updateClusterConfig(data: { id: 
string } & Partial<Cluster
 
 export async function restartBroker(clusterId: string, brokerName: string) {
   const res = await client.post<{ data: { success: boolean; message: string } 
}>(
-    `/clusters/${clusterId}/brokers/${brokerName}/restart`,
+    
`/clusters/${pathSegment(clusterId)}/brokers/${pathSegment(brokerName)}/restart`,
   );
   return res.data.data;
 }
diff --git a/web/src/api/message.test.ts b/web/src/api/message.test.ts
index b435b4e8..75b8e697 100644
--- a/web/src/api/message.test.ts
+++ b/web/src/api/message.test.ts
@@ -110,4 +110,14 @@ describe('message API', () => {
 
     await expect(getMessageTrace('msg-1')).resolves.toEqual(trace);
   });
+
+  it('encodes message IDs before requesting trace records', async () => {
+    const trace = {
+      nodes: [],
+      consumerStatus: [],
+    };
+    mock.onGet('/messages/AC1E0A64%2F0000%202A9F%3A1/trace').reply(200, { 
code: 200, data: trace });
+
+    await expect(getMessageTrace('AC1E0A64/0000 
2A9F:1')).resolves.toEqual(trace);
+  });
 });
diff --git a/web/src/api/message.ts b/web/src/api/message.ts
index 39a0da03..0c879543 100644
--- a/web/src/api/message.ts
+++ b/web/src/api/message.ts
@@ -70,7 +70,7 @@ export async function queryMessages(params: MessageQuery) {
 }
 
 export async function getMessageTrace(msgId: string) {
-  const res = await client.get<{ data: TraceRecord 
}>(`/messages/${msgId}/trace`);
+  const res = await client.get<{ data: TraceRecord 
}>(`/messages/${encodeURIComponent(msgId)}/trace`);
   return res.data.data;
 }
 

Reply via email to