refactor(middleware): 移除数据脱敏中间件及相关代码
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

移除不再使用的数据脱敏功能,包括:
1. 删除data_masking模块
2. 清理loop_runner中的unmask逻辑
3. 移除前端saas-relay-client.ts中的mask/unmask实现
4. 更新中间件层数从15层降为14层
5. 同步更新相关文档(CLAUDE.md、TRUTH.md、wiki等)

此次变更简化了系统架构,移除了不再需要的敏感数据处理逻辑。所有相关测试证据和截图已归档。
This commit is contained in:
iven
2026-04-22 19:19:07 +08:00
parent 14f2f497b6
commit fa5ab4e161
68 changed files with 8049 additions and 3684 deletions

View File

@@ -49,57 +49,6 @@ async function injectMemories(
return basePrompt;
}
// ---------------------------------------------------------------------------
// Frontend DataMasking — mirrors Rust DataMasking middleware for SaaS Relay
// ---------------------------------------------------------------------------
const MASK_PATTERNS: RegExp[] = [
/\b\d{17}[\dXx]\b/g, // ID card
/1[3-9]\d-?\d{4}-?\d{4}/g, // Phone
/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, // Email
/[¥¥$]\s*[\d,.]+[万亿]?元?|[\d,.]+[万亿]元/g, // Money
/[^\s]{1,20}(?:公司|厂|集团|工作室|商行|有限|股份)/g, // Company
];
let maskCounter = 0;
const entityMap = new Map<string, string>();
/** Mask sensitive entities in text before sending to SaaS relay. */
function maskSensitiveData(text: string): string {
const entities: { text: string; token: string }[] = [];
for (const pattern of MASK_PATTERNS) {
pattern.lastIndex = 0;
let match: RegExpExecArray | null;
while ((match = pattern.exec(text)) !== null) {
const entity = match[0];
if (!entityMap.has(entity)) {
maskCounter++;
entityMap.set(entity, `__ENTITY_${maskCounter}__`);
}
entities.push({ text: entity, token: entityMap.get(entity)! });
}
}
// Sort by length descending to replace longest entities first
entities.sort((a, b) => b.text.length - a.text.length);
let result = text;
for (const { text: entity, token } of entities) {
result = result.split(entity).join(token);
}
return result;
}
/** Restore masked tokens in AI response back to original entities. */
function unmaskSensitiveData(text: string): string {
let result = text;
for (const [entity, token] of entityMap) {
result = result.split(token).join(entity);
}
return result;
}
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
@@ -206,12 +155,10 @@ export function createSaaSRelayGatewayClient(
try {
// Build messages array: use history if available, fallback to current message only
// Apply DataMasking to protect sensitive data before sending to relay
const history = opts?.history || [];
const maskedMessage = maskSensitiveData(message);
const messages = history.length > 0
? [...history, { role: 'user' as const, content: maskedMessage }]
: [{ role: 'user' as const, content: maskedMessage }];
? [...history, { role: 'user' as const, content: message }]
: [{ role: 'user' as const, content: message }];
// BUG-M5 fix: Inject relevant memories into system prompt via Tauri IPC.
// This mirrors the MemoryMiddleware that runs in the kernel path.
@@ -309,9 +256,9 @@ export function createSaaSRelayGatewayClient(
callbacks.onThinkingDelta?.(delta.reasoning_content);
}
// Handle regular content — unmask tokens so user sees original entities
// Handle regular content
if (delta?.content) {
callbacks.onDelta(unmaskSensitiveData(delta.content));
callbacks.onDelta(delta.content);
}
// Check for completion