@panguard-ai/panguard-guard 0.1.0

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 (130) hide show
  1. package/dist/agent/analyze-agent.d.ts +62 -0
  2. package/dist/agent/analyze-agent.d.ts.map +1 -0
  3. package/dist/agent/analyze-agent.js +327 -0
  4. package/dist/agent/analyze-agent.js.map +1 -0
  5. package/dist/agent/detect-agent.d.ts +59 -0
  6. package/dist/agent/detect-agent.d.ts.map +1 -0
  7. package/dist/agent/detect-agent.js +214 -0
  8. package/dist/agent/detect-agent.js.map +1 -0
  9. package/dist/agent/index.d.ts +15 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +14 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/report-agent.d.ts +122 -0
  14. package/dist/agent/report-agent.d.ts.map +1 -0
  15. package/dist/agent/report-agent.js +468 -0
  16. package/dist/agent/report-agent.js.map +1 -0
  17. package/dist/agent/respond-agent.d.ts +113 -0
  18. package/dist/agent/respond-agent.d.ts.map +1 -0
  19. package/dist/agent/respond-agent.js +749 -0
  20. package/dist/agent/respond-agent.js.map +1 -0
  21. package/dist/agent-client/index.d.ts +81 -0
  22. package/dist/agent-client/index.d.ts.map +1 -0
  23. package/dist/agent-client/index.js +170 -0
  24. package/dist/agent-client/index.js.map +1 -0
  25. package/dist/cli/index.d.ts +17 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/index.js +295 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/config.d.ts +23 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +108 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/daemon/index.d.ts +66 -0
  34. package/dist/daemon/index.d.ts.map +1 -0
  35. package/dist/daemon/index.js +284 -0
  36. package/dist/daemon/index.js.map +1 -0
  37. package/dist/dashboard/index.d.ts +78 -0
  38. package/dist/dashboard/index.d.ts.map +1 -0
  39. package/dist/dashboard/index.js +455 -0
  40. package/dist/dashboard/index.js.map +1 -0
  41. package/dist/guard-engine.d.ts +108 -0
  42. package/dist/guard-engine.d.ts.map +1 -0
  43. package/dist/guard-engine.js +740 -0
  44. package/dist/guard-engine.js.map +1 -0
  45. package/dist/index.d.ts +29 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +39 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/install/index.d.ts +23 -0
  50. package/dist/install/index.d.ts.map +1 -0
  51. package/dist/install/index.js +216 -0
  52. package/dist/install/index.js.map +1 -0
  53. package/dist/investigation/index.d.ts +80 -0
  54. package/dist/investigation/index.d.ts.map +1 -0
  55. package/dist/investigation/index.js +570 -0
  56. package/dist/investigation/index.js.map +1 -0
  57. package/dist/license/index.d.ts +46 -0
  58. package/dist/license/index.d.ts.map +1 -0
  59. package/dist/license/index.js +145 -0
  60. package/dist/license/index.js.map +1 -0
  61. package/dist/memory/baseline.d.ts +34 -0
  62. package/dist/memory/baseline.d.ts.map +1 -0
  63. package/dist/memory/baseline.js +224 -0
  64. package/dist/memory/baseline.js.map +1 -0
  65. package/dist/memory/index.d.ts +32 -0
  66. package/dist/memory/index.d.ts.map +1 -0
  67. package/dist/memory/index.js +58 -0
  68. package/dist/memory/index.js.map +1 -0
  69. package/dist/memory/learning.d.ts +35 -0
  70. package/dist/memory/learning.d.ts.map +1 -0
  71. package/dist/memory/learning.js +60 -0
  72. package/dist/memory/learning.js.map +1 -0
  73. package/dist/monitors/falco-monitor.d.ts +62 -0
  74. package/dist/monitors/falco-monitor.d.ts.map +1 -0
  75. package/dist/monitors/falco-monitor.js +226 -0
  76. package/dist/monitors/falco-monitor.js.map +1 -0
  77. package/dist/monitors/suricata-monitor.d.ts +80 -0
  78. package/dist/monitors/suricata-monitor.d.ts.map +1 -0
  79. package/dist/monitors/suricata-monitor.js +227 -0
  80. package/dist/monitors/suricata-monitor.js.map +1 -0
  81. package/dist/notify/email.d.ts +23 -0
  82. package/dist/notify/email.d.ts.map +1 -0
  83. package/dist/notify/email.js +124 -0
  84. package/dist/notify/email.js.map +1 -0
  85. package/dist/notify/index.d.ts +31 -0
  86. package/dist/notify/index.d.ts.map +1 -0
  87. package/dist/notify/index.js +70 -0
  88. package/dist/notify/index.js.map +1 -0
  89. package/dist/notify/line-notify.d.ts.map +1 -0
  90. package/dist/notify/slack.d.ts +21 -0
  91. package/dist/notify/slack.d.ts.map +1 -0
  92. package/dist/notify/slack.js +92 -0
  93. package/dist/notify/slack.js.map +1 -0
  94. package/dist/notify/telegram.d.ts +21 -0
  95. package/dist/notify/telegram.d.ts.map +1 -0
  96. package/dist/notify/telegram.js +89 -0
  97. package/dist/notify/telegram.js.map +1 -0
  98. package/dist/response/file-quarantine.d.ts +63 -0
  99. package/dist/response/file-quarantine.d.ts.map +1 -0
  100. package/dist/response/file-quarantine.js +137 -0
  101. package/dist/response/file-quarantine.js.map +1 -0
  102. package/dist/response/index.d.ts +4 -0
  103. package/dist/response/index.d.ts.map +1 -0
  104. package/dist/response/index.js +4 -0
  105. package/dist/response/index.js.map +1 -0
  106. package/dist/response/ip-blocker.d.ts +69 -0
  107. package/dist/response/ip-blocker.d.ts.map +1 -0
  108. package/dist/response/ip-blocker.js +191 -0
  109. package/dist/response/ip-blocker.js.map +1 -0
  110. package/dist/response/process-killer.d.ts +49 -0
  111. package/dist/response/process-killer.d.ts.map +1 -0
  112. package/dist/response/process-killer.js +230 -0
  113. package/dist/response/process-killer.js.map +1 -0
  114. package/dist/rules/builtin-rules.d.ts +12 -0
  115. package/dist/rules/builtin-rules.d.ts.map +1 -0
  116. package/dist/rules/builtin-rules.js +471 -0
  117. package/dist/rules/builtin-rules.js.map +1 -0
  118. package/dist/threat-cloud/client-id.d.ts +13 -0
  119. package/dist/threat-cloud/client-id.d.ts.map +1 -0
  120. package/dist/threat-cloud/client-id.js +38 -0
  121. package/dist/threat-cloud/client-id.js.map +1 -0
  122. package/dist/threat-cloud/index.d.ts +103 -0
  123. package/dist/threat-cloud/index.d.ts.map +1 -0
  124. package/dist/threat-cloud/index.js +386 -0
  125. package/dist/threat-cloud/index.js.map +1 -0
  126. package/dist/types.d.ts +336 -0
  127. package/dist/types.d.ts.map +1 -0
  128. package/dist/types.js +42 -0
  129. package/dist/types.js.map +1 -0
  130. package/package.json +35 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * GuardConfig loader and defaults
3
+ * GuardConfig 載入器與預設值
4
+ * @module @panguard-ai/panguard-guard/config
5
+ */
6
+ import type { GuardConfig } from './types.js';
7
+ /** Default data directory / 預設資料目錄 */
8
+ export declare const DEFAULT_DATA_DIR: string;
9
+ /** Default configuration / 預設配置 */
10
+ export declare const DEFAULT_GUARD_CONFIG: GuardConfig;
11
+ /**
12
+ * Load configuration from JSON file / 從 JSON 檔案載入配置
13
+ */
14
+ export declare function loadConfig(configPath?: string): GuardConfig;
15
+ /**
16
+ * Save configuration to JSON file / 儲存配置到 JSON 檔案
17
+ */
18
+ export declare function saveConfig(config: GuardConfig, configPath?: string): void;
19
+ /**
20
+ * Ensure data directory exists / 確保資料目錄存在
21
+ */
22
+ export declare function ensureDataDir(dataDir: string): void;
23
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,sCAAsC;AACtC,eAAO,MAAM,gBAAgB,QAAqC,CAAC;AAqBnE,mCAAmC;AACnC,eAAO,MAAM,oBAAoB,EAAE,WAwBlC,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAyB3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAUzE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKnD"}
package/dist/config.js ADDED
@@ -0,0 +1,108 @@
1
+ /**
2
+ * GuardConfig loader and defaults
3
+ * GuardConfig 載入器與預設值
4
+ * @module @panguard-ai/panguard-guard/config
5
+ */
6
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
7
+ import { join, dirname } from 'node:path';
8
+ import { homedir } from 'node:os';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { createLogger } from '@panguard-ai/core';
11
+ import { DEFAULT_ACTION_POLICY } from './types.js';
12
+ const logger = createLogger('panguard-guard:config');
13
+ /** Default data directory / 預設資料目錄 */
14
+ export const DEFAULT_DATA_DIR = join(homedir(), '.panguard-guard');
15
+ /**
16
+ * Resolve the bundled rules directory from the installation root.
17
+ * Walks up from this file's location to find the monorepo config/ directory.
18
+ * 從安裝根目錄解析內建規則目錄。
19
+ */
20
+ function findBundledDir(subdir) {
21
+ const thisDir = dirname(fileURLToPath(import.meta.url));
22
+ // Walk up to find the monorepo root (contains config/)
23
+ let dir = thisDir;
24
+ for (let i = 0; i < 8; i++) {
25
+ const candidate = join(dir, 'config', subdir);
26
+ if (existsSync(candidate)) {
27
+ return candidate;
28
+ }
29
+ dir = dirname(dir);
30
+ }
31
+ return undefined;
32
+ }
33
+ /** Default configuration / 預設配置 */
34
+ export const DEFAULT_GUARD_CONFIG = {
35
+ lang: 'zh-TW',
36
+ mode: 'learning',
37
+ learningDays: 7,
38
+ actionPolicy: DEFAULT_ACTION_POLICY,
39
+ notifications: {},
40
+ dataDir: DEFAULT_DATA_DIR,
41
+ yaraRulesDir: join(DEFAULT_DATA_DIR, 'yara-rules'),
42
+ bundledSigmaDir: findBundledDir('sigma-rules'),
43
+ bundledYaraDir: findBundledDir('yara-rules'),
44
+ dashboardPort: 3100,
45
+ dashboardEnabled: true,
46
+ verbose: false,
47
+ monitors: {
48
+ logMonitor: true,
49
+ networkMonitor: true,
50
+ processMonitor: true,
51
+ fileMonitor: true,
52
+ networkPollInterval: 30000,
53
+ processPollInterval: 15000,
54
+ },
55
+ watchdogEnabled: true,
56
+ watchdogInterval: 60000,
57
+ threatCloudEndpoint: 'https://tc.panguard.ai/api',
58
+ };
59
+ /**
60
+ * Load configuration from JSON file / 從 JSON 檔案載入配置
61
+ */
62
+ export function loadConfig(configPath) {
63
+ const path = configPath ?? join(DEFAULT_DATA_DIR, 'config.json');
64
+ if (!existsSync(path)) {
65
+ logger.info(`No config file found at ${path}, using defaults / 找不到配置檔,使用預設值`);
66
+ return { ...DEFAULT_GUARD_CONFIG };
67
+ }
68
+ try {
69
+ const raw = readFileSync(path, 'utf-8');
70
+ const parsed = JSON.parse(raw);
71
+ const merged = {
72
+ ...DEFAULT_GUARD_CONFIG,
73
+ ...parsed,
74
+ actionPolicy: { ...DEFAULT_ACTION_POLICY, ...(parsed.actionPolicy ?? {}) },
75
+ notifications: { ...DEFAULT_GUARD_CONFIG.notifications, ...(parsed.notifications ?? {}) },
76
+ monitors: { ...DEFAULT_GUARD_CONFIG.monitors, ...(parsed.monitors ?? {}) },
77
+ };
78
+ logger.info(`Loaded config from ${path} / 已從 ${path} 載入配置`);
79
+ return merged;
80
+ }
81
+ catch (err) {
82
+ const msg = err instanceof Error ? err.message : String(err);
83
+ logger.error(`Failed to load config: ${msg} / 載入配置失敗: ${msg}`);
84
+ return { ...DEFAULT_GUARD_CONFIG };
85
+ }
86
+ }
87
+ /**
88
+ * Save configuration to JSON file / 儲存配置到 JSON 檔案
89
+ */
90
+ export function saveConfig(config, configPath) {
91
+ const path = configPath ?? join(config.dataDir, 'config.json');
92
+ const dir = join(path, '..');
93
+ if (!existsSync(dir)) {
94
+ mkdirSync(dir, { recursive: true });
95
+ }
96
+ writeFileSync(path, JSON.stringify(config, null, 2), 'utf-8');
97
+ logger.info(`Saved config to ${path} / 已儲存配置到 ${path}`);
98
+ }
99
+ /**
100
+ * Ensure data directory exists / 確保資料目錄存在
101
+ */
102
+ export function ensureDataDir(dataDir) {
103
+ if (!existsSync(dataDir)) {
104
+ mkdirSync(dataDir, { recursive: true });
105
+ logger.info(`Created data directory: ${dataDir} / 已建立資料目錄: ${dataDir}`);
106
+ }
107
+ }
108
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Daemon / Service Management
3
+ * Daemon / 服務管理
4
+ *
5
+ * Cross-platform daemon support:
6
+ * - macOS: launchd plist
7
+ * - Linux: systemd unit file
8
+ * - Windows: sc.exe service
9
+ * Includes PID file management and watchdog functionality.
10
+ *
11
+ * 跨平台 daemon 支援:
12
+ * - macOS: launchd plist
13
+ * - Linux: systemd unit 檔案
14
+ * - Windows: sc.exe 服務
15
+ * 包含 PID 檔案管理和看門狗功能。
16
+ *
17
+ * @module @panguard-ai/panguard-guard/daemon
18
+ */
19
+ /**
20
+ * PID file management / PID 檔案管理
21
+ */
22
+ export declare class PidFile {
23
+ private readonly pidPath;
24
+ constructor(dataDir: string);
25
+ /** Write current PID to file / 將目前 PID 寫入檔案 */
26
+ write(): void;
27
+ /** Read PID from file / 從檔案讀取 PID */
28
+ read(): number | null;
29
+ /** Remove PID file / 移除 PID 檔案 */
30
+ remove(): void;
31
+ /** Check if process with stored PID is running / 檢查儲存的 PID 程序是否執行中 */
32
+ isRunning(): boolean;
33
+ }
34
+ /**
35
+ * Watchdog - monitors the guard engine and restarts if needed
36
+ * 看門狗 - 監控守護引擎,需要時重新啟動
37
+ */
38
+ export declare class Watchdog {
39
+ private timer;
40
+ private readonly intervalMs;
41
+ private lastHeartbeat;
42
+ private readonly onFailure;
43
+ /**
44
+ * @param intervalMs - Check interval in milliseconds / 檢查間隔(毫秒)
45
+ * @param onFailure - Callback when engine appears unresponsive / 引擎無回應時的回呼
46
+ */
47
+ constructor(intervalMs: number, onFailure: () => void);
48
+ /** Start watchdog monitoring / 啟動看門狗監控 */
49
+ start(): void;
50
+ /** Record a heartbeat / 記錄心跳 */
51
+ heartbeat(): void;
52
+ /** Stop watchdog / 停止看門狗 */
53
+ stop(): void;
54
+ }
55
+ /**
56
+ * Install as a system service / 安裝為系統服務
57
+ *
58
+ * @param execPath - Path to the panguard-guard executable / PanguardGuard 可執行檔路徑
59
+ * @param dataDir - Data directory path / 資料目錄路徑
60
+ */
61
+ export declare function installService(execPath: string, dataDir: string): Promise<string>;
62
+ /**
63
+ * Uninstall system service / 解除安裝系統服務
64
+ */
65
+ export declare function uninstallService(): Promise<string>;
66
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAcH;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,MAAM;IAI3B,+CAA+C;IAC/C,KAAK,IAAI,IAAI;IAMb,qCAAqC;IACrC,IAAI,IAAI,MAAM,GAAG,IAAI;IAUrB,kCAAkC;IAClC,MAAM,IAAI,IAAI;IAYd,sEAAsE;IACtE,SAAS,IAAI,OAAO;CAUrB;AAED;;;GAGG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IAEvC;;;OAGG;gBACS,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI;IAKrD,0CAA0C;IAC1C,KAAK,IAAI,IAAI;IAuBb,gCAAgC;IAChC,SAAS,IAAI,IAAI;IAIjB,4BAA4B;IAC5B,IAAI,IAAI,IAAI;CAOb;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAavF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAaxD"}
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Daemon / Service Management
3
+ * Daemon / 服務管理
4
+ *
5
+ * Cross-platform daemon support:
6
+ * - macOS: launchd plist
7
+ * - Linux: systemd unit file
8
+ * - Windows: sc.exe service
9
+ * Includes PID file management and watchdog functionality.
10
+ *
11
+ * 跨平台 daemon 支援:
12
+ * - macOS: launchd plist
13
+ * - Linux: systemd unit 檔案
14
+ * - Windows: sc.exe 服務
15
+ * 包含 PID 檔案管理和看門狗功能。
16
+ *
17
+ * @module @panguard-ai/panguard-guard/daemon
18
+ */
19
+ import { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from 'node:fs';
20
+ import { execFile } from 'node:child_process';
21
+ import { platform, homedir } from 'node:os';
22
+ import { join, dirname } from 'node:path';
23
+ import { createLogger } from '@panguard-ai/core';
24
+ const logger = createLogger('panguard-guard:daemon');
25
+ /** Service name constants / 服務名稱常數 */
26
+ const SERVICE_NAME = 'com.panguard.panguard-guard';
27
+ const SERVICE_DISPLAY_NAME = 'PanguardGuard Security Monitor';
28
+ /**
29
+ * PID file management / PID 檔案管理
30
+ */
31
+ export class PidFile {
32
+ pidPath;
33
+ constructor(dataDir) {
34
+ this.pidPath = join(dataDir, 'panguard-guard.pid');
35
+ }
36
+ /** Write current PID to file / 將目前 PID 寫入檔案 */
37
+ write() {
38
+ mkdirSync(dirname(this.pidPath), { recursive: true });
39
+ writeFileSync(this.pidPath, String(process.pid), 'utf-8');
40
+ logger.info(`PID file written: ${this.pidPath} (PID: ${process.pid}) / PID 檔案已寫入`);
41
+ }
42
+ /** Read PID from file / 從檔案讀取 PID */
43
+ read() {
44
+ try {
45
+ if (!existsSync(this.pidPath))
46
+ return null;
47
+ const pid = parseInt(readFileSync(this.pidPath, 'utf-8').trim(), 10);
48
+ return isNaN(pid) ? null : pid;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /** Remove PID file / 移除 PID 檔案 */
55
+ remove() {
56
+ try {
57
+ if (existsSync(this.pidPath)) {
58
+ unlinkSync(this.pidPath);
59
+ logger.info('PID file removed / PID 檔案已移除');
60
+ }
61
+ }
62
+ catch (err) {
63
+ const msg = err instanceof Error ? err.message : String(err);
64
+ logger.error(`Failed to remove PID file: ${msg} / 移除 PID 檔案失敗`);
65
+ }
66
+ }
67
+ /** Check if process with stored PID is running / 檢查儲存的 PID 程序是否執行中 */
68
+ isRunning() {
69
+ const pid = this.read();
70
+ if (pid === null)
71
+ return false;
72
+ try {
73
+ process.kill(pid, 0);
74
+ return true;
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
80
+ }
81
+ /**
82
+ * Watchdog - monitors the guard engine and restarts if needed
83
+ * 看門狗 - 監控守護引擎,需要時重新啟動
84
+ */
85
+ export class Watchdog {
86
+ timer = null;
87
+ intervalMs;
88
+ lastHeartbeat = Date.now();
89
+ onFailure;
90
+ /**
91
+ * @param intervalMs - Check interval in milliseconds / 檢查間隔(毫秒)
92
+ * @param onFailure - Callback when engine appears unresponsive / 引擎無回應時的回呼
93
+ */
94
+ constructor(intervalMs, onFailure) {
95
+ this.intervalMs = intervalMs;
96
+ this.onFailure = onFailure;
97
+ }
98
+ /** Start watchdog monitoring / 啟動看門狗監控 */
99
+ start() {
100
+ if (this.timer)
101
+ return;
102
+ this.lastHeartbeat = Date.now();
103
+ this.timer = setInterval(() => {
104
+ const elapsed = Date.now() - this.lastHeartbeat;
105
+ // If no heartbeat for 3x the interval, trigger failure
106
+ // 如果超過 3 倍間隔無心跳,觸發失敗
107
+ if (elapsed > this.intervalMs * 3) {
108
+ logger.error(`Watchdog: no heartbeat for ${elapsed}ms, triggering restart / ` +
109
+ `看門狗: ${elapsed}ms 無心跳,觸發重啟`);
110
+ this.onFailure();
111
+ }
112
+ }, this.intervalMs);
113
+ logger.info(`Watchdog started with ${this.intervalMs}ms interval / ` +
114
+ `看門狗已啟動,間隔 ${this.intervalMs}ms`);
115
+ }
116
+ /** Record a heartbeat / 記錄心跳 */
117
+ heartbeat() {
118
+ this.lastHeartbeat = Date.now();
119
+ }
120
+ /** Stop watchdog / 停止看門狗 */
121
+ stop() {
122
+ if (this.timer) {
123
+ clearInterval(this.timer);
124
+ this.timer = null;
125
+ logger.info('Watchdog stopped / 看門狗已停止');
126
+ }
127
+ }
128
+ }
129
+ /**
130
+ * Install as a system service / 安裝為系統服務
131
+ *
132
+ * @param execPath - Path to the panguard-guard executable / PanguardGuard 可執行檔路徑
133
+ * @param dataDir - Data directory path / 資料目錄路徑
134
+ */
135
+ export async function installService(execPath, dataDir) {
136
+ const os = platform();
137
+ switch (os) {
138
+ case 'darwin':
139
+ return installLaunchd(execPath, dataDir);
140
+ case 'linux':
141
+ return installSystemd(execPath, dataDir);
142
+ case 'win32':
143
+ return installWindowsService(execPath);
144
+ default:
145
+ throw new Error(`Unsupported platform: ${os} / 不支援的平台: ${os}`);
146
+ }
147
+ }
148
+ /**
149
+ * Uninstall system service / 解除安裝系統服務
150
+ */
151
+ export async function uninstallService() {
152
+ const os = platform();
153
+ switch (os) {
154
+ case 'darwin':
155
+ return uninstallLaunchd();
156
+ case 'linux':
157
+ return uninstallSystemd();
158
+ case 'win32':
159
+ return uninstallWindowsService();
160
+ default:
161
+ throw new Error(`Unsupported platform: ${os} / 不支援的平台: ${os}`);
162
+ }
163
+ }
164
+ // ---------------------------------------------------------------------------
165
+ // macOS launchd / macOS launchd
166
+ // ---------------------------------------------------------------------------
167
+ async function installLaunchd(execPath, dataDir) {
168
+ const plistPath = join(homedir(), 'Library', 'LaunchAgents', `${SERVICE_NAME}.plist`);
169
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
170
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
171
+ <plist version="1.0">
172
+ <dict>
173
+ <key>Label</key>
174
+ <string>${SERVICE_NAME}</string>
175
+ <key>ProgramArguments</key>
176
+ <array>
177
+ <string>${execPath}</string>
178
+ <string>start</string>
179
+ <string>--data-dir</string>
180
+ <string>${dataDir}</string>
181
+ </array>
182
+ <key>RunAtLoad</key>
183
+ <true/>
184
+ <key>KeepAlive</key>
185
+ <true/>
186
+ <key>StandardOutPath</key>
187
+ <string>${join(dataDir, 'panguard-guard.log')}</string>
188
+ <key>StandardErrorPath</key>
189
+ <string>${join(dataDir, 'panguard-guard-error.log')}</string>
190
+ </dict>
191
+ </plist>`;
192
+ mkdirSync(dirname(plistPath), { recursive: true });
193
+ writeFileSync(plistPath, plist, 'utf-8');
194
+ await execFileAsync('/bin/launchctl', ['load', plistPath]);
195
+ logger.info(`launchd service installed at ${plistPath} / launchd 服務已安裝`);
196
+ return plistPath;
197
+ }
198
+ async function uninstallLaunchd() {
199
+ const plistPath = join(homedir(), 'Library', 'LaunchAgents', `${SERVICE_NAME}.plist`);
200
+ if (existsSync(plistPath)) {
201
+ await execFileAsync('/bin/launchctl', ['unload', plistPath]);
202
+ unlinkSync(plistPath);
203
+ logger.info('launchd service uninstalled / launchd 服務已解除安裝');
204
+ }
205
+ return plistPath;
206
+ }
207
+ // ---------------------------------------------------------------------------
208
+ // Linux systemd / Linux systemd
209
+ // ---------------------------------------------------------------------------
210
+ async function installSystemd(execPath, dataDir) {
211
+ const unitPath = `/etc/systemd/system/${SERVICE_NAME}.service`;
212
+ const unit = `[Unit]
213
+ Description=${SERVICE_DISPLAY_NAME}
214
+ After=network.target
215
+
216
+ [Service]
217
+ Type=simple
218
+ ExecStart=${execPath} start --data-dir ${dataDir}
219
+ Restart=always
220
+ RestartSec=10
221
+ StandardOutput=journal
222
+ StandardError=journal
223
+
224
+ [Install]
225
+ WantedBy=multi-user.target
226
+ `;
227
+ writeFileSync(unitPath, unit, 'utf-8');
228
+ await execFileAsync('/bin/systemctl', ['daemon-reload']);
229
+ await execFileAsync('/bin/systemctl', ['enable', SERVICE_NAME]);
230
+ await execFileAsync('/bin/systemctl', ['start', SERVICE_NAME]);
231
+ logger.info(`systemd service installed at ${unitPath} / systemd 服務已安裝`);
232
+ return unitPath;
233
+ }
234
+ async function uninstallSystemd() {
235
+ const unitPath = `/etc/systemd/system/${SERVICE_NAME}.service`;
236
+ await execFileAsync('/bin/systemctl', ['stop', SERVICE_NAME]);
237
+ await execFileAsync('/bin/systemctl', ['disable', SERVICE_NAME]);
238
+ if (existsSync(unitPath)) {
239
+ unlinkSync(unitPath);
240
+ await execFileAsync('/bin/systemctl', ['daemon-reload']);
241
+ }
242
+ logger.info('systemd service uninstalled / systemd 服務已解除安裝');
243
+ return unitPath;
244
+ }
245
+ // ---------------------------------------------------------------------------
246
+ // Windows sc.exe / Windows sc.exe
247
+ // ---------------------------------------------------------------------------
248
+ async function installWindowsService(execPath) {
249
+ await execFileAsync('sc', [
250
+ 'create',
251
+ SERVICE_NAME,
252
+ `binpath=${execPath} start`,
253
+ `displayname=${SERVICE_DISPLAY_NAME}`,
254
+ 'start=auto',
255
+ ]);
256
+ await execFileAsync('sc', ['start', SERVICE_NAME]);
257
+ logger.info('Windows service installed / Windows 服務已安裝');
258
+ return SERVICE_NAME;
259
+ }
260
+ async function uninstallWindowsService() {
261
+ try {
262
+ execFileAsync('sc', ['stop', SERVICE_NAME]);
263
+ }
264
+ catch {
265
+ // Service may not be running / 服務可能未執行
266
+ }
267
+ await execFileAsync('sc', ['delete', SERVICE_NAME]);
268
+ logger.info('Windows service uninstalled / Windows 服務已解除安裝');
269
+ return SERVICE_NAME;
270
+ }
271
+ // ---------------------------------------------------------------------------
272
+ // Async execFile helper / 非同步 execFile 輔助函數
273
+ // ---------------------------------------------------------------------------
274
+ function execFileAsync(command, args) {
275
+ return new Promise((resolve, reject) => {
276
+ execFile(command, args, { timeout: 15000 }, (error) => {
277
+ if (error)
278
+ reject(error);
279
+ else
280
+ resolve();
281
+ });
282
+ });
283
+ }
284
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Web Dashboard - Real-time monitoring interface
3
+ * Web Dashboard - 即時監控介面
4
+ *
5
+ * Provides an HTTP server with WebSocket push for:
6
+ * - System status overview / 系統狀態概覽
7
+ * - Event timeline / 事件時間軸
8
+ * - Threat map visualization / 威脅地圖視覺化
9
+ * - Configuration management / 配置管理
10
+ * - Language toggle (EN/ZH) / 語言切換
11
+ *
12
+ * Uses only Node.js built-in http module with native WebSocket handshake.
13
+ * 僅使用 Node.js 內建 http 模組搭配原生 WebSocket 交握。
14
+ *
15
+ * @module @panguard-ai/panguard-guard/dashboard
16
+ */
17
+ import type { DashboardStatus, DashboardEvent, ThreatMapEntry, GuardConfig, ThreatVerdict } from '../types.js';
18
+ /**
19
+ * Dashboard Server manages the HTTP + WebSocket real-time dashboard
20
+ * Dashboard 伺服器管理 HTTP + WebSocket 即時儀表板
21
+ */
22
+ export declare class DashboardServer {
23
+ private server;
24
+ private wsClients;
25
+ private status;
26
+ private recentEvents;
27
+ private threatMap;
28
+ private readonly maxRecentEvents;
29
+ private readonly port;
30
+ private getConfig;
31
+ /** API authentication token / API 認證 token */
32
+ private readonly authToken;
33
+ /** Rate limiter state / 速率限制狀態 */
34
+ private rateLimits;
35
+ constructor(port: number);
36
+ /**
37
+ * Set config getter for the settings API / 設定配置 getter 用於設定 API
38
+ */
39
+ setConfigGetter(getter: () => GuardConfig): void;
40
+ /**
41
+ * Start the dashboard HTTP server / 啟動儀表板 HTTP 伺服器
42
+ */
43
+ start(): Promise<void>;
44
+ /**
45
+ * Stop the dashboard server / 停止儀表板伺服器
46
+ */
47
+ stop(): Promise<void>;
48
+ /**
49
+ * Update dashboard status / 更新儀表板狀態
50
+ */
51
+ updateStatus(update: Partial<DashboardStatus>): void;
52
+ /**
53
+ * Push a new event / 推送新事件
54
+ */
55
+ pushEvent(event: DashboardEvent): void;
56
+ /**
57
+ * Add a verdict to recent verdicts / 添加判決到最近判決
58
+ */
59
+ addVerdict(verdict: ThreatVerdict): void;
60
+ /**
61
+ * Update threat map / 更新威脅地圖
62
+ */
63
+ addThreatMapEntry(entry: ThreatMapEntry): void;
64
+ /**
65
+ * Get the auth token for API access / 取得 API 認證 token
66
+ */
67
+ getAuthToken(): string;
68
+ private handleRequest;
69
+ /** Check rate limit for IP / 檢查 IP 的速率限制 */
70
+ private checkRateLimit;
71
+ private serveIndex;
72
+ private jsonResponse;
73
+ private sendToClient;
74
+ private broadcast;
75
+ /** Create a WebSocket text frame / 建立 WebSocket 文字框架 */
76
+ private createWSFrame;
77
+ }
78
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,EACX,aAAa,EACd,MAAM,aAAa,CAAC;AAuBrB;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgD;IAC9D,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAO;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAoC;IACrD,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,kCAAkC;IAClC,OAAO,CAAC,UAAU,CAA0C;gBAEhD,IAAI,EAAE,MAAM;IAiBxB;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,WAAW,GAAG,IAAI;IAIhD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8E5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB3B;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IASpD;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAQtC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAYxC;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAgB9C;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,aAAa;IA8ErB,4CAA4C;IAC5C,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,SAAS;IAMjB,wDAAwD;IACxD,OAAO,CAAC,aAAa;CAsBtB"}