@panguard-ai/threat-cloud 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/backup.d.ts +40 -0
  2. package/dist/backup.d.ts.map +1 -0
  3. package/dist/backup.js +123 -0
  4. package/dist/backup.js.map +1 -0
  5. package/dist/cli.js +24 -64
  6. package/dist/cli.js.map +1 -1
  7. package/dist/database.d.ts +58 -36
  8. package/dist/database.d.ts.map +1 -1
  9. package/dist/database.js +279 -328
  10. package/dist/database.js.map +1 -1
  11. package/dist/index.d.ts +4 -10
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -9
  14. package/dist/index.js.map +1 -1
  15. package/dist/llm-reviewer.d.ts +47 -0
  16. package/dist/llm-reviewer.d.ts.map +1 -0
  17. package/dist/llm-reviewer.js +205 -0
  18. package/dist/llm-reviewer.js.map +1 -0
  19. package/dist/server.d.ts +43 -64
  20. package/dist/server.d.ts.map +1 -1
  21. package/dist/server.js +316 -647
  22. package/dist/server.js.map +1 -1
  23. package/dist/types.d.ts +36 -301
  24. package/dist/types.d.ts.map +1 -1
  25. package/package.json +20 -18
  26. package/LICENSE +0 -21
  27. package/dist/audit-logger.d.ts +0 -46
  28. package/dist/audit-logger.d.ts.map +0 -1
  29. package/dist/audit-logger.js +0 -105
  30. package/dist/audit-logger.js.map +0 -1
  31. package/dist/correlation-engine.d.ts +0 -41
  32. package/dist/correlation-engine.d.ts.map +0 -1
  33. package/dist/correlation-engine.js +0 -313
  34. package/dist/correlation-engine.js.map +0 -1
  35. package/dist/feed-distributor.d.ts +0 -36
  36. package/dist/feed-distributor.d.ts.map +0 -1
  37. package/dist/feed-distributor.js +0 -125
  38. package/dist/feed-distributor.js.map +0 -1
  39. package/dist/ioc-store.d.ts +0 -83
  40. package/dist/ioc-store.d.ts.map +0 -1
  41. package/dist/ioc-store.js +0 -278
  42. package/dist/ioc-store.js.map +0 -1
  43. package/dist/query-handlers.d.ts +0 -40
  44. package/dist/query-handlers.d.ts.map +0 -1
  45. package/dist/query-handlers.js +0 -211
  46. package/dist/query-handlers.js.map +0 -1
  47. package/dist/reputation-engine.d.ts +0 -44
  48. package/dist/reputation-engine.d.ts.map +0 -1
  49. package/dist/reputation-engine.js +0 -169
  50. package/dist/reputation-engine.js.map +0 -1
  51. package/dist/rule-generator.d.ts +0 -47
  52. package/dist/rule-generator.d.ts.map +0 -1
  53. package/dist/rule-generator.js +0 -238
  54. package/dist/rule-generator.js.map +0 -1
  55. package/dist/scheduler.d.ts +0 -52
  56. package/dist/scheduler.d.ts.map +0 -1
  57. package/dist/scheduler.js +0 -143
  58. package/dist/scheduler.js.map +0 -1
  59. package/dist/sighting-store.d.ts +0 -61
  60. package/dist/sighting-store.d.ts.map +0 -1
  61. package/dist/sighting-store.js +0 -191
  62. package/dist/sighting-store.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ /**
2
+ * BackupManager - SQLite database backup with rotation
3
+ *
4
+ * Uses WAL checkpoint + file copy for a consistent backup.
5
+ * Keeps the last N backups (default 7) and rotates old ones automatically.
6
+ */
7
+ export interface BackupResult {
8
+ readonly path: string;
9
+ readonly sizeBytes: number;
10
+ readonly timestamp: string;
11
+ }
12
+ export declare class BackupManager {
13
+ private readonly dbPath;
14
+ private readonly backupDir;
15
+ private readonly maxBackups;
16
+ private readonly dbName;
17
+ constructor(dbPath: string, backupDir: string, maxBackups?: number);
18
+ /**
19
+ * Create a consistent backup of the SQLite database.
20
+ *
21
+ * 1. Opens the DB in readonly mode
22
+ * 2. Runs a WAL checkpoint (TRUNCATE) to flush pending writes
23
+ * 3. Copies the database file to the backup directory
24
+ * 4. Rotates old backups beyond maxBackups
25
+ */
26
+ backup(): BackupResult;
27
+ /**
28
+ * Remove old backups beyond maxBackups, keeping the newest ones.
29
+ */
30
+ rotate(): void;
31
+ /**
32
+ * List existing backups for this database, sorted newest-first.
33
+ */
34
+ listBackups(): string[];
35
+ /**
36
+ * Format a byte count as a human-readable string.
37
+ */
38
+ static formatSize(bytes: number): string;
39
+ }
40
+ //# sourceMappingURL=backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,SAAI;IAkB7D;;;;;;;OAOG;IACH,MAAM,IAAI,YAAY;IA0CtB;;OAEG;IACH,MAAM,IAAI,IAAI;IAsBd;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAYvB;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAKzC"}
package/dist/backup.js ADDED
@@ -0,0 +1,123 @@
1
+ /**
2
+ * BackupManager - SQLite database backup with rotation
3
+ *
4
+ * Uses WAL checkpoint + file copy for a consistent backup.
5
+ * Keeps the last N backups (default 7) and rotates old ones automatically.
6
+ */
7
+ import Database from 'better-sqlite3';
8
+ import { existsSync, mkdirSync, readdirSync, unlinkSync, copyFileSync, statSync } from 'node:fs';
9
+ import { join, basename } from 'node:path';
10
+ export class BackupManager {
11
+ dbPath;
12
+ backupDir;
13
+ maxBackups;
14
+ dbName;
15
+ constructor(dbPath, backupDir, maxBackups = 7) {
16
+ if (!dbPath || !backupDir) {
17
+ throw new Error('dbPath and backupDir are required');
18
+ }
19
+ if (maxBackups < 1) {
20
+ throw new Error('maxBackups must be at least 1');
21
+ }
22
+ this.dbPath = dbPath;
23
+ this.backupDir = backupDir;
24
+ this.maxBackups = maxBackups;
25
+ this.dbName = basename(dbPath, '.db');
26
+ if (!existsSync(backupDir)) {
27
+ mkdirSync(backupDir, { recursive: true });
28
+ }
29
+ }
30
+ /**
31
+ * Create a consistent backup of the SQLite database.
32
+ *
33
+ * 1. Opens the DB in readonly mode
34
+ * 2. Runs a WAL checkpoint (TRUNCATE) to flush pending writes
35
+ * 3. Copies the database file to the backup directory
36
+ * 4. Rotates old backups beyond maxBackups
37
+ */
38
+ backup() {
39
+ if (!existsSync(this.dbPath)) {
40
+ throw new Error(`Database file not found: ${this.dbPath}`);
41
+ }
42
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
43
+ const backupFileName = `${this.dbName}-${timestamp}.db`;
44
+ const backupPath = join(this.backupDir, backupFileName);
45
+ // Checkpoint WAL to ensure all data is flushed to the main DB file
46
+ const db = new Database(this.dbPath);
47
+ try {
48
+ db.pragma('wal_checkpoint(TRUNCATE)');
49
+ }
50
+ finally {
51
+ db.close();
52
+ }
53
+ // Copy the database file
54
+ copyFileSync(this.dbPath, backupPath);
55
+ // Also copy WAL/SHM if they exist (belt and suspenders)
56
+ const walPath = `${this.dbPath}-wal`;
57
+ const shmPath = `${this.dbPath}-shm`;
58
+ if (existsSync(walPath)) {
59
+ copyFileSync(walPath, `${backupPath}-wal`);
60
+ }
61
+ if (existsSync(shmPath)) {
62
+ copyFileSync(shmPath, `${backupPath}-shm`);
63
+ }
64
+ const sizeBytes = statSync(backupPath).size;
65
+ // Rotate old backups
66
+ this.rotate();
67
+ return {
68
+ path: backupPath,
69
+ sizeBytes,
70
+ timestamp,
71
+ };
72
+ }
73
+ /**
74
+ * Remove old backups beyond maxBackups, keeping the newest ones.
75
+ */
76
+ rotate() {
77
+ const backups = this.listBackups();
78
+ if (backups.length <= this.maxBackups) {
79
+ return;
80
+ }
81
+ const toDelete = backups.slice(this.maxBackups);
82
+ for (const fileName of toDelete) {
83
+ const filePath = join(this.backupDir, fileName);
84
+ try {
85
+ unlinkSync(filePath);
86
+ // Also clean up WAL/SHM companions
87
+ const walCompanion = `${filePath}-wal`;
88
+ const shmCompanion = `${filePath}-shm`;
89
+ if (existsSync(walCompanion))
90
+ unlinkSync(walCompanion);
91
+ if (existsSync(shmCompanion))
92
+ unlinkSync(shmCompanion);
93
+ }
94
+ catch {
95
+ // Best-effort deletion; log nothing to avoid noise
96
+ }
97
+ }
98
+ }
99
+ /**
100
+ * List existing backups for this database, sorted newest-first.
101
+ */
102
+ listBackups() {
103
+ if (!existsSync(this.backupDir)) {
104
+ return [];
105
+ }
106
+ const prefix = `${this.dbName}-`;
107
+ return readdirSync(this.backupDir)
108
+ .filter((f) => f.startsWith(prefix) && f.endsWith('.db') && !f.endsWith('-wal') && !f.endsWith('-shm'))
109
+ .sort()
110
+ .reverse(); // newest first (ISO timestamps sort lexicographically)
111
+ }
112
+ /**
113
+ * Format a byte count as a human-readable string.
114
+ */
115
+ static formatSize(bytes) {
116
+ if (bytes < 1024)
117
+ return `${bytes} B`;
118
+ if (bytes < 1024 * 1024)
119
+ return `${(bytes / 1024).toFixed(1)} KB`;
120
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
121
+ }
122
+ }
123
+ //# sourceMappingURL=backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -6,41 +6,29 @@
6
6
  * Usage: threat-cloud [--port 8080] [--host 0.0.0.0] [--db ./data/threats.db]
7
7
  */
8
8
  import { ThreatCloudServer } from './server.js';
9
- const MIN_API_KEY_LENGTH = 32;
10
9
  function parseArgs(args) {
11
10
  const config = {};
12
11
  for (let i = 0; i < args.length; i++) {
13
12
  switch (args[i]) {
14
- case '--port': {
15
- const port = Number(args[++i]);
16
- if (isNaN(port) || port < 1 || port > 65535) {
17
- console.error(`Error: Invalid port number. Must be 1-65535.`);
18
- process.exit(1);
19
- }
20
- config.port = port;
13
+ case '--port':
14
+ config.port = Number(args[++i]);
21
15
  break;
22
- }
23
16
  case '--host':
24
17
  config.host = args[++i];
25
18
  break;
26
19
  case '--db':
27
20
  config.dbPath = args[++i];
28
21
  break;
29
- case '--backup-dir':
30
- config.backupDir = args[++i];
31
- break;
32
- case '--api-key': {
33
- const keys = (args[++i] ?? '').split(',').filter(Boolean);
34
- const weak = keys.filter((k) => k.length < MIN_API_KEY_LENGTH);
35
- if (weak.length > 0) {
36
- console.error(`Error: API keys must be at least ${MIN_API_KEY_LENGTH} characters. ` +
37
- `Generate with: openssl rand -hex 32`);
38
- process.exit(1);
39
- }
22
+ case '--api-key':
40
23
  config.apiKeyRequired = true;
41
- config.apiKeys = keys;
24
+ config.apiKeys = (args[++i] ?? '').split(',');
25
+ break;
26
+ case '--anthropic-api-key':
27
+ config.anthropicApiKey = args[++i];
28
+ break;
29
+ case '--admin-api-key':
30
+ config.adminApiKey = args[++i];
42
31
  break;
43
- }
44
32
  case '--help':
45
33
  console.log(`
46
34
  Threat Cloud Server - Collective Threat Intelligence Backend
@@ -48,15 +36,13 @@ Threat Cloud Server - Collective Threat Intelligence Backend
48
36
  Usage: threat-cloud [options]
49
37
 
50
38
  Options:
51
- --port <number> Listen port (default: 8080, range: 1-65535)
52
- --host <string> Listen host (default: 127.0.0.1)
53
- --db <path> SQLite database path (default: ./threat-cloud.db)
54
- --api-key <keys> Comma-separated API keys (min ${MIN_API_KEY_LENGTH} chars each)
55
- --backup-dir <path> Backup directory (default: ./backups)
56
- --help Show this help
57
-
58
- Generate API key:
59
- openssl rand -hex 32
39
+ --port <number> Listen port (default: 8080)
40
+ --host <string> Listen host (default: 127.0.0.1)
41
+ --db <path> SQLite database path (default: ./threat-cloud.db)
42
+ --api-key <keys> Comma-separated API keys (enables auth)
43
+ --anthropic-api-key <key> Anthropic API key for LLM review of ATR proposals
44
+ --admin-api-key <key> Admin key for write-protected endpoints (POST /api/rules)
45
+ --help Show this help
60
46
  `);
61
47
  process.exit(0);
62
48
  }
@@ -65,28 +51,16 @@ Generate API key:
65
51
  }
66
52
  async function main() {
67
53
  const args = parseArgs(process.argv.slice(2));
68
- // Environment variables override defaults; CLI args override env
69
- const envApiKeys = process.env['TC_API_KEYS']?.split(',').filter(Boolean) ?? [];
70
- // Validate env API keys length in production
71
- if (process.env['NODE_ENV'] === 'production' && envApiKeys.length === 0) {
72
- console.error('Error: TC_API_KEYS is required in production mode.');
73
- console.error('Generate with: openssl rand -hex 32');
74
- process.exit(1);
75
- }
76
- const weakEnvKeys = envApiKeys.filter((k) => k.length < MIN_API_KEY_LENGTH);
77
- if (weakEnvKeys.length > 0) {
78
- console.warn(`WARNING: ${weakEnvKeys.length} API key(s) shorter than ${MIN_API_KEY_LENGTH} chars. ` +
79
- `Generate stronger keys with: openssl rand -hex 32`);
80
- }
81
54
  const config = {
82
- port: args.port ?? Number(process.env['TC_PORT'] ?? '8080'),
83
- host: args.host ?? process.env['TC_HOST'] ?? '127.0.0.1',
84
- dbPath: args.dbPath ?? process.env['TC_DB_PATH'] ?? './threat-cloud.db',
85
- apiKeyRequired: args.apiKeyRequired ?? envApiKeys.length > 0,
86
- apiKeys: args.apiKeys ?? envApiKeys,
55
+ port: args.port ?? Number(process.env['PORT'] ?? '8080'),
56
+ host: args.host ?? '0.0.0.0',
57
+ dbPath: args.dbPath ?? process.env['DB_PATH'] ?? './threat-cloud.db',
58
+ apiKeyRequired: args.apiKeyRequired ?? false,
59
+ apiKeys: args.apiKeys ?? [],
87
60
  rateLimitPerMinute: 120,
61
+ anthropicApiKey: args.anthropicApiKey ?? process.env['ANTHROPIC_API_KEY'],
62
+ adminApiKey: args.adminApiKey ?? process.env['TC_ADMIN_API_KEY'],
88
63
  };
89
- const backupDir = args.backupDir ?? process.env['TC_BACKUP_DIR'] ?? './backups';
90
64
  const server = new ThreatCloudServer(config);
91
65
  const shutdown = async () => {
92
66
  console.log('\nShutting down Threat Cloud server...');
@@ -96,20 +70,6 @@ async function main() {
96
70
  process.on('SIGINT', () => void shutdown());
97
71
  process.on('SIGTERM', () => void shutdown());
98
72
  await server.start();
99
- // Schedule daily backup (3am UTC by default)
100
- const runBackup = () => {
101
- const dest = server.getScheduler().runBackup(backupDir);
102
- if (dest) {
103
- console.log(`[Backup] Database backed up to ${dest}`);
104
- }
105
- else {
106
- console.error('[Backup] Database backup failed');
107
- }
108
- };
109
- // Initial backup on startup
110
- runBackup();
111
- // Daily backup interval
112
- setInterval(runBackup, 24 * 60 * 60 * 1000);
113
73
  }
114
74
  void main();
115
75
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,11 @@
2
2
  * SQLite database layer for Threat Cloud
3
3
  * 威脅雲 SQLite 資料庫層
4
4
  *
5
- * Stores anonymized threat data, enriched events, IoCs, campaigns, and rules.
5
+ * Stores anonymized threat data and community rules using better-sqlite3.
6
6
  *
7
7
  * @module @panguard-ai/threat-cloud/database
8
8
  */
9
- import Database from 'better-sqlite3';
10
- import type { AnonymizedThreatData, ThreatCloudRule, ThreatStats, EnrichedThreatEvent, TrapIntelligencePayload } from './types.js';
9
+ import type { AnonymizedThreatData, ThreatCloudRule, ThreatStats, ATRProposal, SkillThreatSubmission } from './types.js';
11
10
  /**
12
11
  * Threat Cloud database backed by SQLite
13
12
  * 基於 SQLite 的威脅雲資料庫
@@ -15,48 +14,71 @@ import type { AnonymizedThreatData, ThreatCloudRule, ThreatStats, EnrichedThreat
15
14
  export declare class ThreatCloudDB {
16
15
  private readonly db;
17
16
  constructor(dbPath: string);
18
- /** Create a backup of the database / 建立資料庫備份 */
19
- backup(destPath: string): void;
20
- /** Expose underlying db for sub-modules (IoCStore, etc.) / 暴露底層 DB 給子模組 */
21
- getDB(): Database.Database;
22
- /** Create original tables if they don't exist / 建立原始資料表 */
17
+ /** Create tables if they don't exist / 建立資料表 */
23
18
  private initialize;
24
- /** Run idempotent schema migrations / 執行冪等 schema 遷移 */
25
- private runMigrations;
26
19
  /** Insert anonymized threat data / 插入匿名化威脅數據 */
27
20
  insertThreat(data: AnonymizedThreatData): void;
28
- /**
29
- * Insert enriched threat event (deduplicates by event_hash).
30
- * Returns the row id if inserted, null if duplicate.
31
- * 插入豐富化威脅事件(以 event_hash 去重)
32
- */
33
- insertEnrichedThreat(event: Omit<EnrichedThreatEvent, 'id'>): number | null;
34
- /**
35
- * Insert trap credential records.
36
- * Usernames are hashed (SHA-256, truncated to 16 hex chars) before storage
37
- * to avoid storing PII from attacker-attempted credentials.
38
- * 插入 Trap 憑證記錄(使用者名稱先雜湊化以避免 PII 洩漏)
39
- */
40
- insertTrapCredentials(enrichedThreatId: number, credentials: Array<{
41
- username: string;
42
- count: number;
43
- }>): void;
44
- /** Get enriched threats count by source type / 依來源類型取得豐富化威脅數量 */
45
- getEnrichedThreatCountBySource(): Record<string, number>;
46
- /** Count related threats for an IP / 計算某 IP 的相關威脅數量 */
47
- countRelatedThreats(ip: string): number;
48
- /** Convert AnonymizedThreatData to EnrichedThreatEvent / 轉換 Guard 資料 */
49
- static guardToEnriched(data: AnonymizedThreatData): Omit<EnrichedThreatEvent, 'id'>;
50
- /** Convert TrapIntelligencePayload to EnrichedThreatEvent / 轉換 Trap 資料 */
51
- static trapToEnriched(data: TrapIntelligencePayload): Omit<EnrichedThreatEvent, 'id'>;
52
21
  /** Insert or update a community rule / 插入或更新社群規則 */
53
22
  upsertRule(rule: ThreatCloudRule): void;
54
23
  /** Fetch rules published after a given timestamp / 取得指定時間後發佈的規則 */
55
24
  getRulesSince(since: string): ThreatCloudRule[];
56
- /** Fetch all rules / 取得所有規則 */
57
- getAllRules(): ThreatCloudRule[];
25
+ /** Fetch all rules with limit / 取得所有規則(含限制) */
26
+ getAllRules(limit?: number): ThreatCloudRule[];
27
+ /** Insert ATR rule proposal / 插入 ATR 規則提案 */
28
+ insertATRProposal(proposal: ATRProposal): void;
29
+ /** Get ATR proposals, optionally filtered by status / 取得 ATR 提案 */
30
+ getATRProposals(status?: string): unknown[];
31
+ /** Increment confirmations for a proposal; auto-confirm at >= 3 / 增加提案確認數 */
32
+ confirmATRProposal(patternHash: string): void;
33
+ /** Update LLM review verdict for a proposal / 更新 LLM 審查結果 */
34
+ updateATRProposalLLMReview(patternHash: string, verdict: string): void;
35
+ /** Insert ATR feedback / 插入 ATR 回饋 */
36
+ insertATRFeedback(ruleId: string, isTruePositive: boolean, clientId?: string): void;
37
+ /** Get feedback stats for a rule / 取得規則回饋統計 */
38
+ getATRFeedbackStats(ruleId: string): {
39
+ truePositives: number;
40
+ falsePositives: number;
41
+ };
42
+ /** Insert skill threat submission / 插入技能威脅提交 */
43
+ insertSkillThreat(submission: SkillThreatSubmission): void;
44
+ /** Get recent skill threats / 取得最近技能威脅 */
45
+ getSkillThreats(limit?: number): unknown[];
46
+ /** Get proposal statistics / 取得提案統計 */
47
+ getProposalStats(): {
48
+ pending: number;
49
+ confirmed: number;
50
+ rejected: number;
51
+ total: number;
52
+ };
58
53
  /** Get threat statistics / 取得威脅統計 */
59
54
  getStats(): ThreatStats;
55
+ /** Get confirmed/promoted ATR rules, optionally filtered by date / 取得已確認 ATR 規則 */
56
+ getConfirmedATRRules(since?: string): Array<{
57
+ ruleId: string;
58
+ ruleContent: string;
59
+ publishedAt: string;
60
+ source: string;
61
+ }>;
62
+ /** Get IP blocklist from IoC entries and aggregated threat data / 取得 IP 封鎖清單 */
63
+ getIPBlocklist(minReputation: number): string[];
64
+ /** Get domain blocklist from IoC entries / 取得域名封鎖清單 */
65
+ getDomainBlocklist(minReputation: number): string[];
66
+ /** Upsert an IoC entry / 插入或更新 IoC 條目 */
67
+ upsertIoC(type: string, value: string, reputation: number, source: string): void;
68
+ /** Promote confirmed proposals with approved LLM review to rules / 推廣已確認提案為規則 */
69
+ promoteConfirmedProposals(): number;
70
+ /** Reject an ATR proposal / 拒絕 ATR 提案 */
71
+ rejectATRProposal(patternHash: string): void;
72
+ /** Get rules by source type, optionally filtered by date / 依來源取得規則 */
73
+ getRulesBySource(source: string, since?: string): ThreatCloudRule[];
74
+ /** Report a safe skill (increment confirmations, auto-confirm at 3+) / 回報安全 skill */
75
+ reportSafeSkill(skillName: string, fingerprintHash?: string): void;
76
+ /** Get confirmed community whitelist / 取得社群白名單 */
77
+ getSkillWhitelist(): Array<{
78
+ name: string;
79
+ hash: string | null;
80
+ confirmations: number;
81
+ }>;
60
82
  /** Close the database / 關閉資料庫 */
61
83
  close(): void;
62
84
  }
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,EAAE,MAAM;IAc1B,gDAAgD;IAChD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI9B,2EAA2E;IAC3E,KAAK,IAAI,QAAQ,CAAC,QAAQ;IAQ1B,2DAA2D;IAC3D,OAAO,CAAC,UAAU;IAoClB,wDAAwD;IACxD,OAAO,CAAC,aAAa;IAoMrB,gDAAgD;IAChD,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAoB9C;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI;IA4B3E;;;;;OAKG;IACH,qBAAqB,CACnB,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GACtD,IAAI;IAaP,iEAAiE;IACjE,8BAA8B,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAWxD,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAYvC,wEAAwE;IACxE,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;IAoBnF,0EAA0E;IAC1E,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;IA4BrF,oDAAoD;IACpD,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAavC,mEAAmE;IACnE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE;IAU/C,+BAA+B;IAC/B,WAAW,IAAI,eAAe,EAAE;IAahC,qCAAqC;IACrC,QAAQ,IAAI,WAAW;IAiDvB,iCAAiC;IACjC,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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"}