Files
nexus-terminal/.helloagents/plan/202603252354_login-credential-management/proposal.md
T
yinjianm 1f52ff6e0a feat(workspace): 支持多行命令输入并新增仪表盘接口
将底部命令输入框改为支持自动增高的多行 textarea,
并把发送快捷键调整为 Ctrl+Shift+Enter,同时更新多语言提示文案

新增 dashboard summary 后端接口与聚合类型定义,
为首页管理驾驶舱改造提供统一数据入口,并同步知识库方案记录
2026-03-25 23:57:17 +08:00

207 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 变更提案: login-credential-management
## 元信息
```yaml
类型: 新功能
方案类型: implementation
优先级: P1
状态: 草稿
创建: 2026-03-25
```
---
## 1. 需求
### 背景
当前连接的用户名、密码、认证方式和 SSH 密钥选择直接存放在连接本体中。这样虽然能满足单连接直填,但无法形成独立的登录凭证资产,也无法在多台服务器之间稳定复用同一组登录配置。用户明确要求新增独立“登录凭证管理”,同时保留原有直填方式,并支持在新增连接、编辑连接和批量编辑中一键应用已保存凭证。
### 目标
- 新增统一“登录凭证管理”,支持 SSH / RDP / VNC 三类凭证的列表、新增、编辑、删除。
- 新增连接和编辑连接时,保留“账号密码 / 密钥直填”能力,同时增加“使用已保存凭证”模式。
- 批量编辑连接时支持一键把选中的服务器切换到某个已保存凭证。
- 连接运行时需要优先解析“引用凭证”,未引用时继续使用连接自身保存的直填凭证。
- 兼容已有连接数据,不强制迁移旧连接为凭证引用。
### 约束条件
```yaml
时间约束: 本轮内完成数据库、后端 API、前端交互和基础验证闭环
兼容性约束: 旧连接必须继续可编辑、可测试、可连接
数据约束: 已保存凭证需要单独建模,不能继续依附于 connections 表临时拼装
交互约束: 不做本地仓库/云端仓库区分,管理入口采用贴近现有连接工作流的管理面板
安全约束: 凭证敏感字段继续复用现有 encrypt/decrypt 机制,不在连接列表接口中明文返回
```
### 验收标准
- [ ] 后端新增独立登录凭证表和 CRUD API,支持 SSH / RDP / VNC 三类凭证
- [ ] `connections` 表新增可选凭证引用字段,连接创建、更新、测试和实际使用时都能解析已保存凭证
- [ ] 新增连接/编辑连接时支持在“直填凭证”和“已保存凭证”之间切换,且不移除原有直填能力
- [ ] 批量编辑连接支持一键应用某个已保存凭证
- [ ] 旧连接在不绑定登录凭证时仍按原逻辑工作
- [ ] 前后端至少完成可运行的构建或类型校验验证
---
## 2. 方案
### 技术方案
采用“独立登录凭证实体 + 连接可选引用”的实现路径。后端新增 `login_credentials` 表和对应模块,统一存储凭证名称、协议类型、用户名、认证方式、加密后的密码/密钥等信息。`connections` 表新增 `login_credential_id` 外键,连接在保存时可以选择两种模式:
1. 继续在连接中直填并保存用户名/密码/密钥
2. 改为引用某个已保存凭证
连接运行时、测试连接和批量编辑都统一走“先看引用凭证,再回退连接自身凭证”的解析逻辑。前端在现有连接表单的认证区加入“认证来源”切换,并新增登录凭证管理面板;批量编辑弹窗补“应用已保存凭证”入口。
### 影响范围
```yaml
涉及模块:
- backend: database schema/migrations, login-credentials 模块, connections 模块
- frontend: AddConnectionForm, BatchEditConnectionForm, 连接相关 store/types, 新增登录凭证管理组件与入口
- frontend: locales 多语言文案
- knowledge-base: 方案包、实施日志与知识同步
预计变更文件: 14-22
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 连接、测试连接、实际握手三条链路凭证解析不一致 | 高 | 后端提炼统一的“解析有效凭证”逻辑,禁止三处各写一套 |
| 旧连接编辑回显时,直填模式与引用模式切换导致字段覆盖 | 中 | 前端明确区分 `credential_source` 状态,提交时只发送当前模式需要的字段 |
| 批量编辑对不同类型连接应用凭证时可能出现协议不匹配 | 中 | 限制只能应用同类型凭证,后端再次校验 |
| 新增通用凭证实体后与现有 `ssh_keys` 关系重复 | 中 | 保留 `ssh_keys` 作为 SSH 私钥仓库,登录凭证通过 `ssh_key_id` 引用已保存 SSH 密钥 |
---
## 3. 技术设计
### 架构设计
```mermaid
flowchart LR
A[AddConnectionForm / BatchEditConnectionForm] --> B[loginCredentials.store]
A --> C[connections.store]
B --> D[/api/v1/login-credentials]
C --> E[/api/v1/connections]
D --> F[login-credentials.controller]
E --> G[connections.controller]
F --> H[login-credentials.service]
G --> I[connection.service]
H --> J[(login_credentials)]
I --> J
I --> K[(connections)]
I --> L[(ssh_keys)]
```
### API 设计
#### GET /api/v1/login-credentials
- 返回所有登录凭证的安全摘要,不包含明文密码/私钥
#### POST /api/v1/login-credentials
- 新增登录凭证
- 请求需包含 `type``name``username` 和对应认证字段
#### PUT /api/v1/login-credentials/:id
- 更新登录凭证
- 允许局部更新;敏感字段为空时表示“不改”
#### DELETE /api/v1/login-credentials/:id
- 删除登录凭证
- 若有连接引用,默认将连接的 `login_credential_id` 置空,不删连接
#### POST /api/v1/connections/test-unsaved
- 继续保留原接口
- 新增支持 `login_credential_id`,测试时优先使用登录凭证解析结果
### 数据模型
#### 新表 `login_credentials`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `INTEGER` | 主键 |
| `name` | `TEXT` | 凭证名称,前端展示用 |
| `type` | `TEXT` | `SSH` / `RDP` / `VNC` |
| `username` | `TEXT` | 登录用户名 |
| `auth_method` | `TEXT` | SSH 为 `password` / `key`RDP/VNC 固定 `password` |
| `encrypted_password` | `TEXT NULL` | 加密后的密码 |
| `ssh_key_id` | `INTEGER NULL` | SSH 引用的密钥 ID |
| `encrypted_private_key` | `TEXT NULL` | 直接保存的 SSH 私钥 |
| `encrypted_passphrase` | `TEXT NULL` | SSH 私钥口令 |
| `notes` | `TEXT NULL` | 凭证备注 |
| `created_at` | `INTEGER` | 创建时间 |
| `updated_at` | `INTEGER` | 更新时间 |
#### `connections` 表增量字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `login_credential_id` | `INTEGER NULL` | 引用的登录凭证 ID |
### 核心决策
### login-credential-management#D001: 采用“连接可选引用凭证 + 保留直填”的双轨方案
**日期**: 2026-03-25
**状态**: ✅采纳
**背景**: 用户明确要求“不要移除直填”,同时还要能选择使用已保存配置。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 连接只允许引用凭证 | 数据归一最强 | 会破坏现有直填体验,不符合用户要求 |
| B: 连接保留直填,并可选引用凭证 | 兼容旧逻辑,迁移风险低 | 数据模型和前端状态更复杂 |
**决策**: 选择方案 B
**理由**: 这是唯一满足用户要求且兼容现有连接资产的路径。
**影响**: backend, frontend
### login-credential-management#D002: SSH 登录凭证继续复用 `ssh_keys` 作为底层密钥仓库
**日期**: 2026-03-25
**状态**: ✅采纳
**背景**: 仓库已有完整 SSH 密钥管理链路,不应为了通用登录凭证重复造一套密钥管理。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 登录凭证内部直接复用 `ssh_key_id` | 复用现有密钥管理和解密逻辑 | 模型上需要解释“凭证”和“密钥”两层关系 |
| B: 在登录凭证里完全复制私钥管理 | 数据模型更扁平 | 重复实现、风险更高 |
**决策**: 选择方案 A
**理由**: 能最大程度复用现有 SSH 密钥能力,减少改动面和安全风险。
**影响**: backend, frontend
---
## 4. 核心场景
### 场景: 新增连接时选择已保存凭证
**模块**: frontend / backend
**条件**: 用户打开新增连接弹窗并选择“使用已保存凭证”。
**行为**: 表单展示可筛选的凭证下拉或管理入口,用户选择后仅保存 `login_credential_id`
**结果**: 新连接不再重复保存一套账号密码,而是复用独立登录凭证。
### 场景: 批量编辑时一键应用凭证
**模块**: frontend / backend
**条件**: 用户在连接列表中多选多台服务器并打开批量编辑。
**行为**: 批量编辑弹窗允许选择某个已保存凭证,提交后把选中连接统一切换到该凭证。
**结果**: 多台同账号主机可快速改绑同一登录凭证。
### 场景: 旧连接继续使用直填凭证
**模块**: backend
**条件**: 连接未绑定 `login_credential_id`
**行为**: 测试连接、建立连接、编辑回显时继续走旧字段。
**结果**: 老数据零强制迁移,升级后仍可工作。
---
## 5. 成果设计
### 设计方向
- **美学基调**: 延续现有深色控制台视觉,新增一个更聚焦“资产管理”的右侧管理面板
- **记忆点**: 在连接表单中将“认证信息”升级为“认证来源 + 凭证管理”的组合区域,形成明显的操作跃迁
- **交互立场**: 新能力应嵌在现有连接工作流内,而不是把用户赶去陌生页面
### 视觉要素
- **配色**: 继续使用现有 `background / border / primary / text-secondary` 变量,凭证列表用绿色锁图标和次级文字区分状态
- **布局**: 连接弹窗中认证区采用上下分段,先选“直填 / 已保存凭证”,再展示对应表单;登录凭证管理使用右侧抽屉或侧面板布局
- **动效**: 切换认证来源时做轻量内容切换,不引入重动画;凭证管理面板滑入滑出,保持与现有 modal 体系兼容
- **氛围**: 保持专业、克制,不做多余装饰;重点在于“操作密度”和“字段分组清晰”
### 技术约束
- **响应式**: 桌面优先,窄屏时管理面板应退化为全屏弹层
- **可访问性**: 切换认证来源后应保留明确字段标题和禁用态反馈