refactor: 统一项目名称从OpenFang到ZCLAW
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

重构所有代码和文档中的项目名称,将OpenFang统一更新为ZCLAW。包括:
- 配置文件中的项目名称
- 代码注释和文档引用
- 环境变量和路径
- 类型定义和接口名称
- 测试用例和模拟数据

同时优化部分代码结构,移除未使用的模块,并更新相关依赖项。
This commit is contained in:
iven
2026-03-27 07:36:03 +08:00
parent 4b08804aa9
commit 0d4fa96b82
226 changed files with 7288 additions and 5788 deletions

View File

@@ -1,10 +1,11 @@
/**
* securityStore.ts - Security Status and Audit Log Management
*
* Extracted from gatewayStore.ts for Store Refactoring.
* Manages OpenFang security layers, security status, and audit logs.
* Manages ZCLAW security layers, security status, and audit logs.
* Uses local security checks (security-index.ts + Tauri commands) instead of REST API.
*/
import { create } from 'zustand';
import { invoke } from '@tauri-apps/api/core';
import type { GatewayClient } from '../lib/gateway-client';
// === Types ===
@@ -29,7 +30,7 @@ export interface AuditLogEntry {
actor?: string;
result?: 'success' | 'failure';
details?: Record<string, unknown>;
// Merkle hash chain fields (OpenFang)
// Merkle hash chain fields
hash?: string;
previousHash?: string;
}
@@ -45,6 +46,160 @@ function calculateSecurityLevel(enabledCount: number, totalCount: number): 'crit
return 'low'; // 0-5 layers
}
/**
* Check if OS Keyring (secure store) is available via Tauri command.
* Returns false if not in Tauri environment or if keyring is unavailable.
*/
async function checkKeyringAvailable(): Promise<boolean> {
try {
return await invoke<boolean>('secure_store_is_available');
} catch {
// Not in Tauri environment or command failed
return false;
}
}
/**
* Check if the ZCLAW Kernel is initialized via Tauri command.
*/
async function checkKernelInitialized(): Promise<boolean> {
try {
const status = await invoke<{ initialized: boolean }>('kernel_status');
return status.initialized;
} catch {
return false;
}
}
/**
* Build the 16-layer security model from local security checks.
*/
async function buildLocalSecurityLayers(): Promise<SecurityLayer[]> {
// Gather local security status
let auditEnabled = false;
let keychainAvailable = false;
let chatStorageInitialized = false;
try {
const { getSecurityStatus } = await import('../lib/security-index');
const status = await getSecurityStatus();
auditEnabled = status.auditEnabled;
keychainAvailable = status.keychainAvailable;
chatStorageInitialized = status.chatStorageInitialized;
} catch {
// Security module not available - use defaults
}
// Check OS Keyring availability directly via Tauri
const keyringAvailable = await checkKeyringAvailable();
const kernelInitialized = await checkKernelInitialized();
// Use keychainAvailable from security-index as primary, keyringAvailable as fallback
const hasSecureStorage = keychainAvailable || keyringAvailable;
// Map local security capabilities to the 16-layer security model
const layers: SecurityLayer[] = [
{
name: 'input.validation',
enabled: true,
description: 'security-utils.ts provides input validation and sanitization',
},
{
name: 'output.filter',
enabled: true,
description: 'security-utils.ts provides output sanitization and content filtering',
},
{
name: 'rate.limit',
enabled: true,
description: 'security-utils.ts provides rate limiting',
},
{
name: 'auth.identity',
enabled: hasSecureStorage,
description: hasSecureStorage
? 'OS Keyring available for secure identity storage'
: 'OS Keyring not available',
},
{
name: 'incident.response',
enabled: auditEnabled,
description: auditEnabled
? 'Automated incident detection and alerting via audit events'
: 'Requires audit logging for incident response',
},
{
name: 'session.management',
enabled: true,
description: 'Session management is always active',
},
{
name: 'auth.rbac',
enabled: hasSecureStorage,
description: hasSecureStorage
? 'Device authentication and role-based access available'
: 'Requires OS Keyring for device authentication',
},
{
name: 'encryption',
enabled: chatStorageInitialized,
description: chatStorageInitialized
? 'Encrypted chat storage is initialized (AES-256-GCM)'
: 'Encrypted storage not yet initialized',
},
{
name: 'audit.logging',
enabled: auditEnabled,
description: auditEnabled
? 'Security audit logging is active'
: 'Audit logging is disabled',
},
{
name: 'integrity',
enabled: auditEnabled,
description: auditEnabled
? 'Integrity verification enabled via audit log'
: 'Requires audit logging for integrity verification',
},
{
name: 'sandbox',
enabled: true,
description: 'Tauri sandbox provides process isolation',
},
{
name: 'network.security',
enabled: true,
description: 'WSS enforced, CSP headers active',
},
{
name: 'resource.limits',
enabled: true,
description: 'Path validation and timeout limits active',
},
{
name: 'capability.gates',
enabled: kernelInitialized,
description: kernelInitialized
? 'Kernel capability gates active'
: 'Kernel not yet initialized',
},
{
name: 'prompt.defense',
enabled: true,
description: 'Input sanitization includes prompt injection defense',
},
{
name: 'anomaly.detection',
enabled: auditEnabled,
description: auditEnabled
? 'Anomaly detection via security audit events'
: 'Requires audit logging for anomaly detection',
},
];
return layers;
}
// === Client Interface ===
interface SecurityClient {
@@ -81,32 +236,22 @@ export const useSecurityStore = create<SecurityStore>((set, get) => ({
client: null,
loadSecurityStatus: async () => {
const client = get().client;
if (!client) return;
set({ securityStatusLoading: true, securityStatusError: null });
try {
const result = await client.getSecurityStatus();
if (result?.layers) {
const layers = result.layers as SecurityLayer[];
const enabledCount = layers.filter(l => l.enabled).length;
const totalCount = layers.length;
const securityLevel = calculateSecurityLevel(enabledCount, totalCount);
set({
securityStatus: { layers, enabledCount, totalCount, securityLevel },
securityStatusLoading: false,
securityStatusError: null,
});
} else {
set({
securityStatusLoading: false,
securityStatusError: 'API returned no data',
});
}
const layers = await buildLocalSecurityLayers();
const enabledCount = layers.filter(l => l.enabled).length;
const totalCount = layers.length;
const securityLevel = calculateSecurityLevel(enabledCount, totalCount);
set({
securityStatus: { layers, enabledCount, totalCount, securityLevel },
securityStatusLoading: false,
securityStatusError: null,
});
} catch (err: unknown) {
const message = err instanceof Error ? err.message : String(err);
set({
securityStatusLoading: false,
securityStatusError: (err instanceof Error ? err.message : String(err)) || 'Security API not available',
securityStatusError: message || 'Failed to detect security status',
});
}
},