fix(telegram): resolve status SecretRefs with provider-safe env checks

Landed from #39130 by @neocody.

Co-authored-by: Cody <25426121+neocody@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-03-07 20:50:07 +00:00
parent 2015ab3194
commit 330579ef96
3 changed files with 141 additions and 7 deletions

View File

@@ -1,9 +1,14 @@
import fs from "node:fs";
import type { OpenClawConfig } from "../config/config.js";
import { hasConfiguredSecretInput, normalizeSecretInputString } from "../config/types.secrets.js";
import {
coerceSecretRef,
hasConfiguredSecretInput,
normalizeSecretInputString,
} from "../config/types.secrets.js";
import type { TelegramAccountConfig } from "../config/types.telegram.js";
import { resolveAccountWithDefaultFallback } from "../plugin-sdk/account-resolution.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js";
import { resolveDefaultSecretProviderAlias } from "../secrets/ref-contract.js";
import {
mergeTelegramAccountConfig,
resolveDefaultTelegramAccountId,
@@ -55,12 +60,58 @@ function inspectTokenFile(pathValue: unknown): {
}
}
function inspectTokenValue(value: unknown): {
function canResolveEnvSecretRefInReadOnlyPath(params: {
cfg: OpenClawConfig;
provider: string;
id: string;
}): boolean {
const providerConfig = params.cfg.secrets?.providers?.[params.provider];
if (!providerConfig) {
return params.provider === resolveDefaultSecretProviderAlias(params.cfg, "env");
}
if (providerConfig.source !== "env") {
return false;
}
const allowlist = providerConfig.allowlist;
return !allowlist || allowlist.includes(params.id);
}
function inspectTokenValue(params: { cfg: OpenClawConfig; value: unknown }): {
token: string;
tokenSource: "config" | "none";
tokenSource: "config" | "env" | "none";
tokenStatus: TelegramCredentialStatus;
} | null {
const token = normalizeSecretInputString(value);
// Try to resolve env-based SecretRefs from process.env for read-only inspection
const ref = coerceSecretRef(params.value, params.cfg.secrets?.defaults);
if (ref?.source === "env") {
if (
!canResolveEnvSecretRefInReadOnlyPath({
cfg: params.cfg,
provider: ref.provider,
id: ref.id,
})
) {
return {
token: "",
tokenSource: "env",
tokenStatus: "configured_unavailable",
};
}
const envValue = process.env[ref.id];
if (envValue && envValue.trim()) {
return {
token: envValue.trim(),
tokenSource: "env",
tokenStatus: "available",
};
}
return {
token: "",
tokenSource: "env",
tokenStatus: "configured_unavailable",
};
}
const token = normalizeSecretInputString(params.value);
if (token) {
return {
token,
@@ -68,7 +119,7 @@ function inspectTokenValue(value: unknown): {
tokenStatus: "available",
};
}
if (hasConfiguredSecretInput(value)) {
if (hasConfiguredSecretInput(params.value, params.cfg.secrets?.defaults)) {
return {
token: "",
tokenSource: "config",
@@ -102,7 +153,7 @@ function inspectTelegramAccountPrimary(params: {
};
}
const accountToken = inspectTokenValue(accountConfig?.botToken);
const accountToken = inspectTokenValue({ cfg: params.cfg, value: accountConfig?.botToken });
if (accountToken) {
return {
accountId,
@@ -130,7 +181,10 @@ function inspectTelegramAccountPrimary(params: {
};
}
const channelToken = inspectTokenValue(params.cfg.channels?.telegram?.botToken);
const channelToken = inspectTokenValue({
cfg: params.cfg,
value: params.cfg.channels?.telegram?.botToken,
});
if (channelToken) {
return {
accountId,