From 4d58cc6e263f1eff6d2a6f2945785b9edcd77242 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Wed, 11 Mar 2026 14:04:37 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(connection/redis):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Redis=20URI=20=E7=94=A8=E6=88=B7=E5=90=8D?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=AF=BC=E8=87=B4=E8=AE=A4=E8=AF=81=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Redis URI 解析回填 user 字段,兼容 redis://user:pass@... 与 redis://:pass@... - 生成 URI 时按需输出 user/password,避免丢失用户名信息 - Redis 类型默认用户名置空,并在构建配置时清理历史默认 root - 避免 go-redis 触发 ACL AUTH(user, pass) 导致 WRONGPASS - refs #212 --- frontend/src/components/ConnectionModal.tsx | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/ConnectionModal.tsx b/frontend/src/components/ConnectionModal.tsx index bf7414b..ce874a9 100644 --- a/frontend/src/components/ConnectionModal.tsx +++ b/frontend/src/components/ConnectionModal.tsx @@ -568,6 +568,7 @@ const ConnectionModal: React.FC<{ return { host: primary?.host || 'localhost', port: primary?.port || 6379, + user: parsed.username || '', password: parsed.password || '', useSSL: isRediss, sslMode: isRediss ? (skipVerify ? 'skip-verify' : 'required') : 'disable', @@ -823,8 +824,15 @@ const ConnectionModal: React.FC<{ if (hosts.length > 1 || values.redisTopology === 'cluster') { params.set('topology', 'cluster'); } + const redisUser = String(values.user || '').trim(); const redisPassword = String(values.password || ''); - const redisAuth = redisPassword ? `:${encodeURIComponent(redisPassword)}@` : ''; + let redisAuth = ''; + if (redisUser || redisPassword) { + const encodedPassword = redisPassword ? encodeURIComponent(redisPassword) : ''; + redisAuth = redisUser + ? `${encodeURIComponent(redisUser)}${redisPassword ? `:${encodedPassword}` : ''}@` + : `:${encodedPassword}@`; + } const redisDB = Number.isFinite(Number(values.redisDB)) ? Math.max(0, Math.min(15, Math.trunc(Number(values.redisDB)))) : 0; @@ -1368,6 +1376,16 @@ const ConnectionModal: React.FC<{ const defaultPort = getDefaultPortByType(type); const isFileDbType = isFileDatabaseType(type); const sslCapableType = supportsSSLForType(type); + + // Redis 默认不展示用户名字段;若 URI 可解析则以 URI 为准覆盖 user, + // 同时清理历史默认值 root,避免 go-redis 发送 ACL AUTH(user, pass) 导致 WRONGPASS。 + if (type === 'redis') { + if (parsedUriValues && Object.prototype.hasOwnProperty.call(parsedUriValues, 'user')) { + mergedValues.user = String((parsedUriValues as any).user || ''); + } else if (String(mergedValues.user || '').trim() === 'root') { + mergedValues.user = ''; + } + } const sslModeRaw = String(mergedValues.sslMode || 'preferred').trim().toLowerCase(); const sslMode: 'preferred' | 'required' | 'skip-verify' | 'disable' = sslModeRaw === 'required' ? 'required' @@ -1618,7 +1636,11 @@ const ConnectionModal: React.FC<{ redisDB: 0, }); } else if (type !== 'custom') { - const defaultUser = type === 'clickhouse' ? 'default' : 'root'; + const defaultUser = type === 'clickhouse' + ? 'default' + : type === 'redis' + ? '' + : 'root'; const sslCapableType = supportsSSLForType(type); setUseSSL(false); setUseHttpTunnel(false);