@panguard-ai/core 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.
- package/dist/adapters/adapter-registry.d.ts +150 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +271 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/base-adapter.d.ts +101 -0
- package/dist/adapters/base-adapter.d.ts.map +1 -0
- package/dist/adapters/base-adapter.js +160 -0
- package/dist/adapters/base-adapter.js.map +1 -0
- package/dist/adapters/defender-adapter.d.ts +90 -0
- package/dist/adapters/defender-adapter.d.ts.map +1 -0
- package/dist/adapters/defender-adapter.js +227 -0
- package/dist/adapters/defender-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +23 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/syslog-adapter.d.ts +207 -0
- package/dist/adapters/syslog-adapter.d.ts.map +1 -0
- package/dist/adapters/syslog-adapter.js +432 -0
- package/dist/adapters/syslog-adapter.js.map +1 -0
- package/dist/adapters/types.d.ts +135 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +13 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/wazuh-adapter.d.ts +120 -0
- package/dist/adapters/wazuh-adapter.d.ts.map +1 -0
- package/dist/adapters/wazuh-adapter.js +266 -0
- package/dist/adapters/wazuh-adapter.js.map +1 -0
- package/dist/ai/claude-provider.d.ts +66 -0
- package/dist/ai/claude-provider.d.ts.map +1 -0
- package/dist/ai/claude-provider.js +166 -0
- package/dist/ai/claude-provider.js.map +1 -0
- package/dist/ai/funnel-router.d.ts +75 -0
- package/dist/ai/funnel-router.d.ts.map +1 -0
- package/dist/ai/funnel-router.js +173 -0
- package/dist/ai/funnel-router.js.map +1 -0
- package/dist/ai/index.d.ts +77 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +95 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/ollama-provider.d.ts +73 -0
- package/dist/ai/ollama-provider.d.ts.map +1 -0
- package/dist/ai/ollama-provider.js +200 -0
- package/dist/ai/ollama-provider.js.map +1 -0
- package/dist/ai/openai-provider.d.ts +70 -0
- package/dist/ai/openai-provider.d.ts.map +1 -0
- package/dist/ai/openai-provider.js +175 -0
- package/dist/ai/openai-provider.js.map +1 -0
- package/dist/ai/prompts/event-classifier.d.ts +25 -0
- package/dist/ai/prompts/event-classifier.d.ts.map +1 -0
- package/dist/ai/prompts/event-classifier.js +94 -0
- package/dist/ai/prompts/event-classifier.js.map +1 -0
- package/dist/ai/prompts/index.d.ts +13 -0
- package/dist/ai/prompts/index.d.ts.map +1 -0
- package/dist/ai/prompts/index.js +13 -0
- package/dist/ai/prompts/index.js.map +1 -0
- package/dist/ai/prompts/report-generator.d.ts +25 -0
- package/dist/ai/prompts/report-generator.d.ts.map +1 -0
- package/dist/ai/prompts/report-generator.js +131 -0
- package/dist/ai/prompts/report-generator.js.map +1 -0
- package/dist/ai/prompts/threat-analyzer.d.ts +26 -0
- package/dist/ai/prompts/threat-analyzer.d.ts.map +1 -0
- package/dist/ai/prompts/threat-analyzer.js +75 -0
- package/dist/ai/prompts/threat-analyzer.js.map +1 -0
- package/dist/ai/provider-base.d.ts +100 -0
- package/dist/ai/provider-base.d.ts.map +1 -0
- package/dist/ai/provider-base.js +166 -0
- package/dist/ai/provider-base.js.map +1 -0
- package/dist/ai/response-parser.d.ts +36 -0
- package/dist/ai/response-parser.d.ts.map +1 -0
- package/dist/ai/response-parser.js +195 -0
- package/dist/ai/response-parser.js.map +1 -0
- package/dist/ai/token-tracker.d.ts +72 -0
- package/dist/ai/token-tracker.d.ts.map +1 -0
- package/dist/ai/token-tracker.js +145 -0
- package/dist/ai/token-tracker.js.map +1 -0
- package/dist/ai/types.d.ts +138 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +12 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/cli/index.d.ts +146 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +515 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +58 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +327 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/cli/wizard.d.ts +58 -0
- package/dist/cli/wizard.d.ts.map +1 -0
- package/dist/cli/wizard.js +200 -0
- package/dist/cli/wizard.js.map +1 -0
- package/dist/discovery/firewall-checker.d.ts +28 -0
- package/dist/discovery/firewall-checker.d.ts.map +1 -0
- package/dist/discovery/firewall-checker.js +379 -0
- package/dist/discovery/firewall-checker.js.map +1 -0
- package/dist/discovery/index.d.ts +23 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +29 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/network-scanner.d.ts +60 -0
- package/dist/discovery/network-scanner.d.ts.map +1 -0
- package/dist/discovery/network-scanner.js +640 -0
- package/dist/discovery/network-scanner.js.map +1 -0
- package/dist/discovery/os-detector.d.ts +24 -0
- package/dist/discovery/os-detector.d.ts.map +1 -0
- package/dist/discovery/os-detector.js +253 -0
- package/dist/discovery/os-detector.js.map +1 -0
- package/dist/discovery/osquery-provider.d.ts +127 -0
- package/dist/discovery/osquery-provider.d.ts.map +1 -0
- package/dist/discovery/osquery-provider.js +214 -0
- package/dist/discovery/osquery-provider.js.map +1 -0
- package/dist/discovery/risk-scorer.d.ts +66 -0
- package/dist/discovery/risk-scorer.d.ts.map +1 -0
- package/dist/discovery/risk-scorer.js +294 -0
- package/dist/discovery/risk-scorer.js.map +1 -0
- package/dist/discovery/security-tools.d.ts +31 -0
- package/dist/discovery/security-tools.d.ts.map +1 -0
- package/dist/discovery/security-tools.js +346 -0
- package/dist/discovery/security-tools.js.map +1 -0
- package/dist/discovery/service-detector.d.ts +28 -0
- package/dist/discovery/service-detector.d.ts.map +1 -0
- package/dist/discovery/service-detector.js +300 -0
- package/dist/discovery/service-detector.js.map +1 -0
- package/dist/discovery/types.d.ts +502 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +12 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/discovery/user-auditor.d.ts +28 -0
- package/dist/discovery/user-auditor.d.ts.map +1 -0
- package/dist/discovery/user-auditor.js +385 -0
- package/dist/discovery/user-auditor.js.map +1 -0
- package/dist/i18n/config.d.ts +45 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/i18n/config.js +135 -0
- package/dist/i18n/config.js.map +1 -0
- package/dist/i18n/index.d.ts +8 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +8 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/monitor/event-normalizer.d.ts +102 -0
- package/dist/monitor/event-normalizer.d.ts.map +1 -0
- package/dist/monitor/event-normalizer.js +195 -0
- package/dist/monitor/event-normalizer.js.map +1 -0
- package/dist/monitor/file-monitor.d.ts +90 -0
- package/dist/monitor/file-monitor.d.ts.map +1 -0
- package/dist/monitor/file-monitor.js +222 -0
- package/dist/monitor/file-monitor.js.map +1 -0
- package/dist/monitor/index.d.ts +147 -0
- package/dist/monitor/index.d.ts.map +1 -0
- package/dist/monitor/index.js +293 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/monitor/log-monitor.d.ts +102 -0
- package/dist/monitor/log-monitor.d.ts.map +1 -0
- package/dist/monitor/log-monitor.js +245 -0
- package/dist/monitor/log-monitor.js.map +1 -0
- package/dist/monitor/network-monitor.d.ts +103 -0
- package/dist/monitor/network-monitor.d.ts.map +1 -0
- package/dist/monitor/network-monitor.js +336 -0
- package/dist/monitor/network-monitor.js.map +1 -0
- package/dist/monitor/process-monitor.d.ts +108 -0
- package/dist/monitor/process-monitor.d.ts.map +1 -0
- package/dist/monitor/process-monitor.js +245 -0
- package/dist/monitor/process-monitor.js.map +1 -0
- package/dist/monitor/threat-intel-feeds.d.ts +141 -0
- package/dist/monitor/threat-intel-feeds.d.ts.map +1 -0
- package/dist/monitor/threat-intel-feeds.js +430 -0
- package/dist/monitor/threat-intel-feeds.js.map +1 -0
- package/dist/monitor/threat-intel.d.ts +83 -0
- package/dist/monitor/threat-intel.d.ts.map +1 -0
- package/dist/monitor/threat-intel.js +215 -0
- package/dist/monitor/threat-intel.js.map +1 -0
- package/dist/monitor/types.d.ts +65 -0
- package/dist/monitor/types.d.ts.map +1 -0
- package/dist/monitor/types.js +20 -0
- package/dist/monitor/types.js.map +1 -0
- package/dist/rules/index.d.ts +115 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +244 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/rule-loader.d.ts +54 -0
- package/dist/rules/rule-loader.d.ts.map +1 -0
- package/dist/rules/rule-loader.js +167 -0
- package/dist/rules/rule-loader.js.map +1 -0
- package/dist/rules/sigma-matcher.d.ts +40 -0
- package/dist/rules/sigma-matcher.d.ts.map +1 -0
- package/dist/rules/sigma-matcher.js +447 -0
- package/dist/rules/sigma-matcher.js.map +1 -0
- package/dist/rules/sigma-parser.d.ts +36 -0
- package/dist/rules/sigma-parser.d.ts.map +1 -0
- package/dist/rules/sigma-parser.js +180 -0
- package/dist/rules/sigma-parser.js.map +1 -0
- package/dist/rules/types.d.ts +112 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +11 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/yara-scanner.d.ts +103 -0
- package/dist/rules/yara-scanner.d.ts.map +1 -0
- package/dist/rules/yara-scanner.js +421 -0
- package/dist/rules/yara-scanner.js.map +1 -0
- package/dist/scoring/achievements.d.ts +76 -0
- package/dist/scoring/achievements.d.ts.map +1 -0
- package/dist/scoring/achievements.js +211 -0
- package/dist/scoring/achievements.js.map +1 -0
- package/dist/scoring/index.d.ts +3 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +3 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/security-score.d.ts +60 -0
- package/dist/scoring/security-score.d.ts.map +1 -0
- package/dist/scoring/security-score.js +211 -0
- package/dist/scoring/security-score.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +38 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +71 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +35 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +56 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User account auditor
|
|
3
|
+
* 使用者帳號稽核
|
|
4
|
+
*
|
|
5
|
+
* Audits local user accounts to identify administrators, inactive accounts,
|
|
6
|
+
* and other user-related security concerns across macOS, Linux, and Windows.
|
|
7
|
+
* 稽核本地使用者帳號以識別管理員、非活躍帳號和其他跨 macOS、Linux 和 Windows 的使用者相關安全問題。
|
|
8
|
+
*
|
|
9
|
+
* @module @panguard-ai/core/discovery/user-auditor
|
|
10
|
+
*/
|
|
11
|
+
import { execFile } from 'child_process';
|
|
12
|
+
import { promisify } from 'util';
|
|
13
|
+
import { platform as osPlatform } from 'os';
|
|
14
|
+
import { readFile } from 'fs/promises';
|
|
15
|
+
import { createLogger } from '../utils/logger.js';
|
|
16
|
+
const execFileAsync = promisify(execFile);
|
|
17
|
+
const logger = createLogger('discovery:users');
|
|
18
|
+
/**
|
|
19
|
+
* Safely execute a command and return stdout, or empty string on failure
|
|
20
|
+
* 安全地執行命令並回傳 stdout,失敗時回傳空字串
|
|
21
|
+
*
|
|
22
|
+
* @param cmd - Command to execute / 要執行的命令
|
|
23
|
+
* @param args - Command arguments / 命令參數
|
|
24
|
+
* @returns stdout output trimmed / 修剪後的 stdout 輸出
|
|
25
|
+
*/
|
|
26
|
+
async function safeExec(cmd, args) {
|
|
27
|
+
try {
|
|
28
|
+
const { stdout } = await execFileAsync(cmd, args, { timeout: 10_000 });
|
|
29
|
+
return stdout.trim();
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.debug(`Command failed: ${cmd} ${args.join(' ')}`, {
|
|
33
|
+
error: err instanceof Error ? err.message : String(err),
|
|
34
|
+
});
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Audit user accounts on macOS via dscl (Directory Service command line)
|
|
40
|
+
* 透過 dscl(目錄服務命令列)稽核 macOS 上的使用者帳號
|
|
41
|
+
*
|
|
42
|
+
* @returns Array of user info / 使用者資訊陣列
|
|
43
|
+
*/
|
|
44
|
+
async function auditMacOSUsers() {
|
|
45
|
+
const users = [];
|
|
46
|
+
// Get list of all users
|
|
47
|
+
// 取得所有使用者列表
|
|
48
|
+
const userListOutput = await safeExec('dscl', ['.', '-list', '/Users']);
|
|
49
|
+
if (!userListOutput) {
|
|
50
|
+
logger.warn('dscl list returned no output');
|
|
51
|
+
return users;
|
|
52
|
+
}
|
|
53
|
+
// Get admin group members
|
|
54
|
+
// 取得管理員群組成員
|
|
55
|
+
const adminGroupOutput = await safeExec('dscl', [
|
|
56
|
+
'.',
|
|
57
|
+
'-read',
|
|
58
|
+
'/Groups/admin',
|
|
59
|
+
'GroupMembership',
|
|
60
|
+
]);
|
|
61
|
+
const adminUsers = new Set();
|
|
62
|
+
if (adminGroupOutput) {
|
|
63
|
+
const match = adminGroupOutput.match(/GroupMembership:\s*(.+)/);
|
|
64
|
+
if (match?.[1]) {
|
|
65
|
+
match[1]
|
|
66
|
+
.trim()
|
|
67
|
+
.split(/\s+/)
|
|
68
|
+
.forEach((u) => adminUsers.add(u));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const usernames = userListOutput
|
|
72
|
+
.split('\n')
|
|
73
|
+
.map((u) => u.trim())
|
|
74
|
+
.filter(Boolean);
|
|
75
|
+
for (const username of usernames) {
|
|
76
|
+
// Skip system accounts (those starting with _)
|
|
77
|
+
// 跳過系統帳號(以 _ 開頭的)
|
|
78
|
+
if (username.startsWith('_'))
|
|
79
|
+
continue;
|
|
80
|
+
// Skip daemon, nobody, root-like system users on macOS
|
|
81
|
+
// 跳過 macOS 上的 daemon、nobody、root 類似系統使用者
|
|
82
|
+
if (username === 'daemon' || username === 'nobody')
|
|
83
|
+
continue;
|
|
84
|
+
const userDetail = await safeExec('dscl', ['.', '-read', `/Users/${username}`]);
|
|
85
|
+
if (!userDetail)
|
|
86
|
+
continue;
|
|
87
|
+
// Extract UID
|
|
88
|
+
// 擷取 UID
|
|
89
|
+
let uid;
|
|
90
|
+
const uidMatch = userDetail.match(/UniqueID:\s*(\d+)/);
|
|
91
|
+
if (uidMatch?.[1]) {
|
|
92
|
+
uid = uidMatch[1];
|
|
93
|
+
// Skip system accounts with UID < 500 (except root=0)
|
|
94
|
+
// 跳過 UID < 500 的系統帳號(root=0 除外)
|
|
95
|
+
const uidNum = parseInt(uid, 10);
|
|
96
|
+
if (uidNum > 0 && uidNum < 500)
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
// Extract shell
|
|
100
|
+
// 擷取 shell
|
|
101
|
+
let shell;
|
|
102
|
+
const shellMatch = userDetail.match(/UserShell:\s*(\S+)/);
|
|
103
|
+
if (shellMatch?.[1]) {
|
|
104
|
+
shell = shellMatch[1];
|
|
105
|
+
// Skip users with /usr/bin/false or /sbin/nologin shells (non-interactive)
|
|
106
|
+
// 跳過使用 /usr/bin/false 或 /sbin/nologin 的使用者(非互動式)
|
|
107
|
+
if (shell === '/usr/bin/false' || shell === '/sbin/nologin')
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Get last login info
|
|
111
|
+
// 取得上次登入資訊
|
|
112
|
+
let lastLogin;
|
|
113
|
+
const lastOutput = await safeExec('last', ['-1', username]);
|
|
114
|
+
if (lastOutput && !lastOutput.includes('wtmp begins')) {
|
|
115
|
+
const firstLine = lastOutput.split('\n')[0];
|
|
116
|
+
if (firstLine && firstLine.includes(username)) {
|
|
117
|
+
// Extract the date portion from last output
|
|
118
|
+
// 從 last 輸出擷取日期部分
|
|
119
|
+
const dateParts = firstLine.trim().split(/\s+/).slice(2, 6);
|
|
120
|
+
lastLogin = dateParts.join(' ') || undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
users.push({
|
|
124
|
+
username,
|
|
125
|
+
uid,
|
|
126
|
+
isAdmin: adminUsers.has(username),
|
|
127
|
+
lastLogin,
|
|
128
|
+
passwordAge: undefined,
|
|
129
|
+
shell,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return users;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Audit user accounts on Linux via /etc/passwd and /etc/group
|
|
136
|
+
* 透過 /etc/passwd 和 /etc/group 稽核 Linux 上的使用者帳號
|
|
137
|
+
*
|
|
138
|
+
* @returns Array of user info / 使用者資訊陣列
|
|
139
|
+
*/
|
|
140
|
+
async function auditLinuxUsers() {
|
|
141
|
+
const users = [];
|
|
142
|
+
// Read /etc/passwd
|
|
143
|
+
// 讀取 /etc/passwd
|
|
144
|
+
let passwdContent;
|
|
145
|
+
try {
|
|
146
|
+
passwdContent = await readFile('/etc/passwd', 'utf-8');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
logger.warn('Could not read /etc/passwd');
|
|
150
|
+
return users;
|
|
151
|
+
}
|
|
152
|
+
// Determine admin groups (sudo, wheel, admin)
|
|
153
|
+
// 判斷管理員群組(sudo、wheel、admin)
|
|
154
|
+
const adminUsers = new Set();
|
|
155
|
+
// Check root is always admin
|
|
156
|
+
// root 始終是管理員
|
|
157
|
+
adminUsers.add('root');
|
|
158
|
+
try {
|
|
159
|
+
const groupContent = await readFile('/etc/group', 'utf-8');
|
|
160
|
+
const groupLines = groupContent.split('\n');
|
|
161
|
+
for (const line of groupLines) {
|
|
162
|
+
const parts = line.split(':');
|
|
163
|
+
if (parts.length < 4)
|
|
164
|
+
continue;
|
|
165
|
+
const groupName = parts[0] ?? '';
|
|
166
|
+
const membersStr = parts[3] ?? '';
|
|
167
|
+
const members = membersStr
|
|
168
|
+
.split(',')
|
|
169
|
+
.map((m) => m.trim())
|
|
170
|
+
.filter(Boolean);
|
|
171
|
+
// sudo, wheel, and admin groups grant admin privileges
|
|
172
|
+
// sudo、wheel 和 admin 群組授予管理員權限
|
|
173
|
+
if (groupName === 'sudo' || groupName === 'wheel' || groupName === 'admin') {
|
|
174
|
+
members.forEach((m) => adminUsers.add(m));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
logger.warn('Could not read /etc/group');
|
|
180
|
+
}
|
|
181
|
+
const passwdLines = passwdContent.split('\n');
|
|
182
|
+
for (const line of passwdLines) {
|
|
183
|
+
const trimmed = line.trim();
|
|
184
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
185
|
+
continue;
|
|
186
|
+
// Format: username:password:uid:gid:gecos:home:shell
|
|
187
|
+
// 格式:username:password:uid:gid:gecos:home:shell
|
|
188
|
+
const parts = trimmed.split(':');
|
|
189
|
+
if (parts.length < 7)
|
|
190
|
+
continue;
|
|
191
|
+
const username = parts[0] ?? '';
|
|
192
|
+
const uid = parts[2] ?? '';
|
|
193
|
+
const shell = parts[6] ?? '';
|
|
194
|
+
if (!username)
|
|
195
|
+
continue;
|
|
196
|
+
const uidNum = parseInt(uid, 10);
|
|
197
|
+
// Filter: include root (0) and regular users (typically UID >= 1000)
|
|
198
|
+
// 過濾:包含 root (0) 和一般使用者(通常 UID >= 1000)
|
|
199
|
+
if (uidNum !== 0 && uidNum < 1000)
|
|
200
|
+
continue;
|
|
201
|
+
// Skip users with nologin/false shells (non-interactive)
|
|
202
|
+
// 跳過使用 nologin/false shell 的使用者(非互動式)
|
|
203
|
+
if (shell === '/usr/sbin/nologin' ||
|
|
204
|
+
shell === '/sbin/nologin' ||
|
|
205
|
+
shell === '/bin/false' ||
|
|
206
|
+
shell === '/usr/bin/false') {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
// Get last login info
|
|
210
|
+
// 取得上次登入資訊
|
|
211
|
+
let lastLogin;
|
|
212
|
+
const lastOutput = await safeExec('last', ['-1', username]);
|
|
213
|
+
if (lastOutput && !lastOutput.includes('wtmp begins') && lastOutput.trim()) {
|
|
214
|
+
const firstLine = lastOutput.split('\n')[0];
|
|
215
|
+
if (firstLine && firstLine.includes(username)) {
|
|
216
|
+
const dateParts = firstLine.trim().split(/\s+/).slice(2, 6);
|
|
217
|
+
const joined = dateParts.join(' ');
|
|
218
|
+
lastLogin = joined || undefined;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Try to get password age from /etc/shadow (requires root)
|
|
222
|
+
// 嘗試從 /etc/shadow 取得密碼使用天數(需要 root 權限)
|
|
223
|
+
let passwordAge;
|
|
224
|
+
const chageOutput = await safeExec('chage', ['-l', username]);
|
|
225
|
+
if (chageOutput) {
|
|
226
|
+
const lastChangeMatch = chageOutput.match(/Last password change\s*:\s*(.+)/);
|
|
227
|
+
if (lastChangeMatch?.[1]) {
|
|
228
|
+
const changeDate = new Date(lastChangeMatch[1].trim());
|
|
229
|
+
if (!isNaN(changeDate.getTime())) {
|
|
230
|
+
passwordAge = Math.floor((Date.now() - changeDate.getTime()) / (1000 * 60 * 60 * 24));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
users.push({
|
|
235
|
+
username,
|
|
236
|
+
uid: uid || undefined,
|
|
237
|
+
isAdmin: adminUsers.has(username),
|
|
238
|
+
lastLogin,
|
|
239
|
+
passwordAge,
|
|
240
|
+
shell: shell || undefined,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return users;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Audit user accounts on Windows via net user
|
|
247
|
+
* 透過 net user 稽核 Windows 上的使用者帳號
|
|
248
|
+
*
|
|
249
|
+
* @returns Array of user info / 使用者資訊陣列
|
|
250
|
+
*/
|
|
251
|
+
async function auditWindowsUsers() {
|
|
252
|
+
const users = [];
|
|
253
|
+
// Get list of administrators
|
|
254
|
+
// 取得管理員列表
|
|
255
|
+
const adminOutput = await safeExec('net', ['localgroup', 'administrators']);
|
|
256
|
+
const adminUsers = new Set();
|
|
257
|
+
if (adminOutput) {
|
|
258
|
+
const lines = adminOutput.split('\n');
|
|
259
|
+
let inMemberSection = false;
|
|
260
|
+
for (const line of lines) {
|
|
261
|
+
const trimmed = line.trim();
|
|
262
|
+
if (trimmed.startsWith('---')) {
|
|
263
|
+
inMemberSection = true;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (trimmed.startsWith('The command completed')) {
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
if (inMemberSection && trimmed) {
|
|
270
|
+
adminUsers.add(trimmed.toLowerCase());
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Get all users
|
|
275
|
+
// 取得所有使用者
|
|
276
|
+
const userListOutput = await safeExec('net', ['user']);
|
|
277
|
+
if (!userListOutput) {
|
|
278
|
+
logger.warn('net user returned no output');
|
|
279
|
+
return users;
|
|
280
|
+
}
|
|
281
|
+
// Parse user list - net user shows users in columns
|
|
282
|
+
// 解析使用者列表 - net user 以欄位顯示使用者
|
|
283
|
+
const lines = userListOutput.split('\n');
|
|
284
|
+
const usernames = [];
|
|
285
|
+
let inUserSection = false;
|
|
286
|
+
for (const line of lines) {
|
|
287
|
+
const trimmed = line.trim();
|
|
288
|
+
if (trimmed.startsWith('---')) {
|
|
289
|
+
inUserSection = true;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
if (trimmed.startsWith('The command completed')) {
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
if (inUserSection && trimmed) {
|
|
296
|
+
// Users are listed separated by spaces, multiple per line
|
|
297
|
+
// 使用者以空格分隔列出,每行可能多個
|
|
298
|
+
const names = trimmed.split(/\s{2,}/);
|
|
299
|
+
for (const name of names) {
|
|
300
|
+
const n = name.trim();
|
|
301
|
+
if (n)
|
|
302
|
+
usernames.push(n);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// Get detailed info for each user
|
|
307
|
+
// 取得每個使用者的詳細資訊
|
|
308
|
+
for (const username of usernames) {
|
|
309
|
+
const detailOutput = await safeExec('net', ['user', username]);
|
|
310
|
+
let lastLogin;
|
|
311
|
+
let passwordAge;
|
|
312
|
+
if (detailOutput) {
|
|
313
|
+
const lastLogonMatch = detailOutput.match(/Last logon\s*(.+)/i);
|
|
314
|
+
if (lastLogonMatch?.[1]) {
|
|
315
|
+
const dateStr = lastLogonMatch[1].trim();
|
|
316
|
+
if (dateStr !== 'Never') {
|
|
317
|
+
lastLogin = dateStr;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
const passwordLastSetMatch = detailOutput.match(/Password last set\s*(.+)/i);
|
|
321
|
+
if (passwordLastSetMatch?.[1]) {
|
|
322
|
+
const dateStr = passwordLastSetMatch[1].trim();
|
|
323
|
+
const setDate = new Date(dateStr);
|
|
324
|
+
if (!isNaN(setDate.getTime())) {
|
|
325
|
+
passwordAge = Math.floor((Date.now() - setDate.getTime()) / (1000 * 60 * 60 * 24));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
users.push({
|
|
330
|
+
username,
|
|
331
|
+
uid: undefined,
|
|
332
|
+
isAdmin: adminUsers.has(username.toLowerCase()),
|
|
333
|
+
lastLogin,
|
|
334
|
+
passwordAge,
|
|
335
|
+
shell: undefined,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return users;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Audit all local user accounts on the current platform
|
|
342
|
+
* 稽核目前平台上所有本地使用者帳號
|
|
343
|
+
*
|
|
344
|
+
* Dispatches to platform-specific auditing methods:
|
|
345
|
+
* - macOS: dscl . -list /Users + dscl . -read /Users/username
|
|
346
|
+
* - Linux: /etc/passwd + /etc/group
|
|
347
|
+
* - Windows: net user + net localgroup administrators
|
|
348
|
+
* 分派到平台特定的稽核方法:
|
|
349
|
+
* - macOS:dscl . -list /Users + dscl . -read /Users/username
|
|
350
|
+
* - Linux:/etc/passwd + /etc/group
|
|
351
|
+
* - Windows:net user + net localgroup administrators
|
|
352
|
+
*
|
|
353
|
+
* @returns Array of audited user accounts / 已稽核的使用者帳號陣列
|
|
354
|
+
*/
|
|
355
|
+
export async function auditUsers() {
|
|
356
|
+
const currentPlatform = osPlatform();
|
|
357
|
+
logger.info(`Auditing users on ${currentPlatform}`);
|
|
358
|
+
try {
|
|
359
|
+
let users = [];
|
|
360
|
+
switch (currentPlatform) {
|
|
361
|
+
case 'darwin':
|
|
362
|
+
users = await auditMacOSUsers();
|
|
363
|
+
break;
|
|
364
|
+
case 'linux':
|
|
365
|
+
users = await auditLinuxUsers();
|
|
366
|
+
break;
|
|
367
|
+
case 'win32':
|
|
368
|
+
users = await auditWindowsUsers();
|
|
369
|
+
break;
|
|
370
|
+
default:
|
|
371
|
+
logger.warn(`Unsupported platform for user audit: ${currentPlatform}`);
|
|
372
|
+
return [];
|
|
373
|
+
}
|
|
374
|
+
const adminCount = users.filter((u) => u.isAdmin).length;
|
|
375
|
+
logger.info(`Audited ${users.length} users (${adminCount} admins)`);
|
|
376
|
+
return users;
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
logger.error('User audit failed', {
|
|
380
|
+
error: err instanceof Error ? err.message : String(err),
|
|
381
|
+
});
|
|
382
|
+
return [];
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=user-auditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-auditor.js","sourceRoot":"","sources":["../../src/discovery/user-auditor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,IAAI,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAE/C;;;;;;;GAOG;AACH,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAc;IACjD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACvE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,mBAAmB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;YACvD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe;IAC5B,MAAM,KAAK,GAAe,EAAE,CAAC;IAE7B,wBAAwB;IACxB,YAAY;IACZ,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0BAA0B;IAC1B,YAAY;IACZ,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE;QAC9C,GAAG;QACH,OAAO;QACP,eAAe;QACf,iBAAiB;KAClB,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,CAAC,CAAC;iBACL,IAAI,EAAE;iBACN,KAAK,CAAC,KAAK,CAAC;iBACZ,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,cAAc;SAC7B,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,+CAA+C;QAC/C,kBAAkB;QAClB,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACvC,uDAAuD;QACvD,yCAAyC;QACzC,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ;YAAE,SAAS;QAE7D,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,QAAQ,EAAE,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,UAAU;YAAE,SAAS;QAE1B,cAAc;QACd,SAAS;QACT,IAAI,GAAuB,CAAC;QAC5B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvD,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClB,sDAAsD;YACtD,gCAAgC;YAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG;gBAAE,SAAS;QAC3C,CAAC;QAED,gBAAgB;QAChB,WAAW;QACX,IAAI,KAAyB,CAAC;QAC9B,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC1D,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACtB,2EAA2E;YAC3E,iDAAiD;YACjD,IAAI,KAAK,KAAK,gBAAgB,IAAI,KAAK,KAAK,eAAe;gBAAE,SAAS;QACxE,CAAC;QAED,sBAAsB;QACtB,WAAW;QACX,IAAI,SAA6B,CAAC;QAClC,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5D,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACtD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9C,4CAA4C;gBAC5C,kBAAkB;gBAClB,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5D,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ;YACR,GAAG;YACH,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,SAAS;YACT,WAAW,EAAE,SAAS;YACtB,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe;IAC5B,MAAM,KAAK,GAAe,EAAE,CAAC;IAE7B,mBAAmB;IACnB,iBAAiB;IACjB,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8CAA8C;IAC9C,4BAA4B;IAC5B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,6BAA6B;IAC7B,cAAc;IACd,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAE/B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,UAAU;iBACvB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC,CAAC;YAEnB,uDAAuD;YACvD,+BAA+B;YAC/B,IAAI,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;gBAC3E,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,qDAAqD;QACrD,gDAAgD;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAE/B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ;YAAE,SAAS;QAExB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAEjC,qEAAqE;QACrE,wCAAwC;QACxC,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,GAAG,IAAI;YAAE,SAAS;QAE5C,yDAAyD;QACzD,sCAAsC;QACtC,IACE,KAAK,KAAK,mBAAmB;YAC7B,KAAK,KAAK,eAAe;YACzB,KAAK,KAAK,YAAY;YACtB,KAAK,KAAK,gBAAgB,EAC1B,CAAC;YACD,SAAS;QACX,CAAC;QAED,sBAAsB;QACtB,WAAW;QACX,IAAI,SAA6B,CAAC;QAClC,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5D,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3E,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5D,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACnC,SAAS,GAAG,MAAM,IAAI,SAAS,CAAC;YAClC,CAAC;QACH,CAAC;QAED,2DAA2D;QAC3D,uCAAuC;QACvC,IAAI,WAA+B,CAAC;QACpC,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC9D,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YAC7E,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACvD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;oBACjC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;gBACxF,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ;YACR,GAAG,EAAE,GAAG,IAAI,SAAS;YACrB,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,SAAS;YACT,WAAW;YACX,KAAK,EAAE,KAAK,IAAI,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,iBAAiB;IAC9B,MAAM,KAAK,GAAe,EAAE,CAAC;IAE7B,6BAA6B;IAC7B,UAAU;IACV,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC5E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,eAAe,GAAG,KAAK,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAE5B,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,eAAe,GAAG,IAAI,CAAC;gBACvB,SAAS;YACX,CAAC;YAED,IAAI,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAChD,MAAM;YACR,CAAC;YAED,IAAI,eAAe,IAAI,OAAO,EAAE,CAAC;gBAC/B,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,UAAU;IACV,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oDAAoD;IACpD,8BAA8B;IAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,aAAa,GAAG,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,EAAE,CAAC;YAChD,MAAM;QACR,CAAC;QAED,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;YAC7B,0DAA0D;YAC1D,oBAAoB;YACpB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC;oBAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,eAAe;IACf,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QAE/D,IAAI,SAA6B,CAAC;QAClC,IAAI,WAA+B,CAAC;QAEpC,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAChE,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxB,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;oBACxB,SAAS,GAAG,OAAO,CAAC;gBACtB,CAAC;YACH,CAAC;YAED,MAAM,oBAAoB,GAAG,YAAY,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC7E,IAAI,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9B,MAAM,OAAO,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC/C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;gBAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;oBAC9B,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;gBACrF,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ;YACR,GAAG,EAAE,SAAS;YACd,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC/C,SAAS;YACT,WAAW;YACX,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,eAAe,GAAG,UAAU,EAAE,CAAC;IAErC,MAAM,CAAC,IAAI,CAAC,qBAAqB,eAAe,EAAE,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,IAAI,KAAK,GAAe,EAAE,CAAC;QAE3B,QAAQ,eAAe,EAAE,CAAC;YACxB,KAAK,QAAQ;gBACX,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;gBAChC,MAAM;YACR,KAAK,OAAO;gBACV,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;gBAChC,MAAM;YACR,KAAK,OAAO;gBACV,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;gBAClC,MAAM;YACR;gBACE,MAAM,CAAC,IAAI,CAAC,wCAAwC,eAAe,EAAE,CAAC,CAAC;gBACvE,OAAO,EAAE,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,MAAM,WAAW,UAAU,UAAU,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE;YAChC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n configuration and initialization
|
|
3
|
+
* 國際化配置與初始化
|
|
4
|
+
*
|
|
5
|
+
* @module @panguard-ai/core/i18n
|
|
6
|
+
*/
|
|
7
|
+
import { type i18n } from 'i18next';
|
|
8
|
+
import type { Language } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Initialize i18next for bilingual support (zh-TW / en)
|
|
11
|
+
* 初始化 i18next 以支援雙語(繁體中文 / 英文)
|
|
12
|
+
*
|
|
13
|
+
* @param language - Target language / 目標語言
|
|
14
|
+
* @returns Configured i18next instance / 配置好的 i18next 實例
|
|
15
|
+
*/
|
|
16
|
+
export declare function initI18n(language?: Language): Promise<i18n>;
|
|
17
|
+
/**
|
|
18
|
+
* Get the current i18next instance
|
|
19
|
+
* 取得目前的 i18next 實例
|
|
20
|
+
*
|
|
21
|
+
* @returns i18next instance or null if not initialized / i18next 實例,未初始化則為 null
|
|
22
|
+
*/
|
|
23
|
+
export declare function getI18n(): i18n | null;
|
|
24
|
+
/**
|
|
25
|
+
* Change the active language
|
|
26
|
+
* 切換使用中的語言
|
|
27
|
+
*
|
|
28
|
+
* @param language - Target language / 目標語言
|
|
29
|
+
*/
|
|
30
|
+
export declare function changeLanguage(language: Language): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Translate a key using the current language
|
|
33
|
+
* 使用目前語言翻譯指定的鍵值
|
|
34
|
+
*
|
|
35
|
+
* @param key - Translation key (e.g., 'common:welcome') / 翻譯鍵值
|
|
36
|
+
* @param options - Interpolation options / 插值選項
|
|
37
|
+
* @returns Translated string / 翻譯後的字串
|
|
38
|
+
*/
|
|
39
|
+
export declare function t(key: string, options?: Record<string, unknown>): string;
|
|
40
|
+
/**
|
|
41
|
+
* Reset i18n state (primarily for testing)
|
|
42
|
+
* 重設 i18n 狀態(主要用於測試)
|
|
43
|
+
*/
|
|
44
|
+
export declare function resetI18n(): void;
|
|
45
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/i18n/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAI7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAsB5C;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,GAAE,QAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDvE;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,IAAI,IAAI,GAAG,IAAI,CAKrC;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtE;AAED;;;;;;;GAOG;AACH,wBAAgB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAKxE;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n configuration and initialization
|
|
3
|
+
* 國際化配置與初始化
|
|
4
|
+
*
|
|
5
|
+
* @module @panguard-ai/core/i18n
|
|
6
|
+
*/
|
|
7
|
+
import i18next from 'i18next';
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
import { resolve, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
let initialized = false;
|
|
14
|
+
/**
|
|
15
|
+
* Load translation JSON from filesystem
|
|
16
|
+
* 從檔案系統載入翻譯 JSON
|
|
17
|
+
*/
|
|
18
|
+
function loadTranslations(lang, ns) {
|
|
19
|
+
const filePath = resolve(__dirname, `./locales/${lang}/${ns}.json`);
|
|
20
|
+
try {
|
|
21
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
22
|
+
return JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
console.warn(`[i18n] Failed to load translations: ${filePath}`);
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize i18next for bilingual support (zh-TW / en)
|
|
31
|
+
* 初始化 i18next 以支援雙語(繁體中文 / 英文)
|
|
32
|
+
*
|
|
33
|
+
* @param language - Target language / 目標語言
|
|
34
|
+
* @returns Configured i18next instance / 配置好的 i18next 實例
|
|
35
|
+
*/
|
|
36
|
+
export async function initI18n(language = 'en') {
|
|
37
|
+
if (initialized) {
|
|
38
|
+
await i18next.changeLanguage(language);
|
|
39
|
+
return i18next;
|
|
40
|
+
}
|
|
41
|
+
const resources = {
|
|
42
|
+
en: {
|
|
43
|
+
common: loadTranslations('en', 'common'),
|
|
44
|
+
security: loadTranslations('en', 'security'),
|
|
45
|
+
discovery: loadTranslations('en', 'discovery'),
|
|
46
|
+
'panguard-scan': loadTranslations('en', 'panguard-scan'),
|
|
47
|
+
'panguard-guard': loadTranslations('en', 'panguard-guard'),
|
|
48
|
+
'panguard-chat': loadTranslations('en', 'panguard-chat'),
|
|
49
|
+
'panguard-trap': loadTranslations('en', 'panguard-trap'),
|
|
50
|
+
'panguard-report': loadTranslations('en', 'panguard-report'),
|
|
51
|
+
panguardweb: loadTranslations('en', 'panguardweb'),
|
|
52
|
+
},
|
|
53
|
+
'zh-TW': {
|
|
54
|
+
common: loadTranslations('zh-TW', 'common'),
|
|
55
|
+
security: loadTranslations('zh-TW', 'security'),
|
|
56
|
+
discovery: loadTranslations('zh-TW', 'discovery'),
|
|
57
|
+
'panguard-scan': loadTranslations('zh-TW', 'panguard-scan'),
|
|
58
|
+
'panguard-guard': loadTranslations('zh-TW', 'panguard-guard'),
|
|
59
|
+
'panguard-chat': loadTranslations('zh-TW', 'panguard-chat'),
|
|
60
|
+
'panguard-trap': loadTranslations('zh-TW', 'panguard-trap'),
|
|
61
|
+
'panguard-report': loadTranslations('zh-TW', 'panguard-report'),
|
|
62
|
+
panguardweb: loadTranslations('zh-TW', 'panguardweb'),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
await i18next.init({
|
|
66
|
+
lng: language,
|
|
67
|
+
fallbackLng: 'en',
|
|
68
|
+
supportedLngs: ['zh-TW', 'en'],
|
|
69
|
+
ns: [
|
|
70
|
+
'common',
|
|
71
|
+
'security',
|
|
72
|
+
'discovery',
|
|
73
|
+
'panguard-scan',
|
|
74
|
+
'panguard-guard',
|
|
75
|
+
'panguard-chat',
|
|
76
|
+
'panguard-trap',
|
|
77
|
+
'panguard-report',
|
|
78
|
+
'panguardweb',
|
|
79
|
+
],
|
|
80
|
+
defaultNS: 'common',
|
|
81
|
+
resources,
|
|
82
|
+
interpolation: {
|
|
83
|
+
escapeValue: false,
|
|
84
|
+
},
|
|
85
|
+
returnNull: false,
|
|
86
|
+
});
|
|
87
|
+
initialized = true;
|
|
88
|
+
return i18next;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get the current i18next instance
|
|
92
|
+
* 取得目前的 i18next 實例
|
|
93
|
+
*
|
|
94
|
+
* @returns i18next instance or null if not initialized / i18next 實例,未初始化則為 null
|
|
95
|
+
*/
|
|
96
|
+
export function getI18n() {
|
|
97
|
+
if (!initialized) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return i18next;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Change the active language
|
|
104
|
+
* 切換使用中的語言
|
|
105
|
+
*
|
|
106
|
+
* @param language - Target language / 目標語言
|
|
107
|
+
*/
|
|
108
|
+
export async function changeLanguage(language) {
|
|
109
|
+
if (!initialized) {
|
|
110
|
+
throw new Error('i18n not initialized. Call initI18n() first. / i18n 尚未初始化,請先呼叫 initI18n()。');
|
|
111
|
+
}
|
|
112
|
+
await i18next.changeLanguage(language);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Translate a key using the current language
|
|
116
|
+
* 使用目前語言翻譯指定的鍵值
|
|
117
|
+
*
|
|
118
|
+
* @param key - Translation key (e.g., 'common:welcome') / 翻譯鍵值
|
|
119
|
+
* @param options - Interpolation options / 插值選項
|
|
120
|
+
* @returns Translated string / 翻譯後的字串
|
|
121
|
+
*/
|
|
122
|
+
export function t(key, options) {
|
|
123
|
+
if (!initialized) {
|
|
124
|
+
return key;
|
|
125
|
+
}
|
|
126
|
+
return i18next.t(key, options);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Reset i18n state (primarily for testing)
|
|
130
|
+
* 重設 i18n 狀態(主要用於測試)
|
|
131
|
+
*/
|
|
132
|
+
export function resetI18n() {
|
|
133
|
+
initialized = false;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/i18n/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panguard AI - Core Package
|
|
3
|
+
* Panguard 安全平台 - 核心套件
|
|
4
|
+
*
|
|
5
|
+
* Core shared modules for the Panguard AI platform.
|
|
6
|
+
* Provides types, i18n, utilities, discovery, monitoring, rules, AI, and adapters.
|
|
7
|
+
* 核心共用模組,提供類型、國際化、工具函式、偵察、監控、規則、AI 和對接器。
|
|
8
|
+
*
|
|
9
|
+
* @module @panguard-ai/core
|
|
10
|
+
*/
|
|
11
|
+
export type { Language, Severity, EventSource, BaseConfig, SecurityEvent, LogEntry, } from './types.js';
|
|
12
|
+
export { initI18n, getI18n, changeLanguage, t, resetI18n } from './i18n/index.js';
|
|
13
|
+
export { createLogger, setLogLevel, validateInput, sanitizeString, validateFilePath, } from './utils/index.js';
|
|
14
|
+
export type { Logger } from './utils/index.js';
|
|
15
|
+
export { DISCOVERY_VERSION, detectOS, getNetworkInterfaces, scanOpenPorts, getActiveConnections, getGateway, getDnsServers, getDnsServersAsync, detectServices, detectSecurityTools, checkFirewall, auditUsers, calculateRiskScore, getRiskLevel, OsqueryProvider, createOsqueryProvider, } from './discovery/index.js';
|
|
16
|
+
export type { DiscoveryConfig, OSInfo, NetworkInterface, PortInfo, ActiveConnection, NetworkInfo, ServiceInfo, SecurityToolType, SecurityTool, FirewallRule, FirewallStatus, UpdateStatus, UserInfo, RiskFactor, DiscoveryResult, OsqueryProcess, OsqueryListeningPort, OsqueryLoggedInUser, } from './discovery/index.js';
|
|
17
|
+
export { RULES_VERSION, RuleEngine, parseSigmaYaml, parseSigmaFile, matchEvent, matchEventAgainstRules, loadRulesFromDirectory, watchRulesDirectory, YaraScanner, } from './rules/index.js';
|
|
18
|
+
export type { SigmaLogSource, SigmaDetection, SigmaRule, RuleMatch, RuleEngineConfig, YaraMatch, YaraScanResult, } from './rules/index.js';
|
|
19
|
+
export { MONITOR_VERSION, MonitorEngine, LogMonitor, NetworkMonitor, ProcessMonitor, FileMonitor, checkThreatIntel, isPrivateIP, addThreatIntelEntry, getThreatIntelEntries, setFeedManager, getFeedManager, normalizeLogEvent, normalizeNetworkEvent, normalizeProcessEvent, normalizeFileEvent, DEFAULT_MONITOR_CONFIG, ThreatIntelFeedManager, } from './monitor/index.js';
|
|
20
|
+
export type { MonitorConfig, MonitorStatus, ThreatIntelEntry, FileHashRecord, ProcessListEntry, IoC, FeedSource, FeedUpdateResult, FeedManagerConfig, } from './monitor/index.js';
|
|
21
|
+
export { calculateSecurityScore, scoreToGrade, scoreToColor, generateScoreSummary, AchievementTracker, ACHIEVEMENTS, } from './scoring/index.js';
|
|
22
|
+
export type { ScoreFactor, SecurityScoreSnapshot, ScoreInput, Achievement, AchievementStats, EarnedAchievement, } from './scoring/index.js';
|
|
23
|
+
export { AI_VERSION, createLLM } from './ai/index.js';
|
|
24
|
+
export type { LLMConfig, LLMProvider, LLMProviderType, AnalysisResult, ThreatClassification, } from './ai/index.js';
|
|
25
|
+
export { ADAPTERS_VERSION, BaseAdapter, mapSeverity, mapEventSource, DefenderAdapter, WazuhAdapter, SyslogAdapter, parseSyslogMessage, AdapterRegistry, } from './adapters/index.js';
|
|
26
|
+
export type { AdapterConfig, AdapterAlert, SecurityAdapter, SyslogAlertCallback, } from './adapters/index.js';
|
|
27
|
+
export { c, colorSeverity, colorScore, colorGrade, Spinner, spinner, ProgressBar, progressBar, table, box, banner, header, symbols, divider, scoreDisplay, statusPanel, stripAnsi, formatDuration, timeAgo, visLen, promptSelect, promptText, promptConfirm, WizardEngine, } from './cli/index.js';
|
|
28
|
+
export type { ProgressBarOptions, TableColumn, BoxOptions, StatusItem, SelectOption, SelectConfig, TextConfig, ConfirmConfig, WizardStep, WizardAnswers, } from './cli/index.js';
|
|
29
|
+
/** Core package version / 核心套件版本 */
|
|
30
|
+
export declare const CORE_VERSION = "0.1.0";
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|