Skip to content

Commit 8f4cd75

Browse files
committed
fix(status): redact channel base URLs in status-all
1 parent 36e7f21 commit 8f4cd75

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

src/commands/status-all/channels.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,38 @@ describe("buildChannelsTable", () => {
122122
expect(detailRow?.Notes).toContain("credential not checked");
123123
});
124124

125+
it("redacts sensitive channel base URL material in account notes", async () => {
126+
mocks.listReadOnlyChannelPluginsForConfig.mockReturnValue([
127+
{
128+
...discordPlugin,
129+
config: {
130+
...discordPlugin.config,
131+
describeAccount: () => ({
132+
baseUrl:
133+
"https://oc-user:[email protected]/hooks?token=oc-token-raw&keep=1&api_key=oc-api-key-raw",
134+
}),
135+
},
136+
},
137+
]);
138+
mocks.resolveInspectedChannelAccount.mockResolvedValue({
139+
account: {
140+
tokenStatus: "available",
141+
tokenSource: "config",
142+
},
143+
enabled: true,
144+
configured: true,
145+
});
146+
147+
const table = await buildChannelsTable({ channels: { discord: { enabled: true } } });
148+
149+
const notes = table.details[0]?.rows[0]?.Notes;
150+
expect(notes).toContain("https://***:***@mm.example.com/hooks?token=***&keep=1&api_key=***");
151+
expect(notes).not.toContain("oc-user");
152+
expect(notes).not.toContain("oc-pass");
153+
expect(notes).not.toContain("oc-token-raw");
154+
expect(notes).not.toContain("oc-api-key-raw");
155+
});
156+
125157
it("shows configured official external channels when the plugin is missing", async () => {
126158
mocks.listReadOnlyChannelPluginsForConfig.mockReturnValue([]);
127159
mocks.missingOfficialExternalChannels.add("feishu");

src/commands/status-all/channels.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import fs from "node:fs";
55
import { asRecord } from "@openclaw/normalization-core/record-coerce";
66
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
7+
import { redactSensitiveUrlLikeString } from "../../../packages/net-policy/src/redact-sensitive-url.js";
78
import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js";
89
import { resolveInspectedChannelAccount } from "../../channels/account-inspection.js";
910
import { hasConfiguredUnavailableCredentialStatus } from "../../channels/account-snapshot-fields.js";
@@ -137,7 +138,7 @@ const buildAccountNotes = (params: {
137138
notes.push("secret unavailable in this command path");
138139
}
139140
if (snapshot.baseUrl) {
140-
notes.push(snapshot.baseUrl);
141+
notes.push(redactSensitiveUrlLikeString(snapshot.baseUrl));
141142
}
142143
if (snapshot.port != null) {
143144
notes.push(`port:${snapshot.port}`);

0 commit comments

Comments
 (0)