@dimzxzzx07/file-watcher 1.0.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/.env +13 -0
- package/.eslintrc.json +128 -0
- package/.prettierrc +18 -0
- package/Dimzxzzx07.png +0 -0
- package/README.md +1024 -0
- package/dist/core/BackupManager.d.ts +25 -0
- package/dist/core/BackupManager.d.ts.map +1 -0
- package/dist/core/BackupManager.js +290 -0
- package/dist/core/BackupManager.js.map +1 -0
- package/dist/core/IntegrityValidator.d.ts +18 -0
- package/dist/core/IntegrityValidator.d.ts.map +1 -0
- package/dist/core/IntegrityValidator.js +212 -0
- package/dist/core/IntegrityValidator.js.map +1 -0
- package/dist/core/SecurityManager.d.ts +40 -0
- package/dist/core/SecurityManager.d.ts.map +1 -0
- package/dist/core/SecurityManager.js +320 -0
- package/dist/core/SecurityManager.js.map +1 -0
- package/dist/core/WatcherEngine.d.ts +44 -0
- package/dist/core/WatcherEngine.d.ts.map +1 -0
- package/dist/core/WatcherEngine.js +470 -0
- package/dist/core/WatcherEngine.js.map +1 -0
- package/dist/crypto/HashGenerator.d.ts +26 -0
- package/dist/crypto/HashGenerator.d.ts.map +1 -0
- package/dist/crypto/HashGenerator.js +220 -0
- package/dist/crypto/HashGenerator.js.map +1 -0
- package/dist/crypto/KeyManager.d.ts +30 -0
- package/dist/crypto/KeyManager.d.ts.map +1 -0
- package/dist/crypto/KeyManager.js +235 -0
- package/dist/crypto/KeyManager.js.map +1 -0
- package/dist/crypto/SignatureValidator.d.ts +11 -0
- package/dist/crypto/SignatureValidator.d.ts.map +1 -0
- package/dist/crypto/SignatureValidator.js +102 -0
- package/dist/crypto/SignatureValidator.js.map +1 -0
- package/dist/detectors/AnomalyDetector.d.ts +24 -0
- package/dist/detectors/AnomalyDetector.d.ts.map +1 -0
- package/dist/detectors/AnomalyDetector.js +209 -0
- package/dist/detectors/AnomalyDetector.js.map +1 -0
- package/dist/detectors/InjectionDetector.d.ts +14 -0
- package/dist/detectors/InjectionDetector.d.ts.map +1 -0
- package/dist/detectors/InjectionDetector.js +204 -0
- package/dist/detectors/InjectionDetector.js.map +1 -0
- package/dist/detectors/PatternMatcher.d.ts +28 -0
- package/dist/detectors/PatternMatcher.d.ts.map +1 -0
- package/dist/detectors/PatternMatcher.js +283 -0
- package/dist/detectors/PatternMatcher.js.map +1 -0
- package/dist/guards/FileGuard.d.ts +35 -0
- package/dist/guards/FileGuard.d.ts.map +1 -0
- package/dist/guards/FileGuard.js +357 -0
- package/dist/guards/FileGuard.js.map +1 -0
- package/dist/guards/MemoryGuard.d.ts +28 -0
- package/dist/guards/MemoryGuard.d.ts.map +1 -0
- package/dist/guards/MemoryGuard.js +256 -0
- package/dist/guards/MemoryGuard.js.map +1 -0
- package/dist/guards/ProcessGuard.d.ts +25 -0
- package/dist/guards/ProcessGuard.d.ts.map +1 -0
- package/dist/guards/ProcessGuard.js +221 -0
- package/dist/guards/ProcessGuard.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +69 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/Constants.d.ts +407 -0
- package/dist/utils/Constants.d.ts.map +1 -0
- package/dist/utils/Constants.js +505 -0
- package/dist/utils/Constants.js.map +1 -0
- package/dist/utils/Logger.d.ts +45 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +285 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/Validator.d.ts +27 -0
- package/dist/utils/Validator.d.ts.map +1 -0
- package/dist/utils/Validator.js +245 -0
- package/dist/utils/Validator.js.map +1 -0
- package/favicon.png +0 -0
- package/jest.config.js +69 -0
- package/package.json +69 -0
- package/src/core/BackupManager.ts +305 -0
- package/src/core/IntegrityValidator.ts +200 -0
- package/src/core/SecurityManager.ts +348 -0
- package/src/core/WatcherEngine.ts +537 -0
- package/src/crypto/HashGenerator.ts +234 -0
- package/src/crypto/KeyManager.ts +249 -0
- package/src/crypto/SignatureValidator.ts +76 -0
- package/src/detectors/AnomalyDetector.ts +247 -0
- package/src/detectors/InjectionDetector.ts +233 -0
- package/src/detectors/PatternMatcher.ts +319 -0
- package/src/guards/FileGuard.ts +385 -0
- package/src/guards/MemoryGuard.ts +263 -0
- package/src/guards/ProcessGuard.ts +219 -0
- package/src/index.ts +189 -0
- package/src/types/index.ts +72 -0
- package/src/utils/Constants.ts +532 -0
- package/src/utils/Logger.ts +279 -0
- package/src/utils/Validator.ts +248 -0
- package/tests/setup.ts +80 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Logger = exports.LogLevel = void 0;
|
|
37
|
+
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
var LogLevel;
|
|
40
|
+
(function (LogLevel) {
|
|
41
|
+
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
42
|
+
LogLevel[LogLevel["INFO"] = 1] = "INFO";
|
|
43
|
+
LogLevel[LogLevel["WARNING"] = 2] = "WARNING";
|
|
44
|
+
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
45
|
+
LogLevel[LogLevel["CRITICAL"] = 4] = "CRITICAL";
|
|
46
|
+
LogLevel[LogLevel["EMERGENCY"] = 5] = "EMERGENCY";
|
|
47
|
+
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
48
|
+
class Logger {
|
|
49
|
+
static instance;
|
|
50
|
+
logDir;
|
|
51
|
+
logFile;
|
|
52
|
+
errorLogFile;
|
|
53
|
+
securityLogFile;
|
|
54
|
+
currentLogLevel = LogLevel.INFO;
|
|
55
|
+
maxLogSize = 10 * 1024 * 1024;
|
|
56
|
+
maxLogFiles = 5;
|
|
57
|
+
logQueue = [];
|
|
58
|
+
isWriting = false;
|
|
59
|
+
constructor() {
|
|
60
|
+
this.logDir = path.join(process.cwd(), 'logs');
|
|
61
|
+
this.logFile = path.join(this.logDir, 'app.log');
|
|
62
|
+
this.errorLogFile = path.join(this.logDir, 'error.log');
|
|
63
|
+
this.securityLogFile = path.join(this.logDir, 'security.log');
|
|
64
|
+
this.initializeLogging();
|
|
65
|
+
this.startLogProcessor();
|
|
66
|
+
}
|
|
67
|
+
static getInstance() {
|
|
68
|
+
if (!Logger.instance) {
|
|
69
|
+
Logger.instance = new Logger();
|
|
70
|
+
}
|
|
71
|
+
return Logger.instance;
|
|
72
|
+
}
|
|
73
|
+
async initializeLogging() {
|
|
74
|
+
try {
|
|
75
|
+
await fs.mkdir(this.logDir, { recursive: true, mode: 0o700 });
|
|
76
|
+
await this.initializeLogFile(this.logFile);
|
|
77
|
+
await this.initializeLogFile(this.errorLogFile);
|
|
78
|
+
await this.initializeLogFile(this.securityLogFile);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error('Failed to initialize logging:', error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async initializeLogFile(filePath) {
|
|
85
|
+
try {
|
|
86
|
+
const exists = await this.fileExists(filePath);
|
|
87
|
+
if (!exists) {
|
|
88
|
+
const header = `# Log file created at ${new Date().toISOString()}\n`;
|
|
89
|
+
await fs.writeFile(filePath, header);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(`Failed to initialize log file: ${filePath}`, error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
startLogProcessor() {
|
|
97
|
+
setInterval(() => {
|
|
98
|
+
this.processLogQueue();
|
|
99
|
+
}, 1000);
|
|
100
|
+
}
|
|
101
|
+
async processLogQueue() {
|
|
102
|
+
if (this.isWriting || this.logQueue.length === 0) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.isWriting = true;
|
|
106
|
+
try {
|
|
107
|
+
const entries = [...this.logQueue];
|
|
108
|
+
this.logQueue = [];
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
await this.writeLog(entry);
|
|
111
|
+
}
|
|
112
|
+
await this.rotateLogIfNeeded(this.logFile);
|
|
113
|
+
await this.rotateLogIfNeeded(this.errorLogFile);
|
|
114
|
+
await this.rotateLogIfNeeded(this.securityLogFile);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('Failed to process log queue:', error);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
this.isWriting = false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async writeLog(entry) {
|
|
124
|
+
try {
|
|
125
|
+
let logFile = this.logFile;
|
|
126
|
+
if (entry.includes('"level":"ERROR"') || entry.includes('"level":"CRITICAL"')) {
|
|
127
|
+
logFile = this.errorLogFile;
|
|
128
|
+
}
|
|
129
|
+
else if (entry.includes('"level":"WARNING"')) {
|
|
130
|
+
logFile = this.securityLogFile;
|
|
131
|
+
}
|
|
132
|
+
await fs.appendFile(logFile, entry + '\n');
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error('Failed to write log:', error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async rotateLogIfNeeded(logFile) {
|
|
139
|
+
try {
|
|
140
|
+
const stats = await fs.stat(logFile);
|
|
141
|
+
if (stats.size > this.maxLogSize) {
|
|
142
|
+
await this.rotateLog(logFile);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async rotateLog(logFile) {
|
|
149
|
+
for (let i = this.maxLogFiles - 1; i > 0; i--) {
|
|
150
|
+
const oldFile = `${logFile}.${i}`;
|
|
151
|
+
const newFile = `${logFile}.${i + 1}`;
|
|
152
|
+
try {
|
|
153
|
+
await fs.rename(oldFile, newFile);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
await fs.rename(logFile, `${logFile}.1`);
|
|
159
|
+
await this.initializeLogFile(logFile);
|
|
160
|
+
}
|
|
161
|
+
formatLogEntry(level, message, metadata) {
|
|
162
|
+
const entry = {
|
|
163
|
+
timestamp: new Date().toISOString(),
|
|
164
|
+
level: LogLevel[level],
|
|
165
|
+
pid: process.pid,
|
|
166
|
+
message,
|
|
167
|
+
metadata: metadata || {}
|
|
168
|
+
};
|
|
169
|
+
return JSON.stringify(entry);
|
|
170
|
+
}
|
|
171
|
+
queueLog(level, message, metadata) {
|
|
172
|
+
const entry = this.formatLogEntry(level, message, metadata);
|
|
173
|
+
this.logQueue.push(entry);
|
|
174
|
+
if (process.env.NODE_ENV === 'development') {
|
|
175
|
+
const consoleMethod = this.getConsoleMethod(level);
|
|
176
|
+
console[consoleMethod](`[${LogLevel[level]}] ${message}`, metadata || '');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
getConsoleMethod(level) {
|
|
180
|
+
switch (level) {
|
|
181
|
+
case LogLevel.DEBUG:
|
|
182
|
+
case LogLevel.INFO:
|
|
183
|
+
return 'log';
|
|
184
|
+
case LogLevel.WARNING:
|
|
185
|
+
return 'warn';
|
|
186
|
+
case LogLevel.ERROR:
|
|
187
|
+
case LogLevel.CRITICAL:
|
|
188
|
+
case LogLevel.EMERGENCY:
|
|
189
|
+
return 'error';
|
|
190
|
+
default:
|
|
191
|
+
return 'log';
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
debug(message, metadata) {
|
|
195
|
+
if (this.currentLogLevel <= LogLevel.DEBUG) {
|
|
196
|
+
this.queueLog(LogLevel.DEBUG, message, metadata);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
info(message, metadata) {
|
|
200
|
+
if (this.currentLogLevel <= LogLevel.INFO) {
|
|
201
|
+
this.queueLog(LogLevel.INFO, message, metadata);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
warning(message, metadata) {
|
|
205
|
+
if (this.currentLogLevel <= LogLevel.WARNING) {
|
|
206
|
+
this.queueLog(LogLevel.WARNING, message, metadata);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
error(message, metadata) {
|
|
210
|
+
if (this.currentLogLevel <= LogLevel.ERROR) {
|
|
211
|
+
this.queueLog(LogLevel.ERROR, message, metadata);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
critical(message, metadata) {
|
|
215
|
+
if (this.currentLogLevel <= LogLevel.CRITICAL) {
|
|
216
|
+
this.queueLog(LogLevel.CRITICAL, message, metadata);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
emergency(message, metadata) {
|
|
220
|
+
if (this.currentLogLevel <= LogLevel.EMERGENCY) {
|
|
221
|
+
this.queueLog(LogLevel.EMERGENCY, message, metadata);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
setLogLevel(level) {
|
|
225
|
+
this.currentLogLevel = level;
|
|
226
|
+
this.info(`Log level changed to ${LogLevel[level]}`);
|
|
227
|
+
}
|
|
228
|
+
async getLogs(level, limit = 100) {
|
|
229
|
+
try {
|
|
230
|
+
const content = await fs.readFile(this.logFile, 'utf8');
|
|
231
|
+
const lines = content.split('\n').filter(line => line.trim());
|
|
232
|
+
if (level !== undefined) {
|
|
233
|
+
const levelName = LogLevel[level];
|
|
234
|
+
return lines
|
|
235
|
+
.filter(line => line.includes(`"level":"${levelName}"`))
|
|
236
|
+
.slice(-limit);
|
|
237
|
+
}
|
|
238
|
+
return lines.slice(-limit);
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
async getSecurityLogs(limit = 100) {
|
|
245
|
+
try {
|
|
246
|
+
const content = await fs.readFile(this.securityLogFile, 'utf8');
|
|
247
|
+
return content.split('\n').filter(line => line.trim()).slice(-limit);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async clearLogs() {
|
|
254
|
+
try {
|
|
255
|
+
await fs.writeFile(this.logFile, '');
|
|
256
|
+
await fs.writeFile(this.errorLogFile, '');
|
|
257
|
+
await fs.writeFile(this.securityLogFile, '');
|
|
258
|
+
this.info('Logs cleared');
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
console.error('Failed to clear logs:', error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async fileExists(filePath) {
|
|
265
|
+
try {
|
|
266
|
+
await fs.access(filePath);
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
getStatus() {
|
|
274
|
+
return {
|
|
275
|
+
logLevel: LogLevel[this.currentLogLevel],
|
|
276
|
+
logDir: this.logDir,
|
|
277
|
+
queueSize: this.logQueue.length,
|
|
278
|
+
isWriting: this.isWriting,
|
|
279
|
+
maxLogSize: this.maxLogSize,
|
|
280
|
+
maxLogFiles: this.maxLogFiles
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.Logger = Logger;
|
|
285
|
+
//# sourceMappingURL=Logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/utils/Logger.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs/promises';\nimport * as path from 'path';\n\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARNING = 2,\n ERROR = 3,\n CRITICAL = 4,\n EMERGENCY = 5\n}\n\nexport class Logger {\n private static instance: Logger;\n private readonly logDir: string;\n private readonly logFile: string;\n private readonly errorLogFile: string;\n private readonly securityLogFile: string;\n private currentLogLevel: LogLevel = LogLevel.INFO;\n private readonly maxLogSize: number = 10 * 1024 * 1024;\n private readonly maxLogFiles: number = 5;\n private logQueue: string[] = [];\n private isWriting: boolean = false;\n\n private constructor() {\n this.logDir = path.join(process.cwd(), 'logs');\n this.logFile = path.join(this.logDir, 'app.log');\n this.errorLogFile = path.join(this.logDir, 'error.log');\n this.securityLogFile = path.join(this.logDir, 'security.log');\n \n this.initializeLogging();\n this.startLogProcessor();\n }\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n\n private async initializeLogging(): Promise<void> {\n try {\n await fs.mkdir(this.logDir, { recursive: true, mode: 0o700 });\n \n await this.initializeLogFile(this.logFile);\n await this.initializeLogFile(this.errorLogFile);\n await this.initializeLogFile(this.securityLogFile);\n \n } catch (error) {\n console.error('Failed to initialize logging:', error);\n }\n }\n\n private async initializeLogFile(filePath: string): Promise<void> {\n try {\n const exists = await this.fileExists(filePath);\n if (!exists) {\n const header = `# Log file created at ${new Date().toISOString()}\\n`;\n await fs.writeFile(filePath, header);\n }\n } catch (error) {\n console.error(`Failed to initialize log file: ${filePath}`, error);\n }\n }\n\n private startLogProcessor(): void {\n setInterval(() => {\n this.processLogQueue();\n }, 1000);\n }\n\n private async processLogQueue(): Promise<void> {\n if (this.isWriting || this.logQueue.length === 0) {\n return;\n }\n\n this.isWriting = true;\n\n try {\n const entries = [...this.logQueue];\n this.logQueue = [];\n\n for (const entry of entries) {\n await this.writeLog(entry);\n }\n\n await this.rotateLogIfNeeded(this.logFile);\n await this.rotateLogIfNeeded(this.errorLogFile);\n await this.rotateLogIfNeeded(this.securityLogFile);\n \n } catch (error) {\n console.error('Failed to process log queue:', error);\n } finally {\n this.isWriting = false;\n }\n }\n\n private async writeLog(entry: string): Promise<void> {\n try {\n let logFile = this.logFile;\n \n if (entry.includes('\"level\":\"ERROR\"') || entry.includes('\"level\":\"CRITICAL\"')) {\n logFile = this.errorLogFile;\n } else if (entry.includes('\"level\":\"WARNING\"')) {\n logFile = this.securityLogFile;\n }\n\n await fs.appendFile(logFile, entry + '\\n');\n \n } catch (error) {\n console.error('Failed to write log:', error);\n }\n }\n\n private async rotateLogIfNeeded(logFile: string): Promise<void> {\n try {\n const stats = await fs.stat(logFile);\n \n if (stats.size > this.maxLogSize) {\n await this.rotateLog(logFile);\n }\n } catch {\n }\n }\n\n private async rotateLog(logFile: string): Promise<void> {\n for (let i = this.maxLogFiles - 1; i > 0; i--) {\n const oldFile = `${logFile}.${i}`;\n const newFile = `${logFile}.${i + 1}`;\n \n try {\n await fs.rename(oldFile, newFile);\n } catch {\n }\n }\n\n await fs.rename(logFile, `${logFile}.1`);\n await this.initializeLogFile(logFile);\n }\n\n private formatLogEntry(level: LogLevel, message: string, metadata?: any): string {\n const entry = {\n timestamp: new Date().toISOString(),\n level: LogLevel[level],\n pid: process.pid,\n message,\n metadata: metadata || {}\n };\n\n return JSON.stringify(entry);\n }\n\n private queueLog(level: LogLevel, message: string, metadata?: any): void {\n const entry = this.formatLogEntry(level, message, metadata);\n this.logQueue.push(entry);\n\n if (process.env.NODE_ENV === 'development') {\n const consoleMethod = this.getConsoleMethod(level);\n console[consoleMethod](`[${LogLevel[level]}] ${message}`, metadata || '');\n }\n }\n\n private getConsoleMethod(level: LogLevel): 'log' | 'info' | 'warn' | 'error' {\n switch (level) {\n case LogLevel.DEBUG:\n case LogLevel.INFO:\n return 'log';\n case LogLevel.WARNING:\n return 'warn';\n case LogLevel.ERROR:\n case LogLevel.CRITICAL:\n case LogLevel.EMERGENCY:\n return 'error';\n default:\n return 'log';\n }\n }\n\n public debug(message: string, metadata?: any): void {\n if (this.currentLogLevel <= LogLevel.DEBUG) {\n this.queueLog(LogLevel.DEBUG, message, metadata);\n }\n }\n\n public info(message: string, metadata?: any): void {\n if (this.currentLogLevel <= LogLevel.INFO) {\n this.queueLog(LogLevel.INFO, message, metadata);\n }\n }\n\n public warning(message: string, metadata?: any): void {\n if (this.currentLogLevel <= LogLevel.WARNING) {\n this.queueLog(LogLevel.WARNING, message, metadata);\n }\n }\n\n public error(message: string, metadata?: any): void {\n if (this.currentLogLevel <= LogLevel.ERROR) {\n this.queueLog(LogLevel.ERROR, message, metadata);\n }\n }\n\n public critical(message: string, metadata?: any): void {\n if (this.currentLogLevel <= LogLevel.CRITICAL) {\n this.queueLog(LogLevel.CRITICAL, message, metadata);\n }\n }\n\n public emergency(message: string, metadata?: any): void {\n if (this.currentLogLevel <= LogLevel.EMERGENCY) {\n this.queueLog(LogLevel.EMERGENCY, message, metadata);\n }\n }\n\n public setLogLevel(level: LogLevel): void {\n this.currentLogLevel = level;\n this.info(`Log level changed to ${LogLevel[level]}`);\n }\n\n public async getLogs(level?: LogLevel, limit: number = 100): Promise<string[]> {\n try {\n const content = await fs.readFile(this.logFile, 'utf8');\n const lines = content.split('\\n').filter(line => line.trim());\n \n if (level !== undefined) {\n const levelName = LogLevel[level];\n return lines\n .filter(line => line.includes(`\"level\":\"${levelName}\"`))\n .slice(-limit);\n }\n \n return lines.slice(-limit);\n } catch {\n return [];\n }\n }\n\n public async getSecurityLogs(limit: number = 100): Promise<string[]> {\n try {\n const content = await fs.readFile(this.securityLogFile, 'utf8');\n return content.split('\\n').filter(line => line.trim()).slice(-limit);\n } catch {\n return [];\n }\n }\n\n public async clearLogs(): Promise<void> {\n try {\n await fs.writeFile(this.logFile, '');\n await fs.writeFile(this.errorLogFile, '');\n await fs.writeFile(this.securityLogFile, '');\n \n this.info('Logs cleared');\n } catch (error) {\n console.error('Failed to clear logs:', error);\n }\n }\n\n private async fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n public getStatus(): any {\n return {\n logLevel: LogLevel[this.currentLogLevel],\n logDir: this.logDir,\n queueSize: this.logQueue.length,\n isWriting: this.isWriting,\n maxLogSize: this.maxLogSize,\n maxLogFiles: this.maxLogFiles\n };\n }\n}"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SecurityConfig } from '../types';
|
|
2
|
+
export declare class Validator {
|
|
3
|
+
private static instance;
|
|
4
|
+
private readonly logger;
|
|
5
|
+
private readonly config;
|
|
6
|
+
private constructor();
|
|
7
|
+
static getInstance(config?: SecurityConfig): Validator;
|
|
8
|
+
validateFilePath(filePath: string): boolean;
|
|
9
|
+
validateFileName(fileName: string): boolean;
|
|
10
|
+
validateFileExtension(extension: string): boolean;
|
|
11
|
+
validateFileSize(size: number): boolean;
|
|
12
|
+
validateHash(hash: string, algorithm?: string): boolean;
|
|
13
|
+
validateEmail(email: string): boolean;
|
|
14
|
+
validateUrl(url: string): boolean;
|
|
15
|
+
validateIpAddress(ip: string): boolean;
|
|
16
|
+
validatePort(port: number): boolean;
|
|
17
|
+
validateTimestamp(timestamp: number): boolean;
|
|
18
|
+
validatePermission(mode: number): boolean;
|
|
19
|
+
validateJson(json: string): boolean;
|
|
20
|
+
validateBase64(str: string): boolean;
|
|
21
|
+
validateHex(str: string): boolean;
|
|
22
|
+
validateAscii(str: string): boolean;
|
|
23
|
+
validateUtf8(buffer: Buffer): boolean;
|
|
24
|
+
validateChecksum(data: Buffer, checksum: string): boolean;
|
|
25
|
+
validateConfig(config: any): boolean;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=Validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.d.ts","sourceRoot":"","sources":["../../src/utils/Validator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,qBAAa,SAAS;IAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC,OAAO;WAKO,WAAW,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS;IAOtD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAgD3C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IA0B3C,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAmBjD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAavC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAiB,GAAG,OAAO;IAqBjE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAKrC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASjC,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAOtC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAQ7C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIzC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IASnC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASpC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIjC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAInC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IASrC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAQzD,cAAc,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO;CAkB9C"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Validator = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const Logger_1 = require("./Logger");
|
|
40
|
+
class Validator {
|
|
41
|
+
static instance;
|
|
42
|
+
logger;
|
|
43
|
+
config;
|
|
44
|
+
constructor(config) {
|
|
45
|
+
this.logger = Logger_1.Logger.getInstance();
|
|
46
|
+
this.config = config;
|
|
47
|
+
}
|
|
48
|
+
static getInstance(config) {
|
|
49
|
+
if (!Validator.instance && config) {
|
|
50
|
+
Validator.instance = new Validator(config);
|
|
51
|
+
}
|
|
52
|
+
return Validator.instance;
|
|
53
|
+
}
|
|
54
|
+
validateFilePath(filePath) {
|
|
55
|
+
try {
|
|
56
|
+
const normalized = path.normalize(filePath);
|
|
57
|
+
if (normalized.includes('..')) {
|
|
58
|
+
this.logger.warning('Path traversal detected', { filePath });
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (filePath.includes('\0')) {
|
|
62
|
+
this.logger.warning('Null byte in path', { filePath });
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (/[\x00-\x1F\x7F]/.test(filePath)) {
|
|
66
|
+
this.logger.warning('Control characters in path', { filePath });
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const suspiciousPatterns = [
|
|
70
|
+
/^\./,
|
|
71
|
+
/^\/etc/,
|
|
72
|
+
/^\/var/,
|
|
73
|
+
/^\/proc/,
|
|
74
|
+
/^\/dev/,
|
|
75
|
+
/^\/sys/,
|
|
76
|
+
/^\/boot/,
|
|
77
|
+
/^\/root/,
|
|
78
|
+
/^\/bin/,
|
|
79
|
+
/^\/sbin/,
|
|
80
|
+
/^\/usr/,
|
|
81
|
+
/^\/lib/
|
|
82
|
+
];
|
|
83
|
+
for (const pattern of suspiciousPatterns) {
|
|
84
|
+
if (pattern.test(filePath)) {
|
|
85
|
+
this.logger.warning('Suspicious path pattern', { filePath, pattern });
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
this.logger.error('Path validation error', { error, filePath });
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
validateFileName(fileName) {
|
|
97
|
+
if (fileName.length === 0 || fileName.length > 255) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
const invalidChars = /[<>:"/\\|?*\x00-\x1F]/g;
|
|
101
|
+
if (invalidChars.test(fileName)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const reservedNames = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;
|
|
105
|
+
if (reservedNames.test(fileName)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
if (fileName.startsWith('.') && !fileName.startsWith('.')) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (/[\u200B-\u200D\uFEFF]/.test(fileName)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
validateFileExtension(extension) {
|
|
117
|
+
const ext = extension.toLowerCase();
|
|
118
|
+
if (this.config.allowedExtensions.length > 0) {
|
|
119
|
+
return this.config.allowedExtensions.includes(ext);
|
|
120
|
+
}
|
|
121
|
+
const dangerousExtensions = [
|
|
122
|
+
'.exe', '.dll', '.so', '.dylib', '.bin',
|
|
123
|
+
'.sh', '.bash', '.cmd', '.bat', '.ps1',
|
|
124
|
+
'.vbs', '.js', '.jar', '.class', '.py',
|
|
125
|
+
'.rb', '.pl', '.php', '.asp', '.aspx',
|
|
126
|
+
'.jsp', '.cgi', '.swf', '.apk', '.app',
|
|
127
|
+
'.deb', '.rpm', '.msi'
|
|
128
|
+
];
|
|
129
|
+
return !dangerousExtensions.includes(ext);
|
|
130
|
+
}
|
|
131
|
+
validateFileSize(size) {
|
|
132
|
+
if (size <= 0) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
if (size > this.config.maxFileSize) {
|
|
136
|
+
this.logger.warning('File too large', { size, max: this.config.maxFileSize });
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
validateHash(hash, algorithm = 'sha512') {
|
|
142
|
+
const hashLengths = {
|
|
143
|
+
md5: 32,
|
|
144
|
+
sha1: 40,
|
|
145
|
+
sha256: 64,
|
|
146
|
+
sha384: 96,
|
|
147
|
+
sha512: 128
|
|
148
|
+
};
|
|
149
|
+
const expectedLength = hashLengths[algorithm];
|
|
150
|
+
if (!expectedLength) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (hash.length !== expectedLength) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
return /^[0-9a-f]+$/i.test(hash);
|
|
157
|
+
}
|
|
158
|
+
validateEmail(email) {
|
|
159
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
160
|
+
return emailRegex.test(email);
|
|
161
|
+
}
|
|
162
|
+
validateUrl(url) {
|
|
163
|
+
try {
|
|
164
|
+
new URL(url);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
validateIpAddress(ip) {
|
|
172
|
+
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
173
|
+
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
|
|
174
|
+
return ipv4Regex.test(ip) || ipv6Regex.test(ip);
|
|
175
|
+
}
|
|
176
|
+
validatePort(port) {
|
|
177
|
+
return port > 0 && port < 65536;
|
|
178
|
+
}
|
|
179
|
+
validateTimestamp(timestamp) {
|
|
180
|
+
const now = Date.now();
|
|
181
|
+
const oneYearAgo = now - 365 * 24 * 60 * 60 * 1000;
|
|
182
|
+
const oneYearFromNow = now + 365 * 24 * 60 * 60 * 1000;
|
|
183
|
+
return timestamp > oneYearAgo && timestamp < oneYearFromNow;
|
|
184
|
+
}
|
|
185
|
+
validatePermission(mode) {
|
|
186
|
+
return mode >= 0 && mode <= 0o777;
|
|
187
|
+
}
|
|
188
|
+
validateJson(json) {
|
|
189
|
+
try {
|
|
190
|
+
JSON.parse(json);
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
validateBase64(str) {
|
|
198
|
+
try {
|
|
199
|
+
const encoded = Buffer.from(str, 'base64').toString('base64');
|
|
200
|
+
return encoded === str;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
validateHex(str) {
|
|
207
|
+
return /^[0-9a-fA-F]+$/.test(str);
|
|
208
|
+
}
|
|
209
|
+
validateAscii(str) {
|
|
210
|
+
return /^[\x00-\x7F]*$/.test(str);
|
|
211
|
+
}
|
|
212
|
+
validateUtf8(buffer) {
|
|
213
|
+
try {
|
|
214
|
+
buffer.toString('utf8');
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
validateChecksum(data, checksum) {
|
|
222
|
+
const hash = crypto.createHash('sha256')
|
|
223
|
+
.update(data)
|
|
224
|
+
.digest('hex');
|
|
225
|
+
return hash === checksum;
|
|
226
|
+
}
|
|
227
|
+
validateConfig(config) {
|
|
228
|
+
const requiredFields = [
|
|
229
|
+
'watchDir',
|
|
230
|
+
'hashAlgorithm',
|
|
231
|
+
'backupDir',
|
|
232
|
+
'maxFileSize',
|
|
233
|
+
'scanInterval'
|
|
234
|
+
];
|
|
235
|
+
for (const field of requiredFields) {
|
|
236
|
+
if (!(field in config)) {
|
|
237
|
+
this.logger.error(`Missing required config field: ${field}`);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
exports.Validator = Validator;
|
|
245
|
+
//# sourceMappingURL=Validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.js","sourceRoot":"","sources":["../../src/utils/Validator.ts"],"names":[],"mappings":"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","sourcesContent":["import * as crypto from 'crypto';\nimport * as path from 'path';\nimport { SecurityConfig } from '../types';\nimport { Logger } from './Logger';\n\nexport class Validator {\n private static instance: Validator;\n private readonly logger: Logger;\n private readonly config: SecurityConfig;\n\n private constructor(config: SecurityConfig) {\n this.logger = Logger.getInstance();\n this.config = config;\n }\n\n public static getInstance(config?: SecurityConfig): Validator {\n if (!Validator.instance && config) {\n Validator.instance = new Validator(config);\n }\n return Validator.instance;\n }\n\n public validateFilePath(filePath: string): boolean {\n try {\n const normalized = path.normalize(filePath);\n \n if (normalized.includes('..')) {\n this.logger.warning('Path traversal detected', { filePath });\n return false;\n }\n\n if (filePath.includes('\\0')) {\n this.logger.warning('Null byte in path', { filePath });\n return false;\n }\n\n if (/[\\x00-\\x1F\\x7F]/.test(filePath)) {\n this.logger.warning('Control characters in path', { filePath });\n return false;\n }\n\n const suspiciousPatterns = [\n /^\\./,\n /^\\/etc/,\n /^\\/var/,\n /^\\/proc/,\n /^\\/dev/,\n /^\\/sys/,\n /^\\/boot/,\n /^\\/root/,\n /^\\/bin/,\n /^\\/sbin/,\n /^\\/usr/,\n /^\\/lib/\n ];\n\n for (const pattern of suspiciousPatterns) {\n if (pattern.test(filePath)) {\n this.logger.warning('Suspicious path pattern', { filePath, pattern });\n return false;\n }\n }\n\n return true;\n } catch (error) {\n this.logger.error('Path validation error', { error, filePath });\n return false;\n }\n }\n\n public validateFileName(fileName: string): boolean {\n if (fileName.length === 0 || fileName.length > 255) {\n return false;\n }\n\n const invalidChars = /[<>:\"/\\\\|?*\\x00-\\x1F]/g;\n if (invalidChars.test(fileName)) {\n return false;\n }\n\n const reservedNames = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;\n if (reservedNames.test(fileName)) {\n return false;\n }\n\n if (fileName.startsWith('.') && !fileName.startsWith('.')) {\n return false;\n }\n\n if (/[\\u200B-\\u200D\\uFEFF]/.test(fileName)) {\n return false;\n }\n\n return true;\n }\n\n public validateFileExtension(extension: string): boolean {\n const ext = extension.toLowerCase();\n \n if (this.config.allowedExtensions.length > 0) {\n return this.config.allowedExtensions.includes(ext);\n }\n\n const dangerousExtensions = [\n '.exe', '.dll', '.so', '.dylib', '.bin',\n '.sh', '.bash', '.cmd', '.bat', '.ps1',\n '.vbs', '.js', '.jar', '.class', '.py',\n '.rb', '.pl', '.php', '.asp', '.aspx',\n '.jsp', '.cgi', '.swf', '.apk', '.app',\n '.deb', '.rpm', '.msi'\n ];\n\n return !dangerousExtensions.includes(ext);\n }\n\n public validateFileSize(size: number): boolean {\n if (size <= 0) {\n return false;\n }\n\n if (size > this.config.maxFileSize) {\n this.logger.warning('File too large', { size, max: this.config.maxFileSize });\n return false;\n }\n\n return true;\n }\n\n public validateHash(hash: string, algorithm: string = 'sha512'): boolean {\n const hashLengths: Record<string, number> = {\n md5: 32,\n sha1: 40,\n sha256: 64,\n sha384: 96,\n sha512: 128\n };\n\n const expectedLength = hashLengths[algorithm];\n if (!expectedLength) {\n return false;\n }\n\n if (hash.length !== expectedLength) {\n return false;\n }\n\n return /^[0-9a-f]+$/i.test(hash);\n }\n\n public validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n\n public validateUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n\n public validateIpAddress(ip: string): boolean {\n const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\n \n return ipv4Regex.test(ip) || ipv6Regex.test(ip);\n }\n\n public validatePort(port: number): boolean {\n return port > 0 && port < 65536;\n }\n\n public validateTimestamp(timestamp: number): boolean {\n const now = Date.now();\n const oneYearAgo = now - 365 * 24 * 60 * 60 * 1000;\n const oneYearFromNow = now + 365 * 24 * 60 * 60 * 1000;\n \n return timestamp > oneYearAgo && timestamp < oneYearFromNow;\n }\n\n public validatePermission(mode: number): boolean {\n return mode >= 0 && mode <= 0o777;\n }\n\n public validateJson(json: string): boolean {\n try {\n JSON.parse(json);\n return true;\n } catch {\n return false;\n }\n }\n\n public validateBase64(str: string): boolean {\n try {\n const encoded = Buffer.from(str, 'base64').toString('base64');\n return encoded === str;\n } catch {\n return false;\n }\n }\n\n public validateHex(str: string): boolean {\n return /^[0-9a-fA-F]+$/.test(str);\n }\n\n public validateAscii(str: string): boolean {\n return /^[\\x00-\\x7F]*$/.test(str);\n }\n\n public validateUtf8(buffer: Buffer): boolean {\n try {\n buffer.toString('utf8');\n return true;\n } catch {\n return false;\n }\n }\n\n public validateChecksum(data: Buffer, checksum: string): boolean {\n const hash = crypto.createHash('sha256')\n .update(data)\n .digest('hex');\n \n return hash === checksum;\n }\n\n public validateConfig(config: any): boolean {\n const requiredFields = [\n 'watchDir',\n 'hashAlgorithm',\n 'backupDir',\n 'maxFileSize',\n 'scanInterval'\n ];\n\n for (const field of requiredFields) {\n if (!(field in config)) {\n this.logger.error(`Missing required config field: ${field}`);\n return false;\n }\n }\n\n return true;\n }\n}"]}
|
package/favicon.png
ADDED
|
Binary file
|