mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(tui): preserve credential-like tokens in render sanitization
This commit is contained in:
@@ -30,6 +30,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- TUI/token copy-safety rendering: treat long credential-like mixed alphanumeric tokens (including quoted forms) as copy-sensitive in render sanitization so formatter hard-wrap guards no longer inject visible spaces into auth-style values before display. (#26710) Thanks @jasonthane.
|
||||
- WhatsApp/self-chat response prefix fallback: stop forcing `"[openclaw]"` as the implicit outbound response prefix when no identity name or response prefix is configured, so blank/default prefix settings no longer inject branding text unexpectedly in self-chat flows. (#27962) Thanks @ecanmor.
|
||||
- Memory/QMD search result decoding: accept `qmd search` hits that only include `file` URIs (for example `qmd://collection/path.md`) without `docid`, resolve them through managed collection roots, and keep multi-collection results keyed by file fallback so valid QMD hits no longer collapse to empty `memory_search` output. (#28181) Thanks @0x76696265.
|
||||
- Memory/QMD collection-name conflict recovery: when `qmd collection add` fails because another collection already occupies the same `path + pattern`, detect the conflicting collection from `collection list`, remove it, and retry add so agent-scoped managed collections are created deterministically instead of being silently skipped; also add warning-only fallback when qmd metadata is unavailable to avoid destructive guesses. (#25496) Thanks @Ramsbaby.
|
||||
|
||||
@@ -249,6 +249,20 @@ describe("sanitizeRenderableText", () => {
|
||||
expect(sanitized).toBe(input);
|
||||
});
|
||||
|
||||
it("preserves long credential-like mixed alnum tokens for copy safety", () => {
|
||||
const input = "e3b19c3b87bcf364b23eebb2c276e96ec478956ba1d84c93";
|
||||
const sanitized = sanitizeRenderableText(input);
|
||||
|
||||
expect(sanitized).toBe(input);
|
||||
});
|
||||
|
||||
it("preserves quoted credential-like mixed alnum tokens for copy safety", () => {
|
||||
const input = "'e3b19c3b87bcf364b23eebb2c276e96ec478956ba1d84c93'";
|
||||
const sanitized = sanitizeRenderableText(input);
|
||||
|
||||
expect(sanitized).toBe(input);
|
||||
});
|
||||
|
||||
it("wraps rtl lines with directional isolation marks", () => {
|
||||
const input = "مرحبا بالعالم";
|
||||
const sanitized = sanitizeRenderableText(input);
|
||||
|
||||
@@ -11,6 +11,8 @@ const BINARY_LINE_REPLACEMENT_THRESHOLD = 12;
|
||||
const URL_PREFIX_RE = /^(https?:\/\/|file:\/\/)/i;
|
||||
const WINDOWS_DRIVE_RE = /^[a-zA-Z]:[\\/]/;
|
||||
const FILE_LIKE_RE = /^[a-zA-Z0-9._-]+$/;
|
||||
const EDGE_PUNCTUATION_RE = /^[`"'([{<]+|[`"')\]}>.,:;!?]+$/g;
|
||||
const TOKENISH_MIN_LENGTH = 24;
|
||||
const RTL_SCRIPT_RE = /[\u0590-\u08ff\ufb1d-\ufdff\ufe70-\ufefc]/;
|
||||
const BIDI_CONTROL_RE = /[\u202a-\u202e\u2066-\u2069]/;
|
||||
const RTL_ISOLATE_START = "\u2067";
|
||||
@@ -56,6 +58,9 @@ function chunkToken(token: string, maxChars: number): string[] {
|
||||
}
|
||||
|
||||
function isCopySensitiveToken(token: string): boolean {
|
||||
const coreToken = token.replace(EDGE_PUNCTUATION_RE, "");
|
||||
const candidate = coreToken || token;
|
||||
|
||||
if (URL_PREFIX_RE.test(token)) {
|
||||
return true;
|
||||
}
|
||||
@@ -73,7 +78,16 @@ function isCopySensitiveToken(token: string): boolean {
|
||||
if (token.includes("/") || token.includes("\\")) {
|
||||
return true;
|
||||
}
|
||||
return token.includes("_") && FILE_LIKE_RE.test(token);
|
||||
if (token.includes("_") && FILE_LIKE_RE.test(token)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preserve long credential-like tokens (hex/base62/etc.) to avoid introducing
|
||||
// visible spaces that users may copy back into secrets.
|
||||
if (candidate.length >= TOKENISH_MIN_LENGTH && /[a-z]/i.test(candidate) && /\d/.test(candidate)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeLongTokenForDisplay(token: string): string {
|
||||
|
||||
Reference in New Issue
Block a user