fix(status): show token previews
This commit is contained in:
parent
57dafec0ec
commit
318f59ec3e
@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026.1.10-4
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- CLI/Status: show token previews (first/last chars) in `clawdbot status` provider details; keep `status --all` redacted (hash+length).
|
||||||
|
|
||||||
## 2026.1.10-3
|
## 2026.1.10-3
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "clawdbot",
|
"name": "clawdbot",
|
||||||
"version": "2026.1.10-3",
|
"version": "2026.1.10-4",
|
||||||
"description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent",
|
"description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@ -138,7 +138,7 @@ export async function statusAllCommand(
|
|||||||
progress.setLabel("Scanning agents…");
|
progress.setLabel("Scanning agents…");
|
||||||
const agentStatus = await getAgentLocalStatuses(cfg);
|
const agentStatus = await getAgentLocalStatuses(cfg);
|
||||||
progress.setLabel("Summarizing providers…");
|
progress.setLabel("Summarizing providers…");
|
||||||
const providers = await buildProvidersTable(cfg);
|
const providers = await buildProvidersTable(cfg, { showSecrets: false });
|
||||||
|
|
||||||
const connectionDetailsForReport = (() => {
|
const connectionDetailsForReport = (() => {
|
||||||
if (!remoteUrlMissing) return connection.message;
|
if (!remoteUrlMissing) return connection.message;
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import crypto from "node:crypto";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import type { ClawdbotConfig } from "../../config/config.js";
|
import type { ClawdbotConfig } from "../../config/config.js";
|
||||||
import {
|
import {
|
||||||
@ -66,7 +67,28 @@ function existsSyncMaybe(p: string | undefined): boolean | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
function sha256HexPrefix(value: string, len = 8): string {
|
||||||
|
return crypto.createHash("sha256").update(value).digest("hex").slice(0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTokenHint(
|
||||||
|
token: string,
|
||||||
|
opts: { showSecrets: boolean },
|
||||||
|
): string {
|
||||||
|
const t = token.trim();
|
||||||
|
if (!t) return "empty";
|
||||||
|
if (!opts.showSecrets)
|
||||||
|
return `sha256:${sha256HexPrefix(t)} · len ${t.length}`;
|
||||||
|
const head = t.slice(0, 4);
|
||||||
|
const tail = t.slice(-4);
|
||||||
|
if (t.length <= 10) return `${t} · len ${t.length}`;
|
||||||
|
return `${head}…${tail} · len ${t.length}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function buildProvidersTable(
|
||||||
|
cfg: ClawdbotConfig,
|
||||||
|
opts?: { showSecrets?: boolean },
|
||||||
|
): Promise<{
|
||||||
rows: ProviderRow[];
|
rows: ProviderRow[];
|
||||||
details: Array<{
|
details: Array<{
|
||||||
title: string;
|
title: string;
|
||||||
@ -74,6 +96,7 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
rows: Array<Record<string, string>>;
|
rows: Array<Record<string, string>>;
|
||||||
}>;
|
}>;
|
||||||
}> {
|
}> {
|
||||||
|
const showSecrets = opts?.showSecrets === true;
|
||||||
const rows: ProviderRow[] = [];
|
const rows: ProviderRow[] = [];
|
||||||
const details: Array<{
|
const details: Array<{
|
||||||
title: string;
|
title: string;
|
||||||
@ -138,6 +161,10 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
const tgEnabledAccounts = tgAccounts.filter((a) => a.enabled);
|
const tgEnabledAccounts = tgAccounts.filter((a) => a.enabled);
|
||||||
const tgTokenAccounts = tgEnabledAccounts.filter((a) => a.token?.trim());
|
const tgTokenAccounts = tgEnabledAccounts.filter((a) => a.token?.trim());
|
||||||
const tgSources = summarizeSources(tgTokenAccounts.map((a) => a.tokenSource));
|
const tgSources = summarizeSources(tgTokenAccounts.map((a) => a.tokenSource));
|
||||||
|
const tgSampleToken = tgTokenAccounts[0]?.token?.trim() || "";
|
||||||
|
const tgTokenHint = tgSampleToken
|
||||||
|
? formatTokenHint(tgSampleToken, { showSecrets })
|
||||||
|
: "";
|
||||||
const tgMissingFiles: string[] = [];
|
const tgMissingFiles: string[] = [];
|
||||||
const tgGlobalTokenFileExists = existsSyncMaybe(cfg.telegram?.tokenFile);
|
const tgGlobalTokenFileExists = existsSyncMaybe(cfg.telegram?.tokenFile);
|
||||||
if (
|
if (
|
||||||
@ -170,7 +197,7 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
? tgMisconfigured
|
? tgMisconfigured
|
||||||
? `token file missing (${tgMissingFiles[0]})`
|
? `token file missing (${tgMissingFiles[0]})`
|
||||||
: tgTokenAccounts.length > 0
|
: tgTokenAccounts.length > 0
|
||||||
? `bot token ${tgSources.label} · accounts ${tgTokenAccounts.length}/${tgEnabledAccounts.length || 1}`
|
? `bot token ${tgSources.label}${tgTokenHint ? ` (${tgTokenHint})` : ""} · accounts ${tgTokenAccounts.length}/${tgEnabledAccounts.length || 1}`
|
||||||
: "no bot token (TELEGRAM_BOT_TOKEN / telegram.botToken)"
|
: "no bot token (TELEGRAM_BOT_TOKEN / telegram.botToken)"
|
||||||
: "disabled",
|
: "disabled",
|
||||||
});
|
});
|
||||||
@ -183,13 +210,17 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
const dcEnabledAccounts = dcAccounts.filter((a) => a.enabled);
|
const dcEnabledAccounts = dcAccounts.filter((a) => a.enabled);
|
||||||
const dcTokenAccounts = dcEnabledAccounts.filter((a) => a.token?.trim());
|
const dcTokenAccounts = dcEnabledAccounts.filter((a) => a.token?.trim());
|
||||||
const dcSources = summarizeSources(dcTokenAccounts.map((a) => a.tokenSource));
|
const dcSources = summarizeSources(dcTokenAccounts.map((a) => a.tokenSource));
|
||||||
|
const dcSampleToken = dcTokenAccounts[0]?.token?.trim() || "";
|
||||||
|
const dcTokenHint = dcSampleToken
|
||||||
|
? formatTokenHint(dcSampleToken, { showSecrets })
|
||||||
|
: "";
|
||||||
rows.push({
|
rows.push({
|
||||||
provider: "Discord",
|
provider: "Discord",
|
||||||
enabled: dcEnabled,
|
enabled: dcEnabled,
|
||||||
state: !dcEnabled ? "off" : dcTokenAccounts.length > 0 ? "ok" : "setup",
|
state: !dcEnabled ? "off" : dcTokenAccounts.length > 0 ? "ok" : "setup",
|
||||||
detail: dcEnabled
|
detail: dcEnabled
|
||||||
? dcTokenAccounts.length > 0
|
? dcTokenAccounts.length > 0
|
||||||
? `bot token ${dcSources.label} · accounts ${dcTokenAccounts.length}/${dcEnabledAccounts.length || 1}`
|
? `bot token ${dcSources.label}${dcTokenHint ? ` (${dcTokenHint})` : ""} · accounts ${dcTokenAccounts.length}/${dcEnabledAccounts.length || 1}`
|
||||||
: "no bot token (DISCORD_BOT_TOKEN / discord.token)"
|
: "no bot token (DISCORD_BOT_TOKEN / discord.token)"
|
||||||
: "disabled",
|
: "disabled",
|
||||||
});
|
});
|
||||||
@ -217,6 +248,15 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
const slAppSources = summarizeSources(
|
const slAppSources = summarizeSources(
|
||||||
slReady.map((a) => a.appTokenSource ?? "none"),
|
slReady.map((a) => a.appTokenSource ?? "none"),
|
||||||
);
|
);
|
||||||
|
const slSample = slReady[0] ?? null;
|
||||||
|
const slBotHint =
|
||||||
|
slSample?.botToken?.trim() && slSample.botTokenSource !== "none"
|
||||||
|
? formatTokenHint(slSample.botToken, { showSecrets })
|
||||||
|
: "";
|
||||||
|
const slAppHint =
|
||||||
|
slSample?.appToken?.trim() && slSample.appTokenSource !== "none"
|
||||||
|
? formatTokenHint(slSample.appToken, { showSecrets })
|
||||||
|
: "";
|
||||||
rows.push({
|
rows.push({
|
||||||
provider: "Slack",
|
provider: "Slack",
|
||||||
enabled: slEnabled,
|
enabled: slEnabled,
|
||||||
@ -231,7 +271,7 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
? slPartial.length > 0
|
? slPartial.length > 0
|
||||||
? `partial tokens (need bot+app) · accounts ${slPartial.length}`
|
? `partial tokens (need bot+app) · accounts ${slPartial.length}`
|
||||||
: slReady.length > 0
|
: slReady.length > 0
|
||||||
? `tokens ok (bot ${slBotSources.label}, app ${slAppSources.label}) · accounts ${slReady.length}/${slEnabledAccounts.length || 1}`
|
? `tokens ok (bot ${slBotSources.label}${slBotHint ? ` ${slBotHint}` : ""}, app ${slAppSources.label}${slAppHint ? ` ${slAppHint}` : ""}) · accounts ${slReady.length}/${slEnabledAccounts.length || 1}`
|
||||||
: slHasAnyToken
|
: slHasAnyToken
|
||||||
? "tokens incomplete (need bot+app)"
|
? "tokens incomplete (need bot+app)"
|
||||||
: "no tokens (SLACK_BOT_TOKEN + SLACK_APP_TOKEN)"
|
: "no tokens (SLACK_BOT_TOKEN + SLACK_APP_TOKEN)"
|
||||||
@ -298,6 +338,9 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
!msTenantId ? "tenantId" : null,
|
!msTenantId ? "tenantId" : null,
|
||||||
].filter(Boolean) as string[];
|
].filter(Boolean) as string[];
|
||||||
const msAnyPresent = Boolean(msAppId || msAppPassword || msTenantId);
|
const msAnyPresent = Boolean(msAppId || msAppPassword || msTenantId);
|
||||||
|
const msPasswordHint = msAppPassword
|
||||||
|
? formatTokenHint(msAppPassword, { showSecrets })
|
||||||
|
: "";
|
||||||
rows.push({
|
rows.push({
|
||||||
provider: "MS Teams",
|
provider: "MS Teams",
|
||||||
enabled: msEnabled,
|
enabled: msEnabled,
|
||||||
@ -310,7 +353,7 @@ export async function buildProvidersTable(cfg: ClawdbotConfig): Promise<{
|
|||||||
: "setup",
|
: "setup",
|
||||||
detail: msEnabled
|
detail: msEnabled
|
||||||
? msCreds
|
? msCreds
|
||||||
? "credentials set"
|
? `credentials set${msPasswordHint ? ` (password ${msPasswordHint})` : ""}`
|
||||||
: msAnyPresent
|
: msAnyPresent
|
||||||
? `credentials incomplete (missing ${msMissing.join(", ")})`
|
? `credentials incomplete (missing ${msMissing.join(", ")})`
|
||||||
: "no credentials (MSTEAMS_APP_ID / _PASSWORD / _TENANT_ID)"
|
: "no credentials (MSTEAMS_APP_ID / _PASSWORD / _TENANT_ID)"
|
||||||
|
|||||||
@ -578,7 +578,11 @@ export async function statusCommand(
|
|||||||
progress.tick();
|
progress.tick();
|
||||||
|
|
||||||
progress.setLabel("Summarizing providers…");
|
progress.setLabel("Summarizing providers…");
|
||||||
const providers = await buildProvidersTable(cfg);
|
const providers = await buildProvidersTable(cfg, {
|
||||||
|
// Show token previews in regular status; keep `status --all` redacted.
|
||||||
|
// Set `CLAWDBOT_SHOW_SECRETS=0` to force redaction.
|
||||||
|
showSecrets: process.env.CLAWDBOT_SHOW_SECRETS?.trim() !== "0",
|
||||||
|
});
|
||||||
progress.tick();
|
progress.tick();
|
||||||
|
|
||||||
progress.setLabel("Reading sessions…");
|
progress.setLabel("Reading sessions…");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user