i18ntk 1.10.2 ā 2.0.2
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/LICENSE +1 -1
- package/README.md +141 -1191
- package/main/i18ntk-analyze.js +65 -84
- package/main/i18ntk-backup-class.js +420 -0
- package/main/i18ntk-backup.js +3 -3
- package/main/i18ntk-complete.js +90 -65
- package/main/i18ntk-doctor.js +123 -103
- package/main/i18ntk-fixer.js +61 -725
- package/main/i18ntk-go.js +14 -15
- package/main/i18ntk-init.js +77 -26
- package/main/i18ntk-java.js +27 -32
- package/main/i18ntk-js.js +70 -68
- package/main/i18ntk-manage.js +129 -30
- package/main/i18ntk-php.js +75 -75
- package/main/i18ntk-py.js +55 -56
- package/main/i18ntk-scanner.js +59 -57
- package/main/i18ntk-setup.js +9 -404
- package/main/i18ntk-sizing.js +6 -6
- package/main/i18ntk-summary.js +21 -18
- package/main/i18ntk-ui.js +11 -10
- package/main/i18ntk-usage.js +54 -18
- package/main/i18ntk-validate.js +13 -13
- package/main/manage/commands/AnalyzeCommand.js +1124 -0
- package/main/manage/commands/BackupCommand.js +62 -0
- package/main/manage/commands/CommandRouter.js +295 -0
- package/main/manage/commands/CompleteCommand.js +61 -0
- package/main/manage/commands/DoctorCommand.js +60 -0
- package/main/manage/commands/FixerCommand.js +624 -0
- package/main/manage/commands/InitCommand.js +62 -0
- package/main/manage/commands/ScannerCommand.js +654 -0
- package/main/manage/commands/SizingCommand.js +60 -0
- package/main/manage/commands/SummaryCommand.js +61 -0
- package/main/manage/commands/UsageCommand.js +60 -0
- package/main/manage/commands/ValidateCommand.js +978 -0
- package/main/manage/index-fixed.js +1447 -0
- package/main/manage/index.js +1462 -0
- package/main/manage/managers/DebugMenu.js +140 -0
- package/main/manage/managers/InteractiveMenu.js +177 -0
- package/main/manage/managers/LanguageMenu.js +62 -0
- package/main/manage/managers/SettingsMenu.js +53 -0
- package/main/manage/services/AuthenticationService.js +263 -0
- package/main/manage/services/ConfigurationService-fixed.js +449 -0
- package/main/manage/services/ConfigurationService.js +449 -0
- package/main/manage/services/FileManagementService.js +368 -0
- package/main/manage/services/FrameworkDetectionService.js +458 -0
- package/main/manage/services/InitService.js +1051 -0
- package/main/manage/services/SetupService.js +462 -0
- package/main/manage/services/SummaryService.js +450 -0
- package/main/manage/services/UsageService.js +1502 -0
- package/package.json +32 -29
- package/runtime/enhanced.d.ts +221 -221
- package/runtime/index.d.ts +29 -29
- package/runtime/index.full.d.ts +331 -331
- package/runtime/index.js +7 -6
- package/scripts/build-lite.js +17 -17
- package/scripts/deprecate-versions.js +23 -6
- package/scripts/export-translations.js +5 -5
- package/scripts/fix-all-i18n.js +3 -3
- package/scripts/fix-and-purify-i18n.js +3 -2
- package/scripts/fix-locale-control-chars.js +110 -0
- package/scripts/lint-locales.js +80 -0
- package/scripts/locale-optimizer.js +8 -8
- package/scripts/prepublish.js +21 -21
- package/scripts/security-check.js +117 -117
- package/scripts/sync-translations.js +4 -4
- package/scripts/sync-ui-locales.js +9 -8
- package/scripts/validate-all-translations.js +8 -7
- package/scripts/verify-deprecations.js +157 -161
- package/scripts/verify-translations.js +6 -5
- package/settings/i18ntk-config.json +282 -282
- package/settings/language-config.json +5 -5
- package/settings/settings-cli.js +9 -9
- package/settings/settings-manager.js +18 -18
- package/ui-locales/de.json +2417 -2348
- package/ui-locales/en.json +2415 -2352
- package/ui-locales/es.json +2425 -2353
- package/ui-locales/fr.json +2418 -2348
- package/ui-locales/ja.json +2463 -2361
- package/ui-locales/ru.json +2463 -2359
- package/ui-locales/zh.json +2418 -2351
- package/utils/admin-auth.js +2 -2
- package/utils/admin-cli.js +297 -297
- package/utils/admin-pin.js +9 -9
- package/utils/cli-helper.js +9 -9
- package/utils/config-helper.js +73 -104
- package/utils/config-manager.js +204 -171
- package/utils/config.js +5 -4
- package/utils/env-manager.js +249 -263
- package/utils/framework-detector.js +27 -24
- package/utils/i18n-helper.js +85 -41
- package/utils/init-helper.js +152 -94
- package/utils/json-output.js +98 -98
- package/utils/mini-commander.js +179 -0
- package/utils/missing-key-validator.js +5 -5
- package/utils/plugin-loader.js +40 -29
- package/utils/prompt.js +14 -44
- package/utils/safe-json.js +40 -0
- package/utils/secure-errors.js +3 -3
- package/utils/security-check-improved.js +390 -0
- package/utils/security-config.js +5 -5
- package/utils/security-fixed.js +607 -0
- package/utils/security.js +652 -602
- package/utils/setup-enforcer.js +136 -44
- package/utils/setup-validator.js +33 -32
- package/utils/ultra-performance-optimizer.js +11 -9
- package/utils/watch-locales.js +2 -1
- package/utils/prompt-fixed.js +0 -55
- package/utils/security-check.js +0 -454
package/utils/security-check.js
DELETED
|
@@ -1,454 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Security Check Utility
|
|
5
|
-
* Runs automated security checks and provides recommendations
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const { envManager } = require('./env-manager');
|
|
11
|
-
|
|
12
|
-
class SecurityChecker {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.checks = [];
|
|
15
|
-
this.recommendations = [];
|
|
16
|
-
this.isSilent = this.shouldBeSilent();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Check if we should suppress output (e.g., during npm install)
|
|
21
|
-
*/
|
|
22
|
-
shouldBeSilent() {
|
|
23
|
-
// Determine silent mode based on environment variables
|
|
24
|
-
const logLevel = envManager.get('I18NTK_LOG_LEVEL');
|
|
25
|
-
const silentMode = envManager.get('I18NTK_SILENT');
|
|
26
|
-
const isSilent = (
|
|
27
|
-
process.env.npm_config_loglevel === 'silent' ||
|
|
28
|
-
silentMode === 'true' ||
|
|
29
|
-
process.env.CI === 'true'
|
|
30
|
-
);
|
|
31
|
-
return isSilent;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Log message only if not silent
|
|
36
|
-
*/
|
|
37
|
-
log(message) {
|
|
38
|
-
if (!this.isSilent) {
|
|
39
|
-
console.log(message);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Run all security checks
|
|
45
|
-
*/
|
|
46
|
-
async runSecurityChecks() {
|
|
47
|
-
this.log('š Running security checks...\n');
|
|
48
|
-
|
|
49
|
-
this.checkSensitiveFiles();
|
|
50
|
-
this.checkConfigurationFiles();
|
|
51
|
-
this.checkDependencies();
|
|
52
|
-
this.checkEncryptionConfig();
|
|
53
|
-
this.checkAccessPermissions();
|
|
54
|
-
|
|
55
|
-
this.generateReport();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Check for sensitive files that shouldn't be committed
|
|
60
|
-
*/
|
|
61
|
-
checkSensitiveFiles() {
|
|
62
|
-
const sensitivePatterns = [
|
|
63
|
-
'.env',
|
|
64
|
-
'*.key',
|
|
65
|
-
'*.pem',
|
|
66
|
-
'admin-pin.json',
|
|
67
|
-
'config.json',
|
|
68
|
-
'secrets.json'
|
|
69
|
-
];
|
|
70
|
-
|
|
71
|
-
const gitignorePath = '.gitignore';
|
|
72
|
-
let gitignoreContent = '';
|
|
73
|
-
|
|
74
|
-
if (fs.existsSync(gitignorePath)) {
|
|
75
|
-
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const issues = [];
|
|
79
|
-
sensitivePatterns.forEach(pattern => {
|
|
80
|
-
const files = this.findFiles(pattern);
|
|
81
|
-
files.forEach(file => {
|
|
82
|
-
if (!gitignoreContent.includes(file)) {
|
|
83
|
-
issues.push(file);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
this.checks.push({
|
|
89
|
-
name: 'Sensitive Files Protection',
|
|
90
|
-
status: issues.length === 0 ? 'PASS' : 'WARN',
|
|
91
|
-
issues: issues,
|
|
92
|
-
message: issues.length > 0 ? `${issues.length} sensitive files not in .gitignore` : 'All sensitive files protected'
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Check configuration files
|
|
98
|
-
*/
|
|
99
|
-
checkConfigurationFiles() {
|
|
100
|
-
const configFiles = ['i18ntk-config.json', 'config.json'];
|
|
101
|
-
const hasConfigFile = configFiles.some(file => fs.existsSync(file));
|
|
102
|
-
|
|
103
|
-
this.checks.push({
|
|
104
|
-
name: 'Configuration Files',
|
|
105
|
-
status: hasConfigFile ? 'PASS' : 'WARN',
|
|
106
|
-
message: hasConfigFile ? 'Configuration files configured' : 'Consider creating i18ntk-config.json'
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Check for default PINs in config
|
|
110
|
-
const defaultPinFiles = ['i18ntk-config.json', 'config.json'];
|
|
111
|
-
defaultPinFiles.forEach(file => {
|
|
112
|
-
if (fs.existsSync(file)) {
|
|
113
|
-
try {
|
|
114
|
-
const config = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
115
|
-
if (config.adminPin && ['1234', '0000', 'admin', 'password'].includes(config.adminPin)) {
|
|
116
|
-
this.checks.push({
|
|
117
|
-
name: 'Default PIN Check',
|
|
118
|
-
status: 'FAIL',
|
|
119
|
-
message: `Default PIN detected in ${file}: ${config.adminPin}`
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
// Ignore parse errors
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Check dependencies for vulnerabilities
|
|
131
|
-
*/
|
|
132
|
-
checkDependencies() {
|
|
133
|
-
try {
|
|
134
|
-
// Check if package-lock.json exists and analyze dependencies safely
|
|
135
|
-
const packageLockPath = 'package-lock.json';
|
|
136
|
-
const packagePath = 'package.json';
|
|
137
|
-
|
|
138
|
-
let hasVulnerabilities = false;
|
|
139
|
-
let criticalCount = 0;
|
|
140
|
-
let highCount = 0;
|
|
141
|
-
let moderateCount = 0;
|
|
142
|
-
|
|
143
|
-
if (fs.existsSync(packageLockPath)) {
|
|
144
|
-
try {
|
|
145
|
-
const packageLock = JSON.parse(fs.readFileSync(packageLockPath, 'utf8'));
|
|
146
|
-
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
147
|
-
|
|
148
|
-
// Check for outdated dependencies by comparing versions
|
|
149
|
-
const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
150
|
-
|
|
151
|
-
// Simple heuristic: check if any dependencies are significantly outdated
|
|
152
|
-
// This is a safe alternative to npm audit
|
|
153
|
-
const outdatedPackages = this.checkOutdatedPackages(dependencies, packageLock);
|
|
154
|
-
|
|
155
|
-
// Set conservative counts based on outdated packages
|
|
156
|
-
criticalCount = outdatedPackages.filter(p => p.severity === 'critical').length;
|
|
157
|
-
highCount = outdatedPackages.filter(p => p.severity === 'high').length;
|
|
158
|
-
moderateCount = outdatedPackages.filter(p => p.severity === 'moderate').length;
|
|
159
|
-
|
|
160
|
-
} catch (parseError) {
|
|
161
|
-
// Handle JSON parsing errors
|
|
162
|
-
hasVulnerabilities = true;
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
// No package-lock.json, suggest running npm install
|
|
166
|
-
hasVulnerabilities = true;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
let status = 'PASS';
|
|
170
|
-
if (criticalCount > 0) status = 'FAIL';
|
|
171
|
-
else if (highCount > 0) status = 'WARN';
|
|
172
|
-
else if (moderateCount > 5) status = 'WARN';
|
|
173
|
-
|
|
174
|
-
this.checks.push({
|
|
175
|
-
name: 'Dependency Vulnerabilities',
|
|
176
|
-
status: status,
|
|
177
|
-
message: `Critical: ${criticalCount}, High: ${highCount}, Moderate: ${moderateCount}`,
|
|
178
|
-
details: { critical: criticalCount, high: highCount, moderate: moderateCount }
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
} catch (error) {
|
|
182
|
-
this.checks.push({
|
|
183
|
-
name: 'Dependency Vulnerabilities',
|
|
184
|
-
status: 'WARN',
|
|
185
|
-
message: 'Unable to analyze dependencies - run npm audit manually'
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Check encryption configuration
|
|
192
|
-
*/
|
|
193
|
-
checkEncryptionConfig() {
|
|
194
|
-
const adminPinPath = 'admin-pin.json';
|
|
195
|
-
|
|
196
|
-
if (fs.existsSync(adminPinPath)) {
|
|
197
|
-
try {
|
|
198
|
-
const pinData = JSON.parse(fs.readFileSync(adminPinPath, 'utf8'));
|
|
199
|
-
|
|
200
|
-
// Check for old encryption methods
|
|
201
|
-
if (pinData.hash && pinData.hash.length === 64) {
|
|
202
|
-
// SHA256 hash - old method
|
|
203
|
-
this.checks.push({
|
|
204
|
-
name: 'Encryption Method',
|
|
205
|
-
status: 'WARN',
|
|
206
|
-
message: 'Old SHA256 hashing detected - consider upgrading to scrypt'
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Check for secure algorithm
|
|
211
|
-
if (pinData.algorithm && ['scrypt', 'pbkdf2'].includes(pinData.algorithm)) {
|
|
212
|
-
this.checks.push({
|
|
213
|
-
name: 'Hashing Algorithm',
|
|
214
|
-
status: 'PASS',
|
|
215
|
-
message: `Using secure hashing: ${pinData.algorithm}`
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
} catch (error) {
|
|
220
|
-
this.checks.push({
|
|
221
|
-
name: 'Encryption Configuration',
|
|
222
|
-
status: 'WARN',
|
|
223
|
-
message: 'Unable to read PIN configuration'
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
} else {
|
|
227
|
-
this.checks.push({
|
|
228
|
-
name: 'Encryption Configuration',
|
|
229
|
-
status: 'INFO',
|
|
230
|
-
message: 'No PIN configuration found - will be created on first admin setup'
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Check file permissions
|
|
237
|
-
*/
|
|
238
|
-
checkAccessPermissions() {
|
|
239
|
-
const sensitiveFiles = ['admin-pin.json', 'config.json', 'i18ntk-config.json'];
|
|
240
|
-
|
|
241
|
-
sensitiveFiles.forEach(file => {
|
|
242
|
-
if (fs.existsSync(file)) {
|
|
243
|
-
try {
|
|
244
|
-
const stats = fs.statSync(file);
|
|
245
|
-
const mode = stats.mode & parseInt('777', 8);
|
|
246
|
-
|
|
247
|
-
if (mode > parseInt('600', 8)) {
|
|
248
|
-
this.checks.push({
|
|
249
|
-
name: `File Permissions (${file})`,
|
|
250
|
-
status: 'WARN',
|
|
251
|
-
message: `File permissions are ${mode.toString(8)} - consider 600 or stricter`
|
|
252
|
-
});
|
|
253
|
-
} else {
|
|
254
|
-
this.checks.push({
|
|
255
|
-
name: `File Permissions (${file})`,
|
|
256
|
-
status: 'PASS',
|
|
257
|
-
message: 'File permissions are secure'
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
} catch (error) {
|
|
261
|
-
// Ignore permission errors
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Find files matching pattern
|
|
269
|
-
*/
|
|
270
|
-
findFiles(pattern) {
|
|
271
|
-
try {
|
|
272
|
-
return this.findFilesRecursively('.', pattern);
|
|
273
|
-
} catch (error) {
|
|
274
|
-
return [];
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Recursively find files matching pattern (safe alternative to find command)
|
|
280
|
-
*/
|
|
281
|
-
findFilesRecursively(dir, pattern) {
|
|
282
|
-
const results = [];
|
|
283
|
-
|
|
284
|
-
try {
|
|
285
|
-
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
286
|
-
|
|
287
|
-
items.forEach(item => {
|
|
288
|
-
const fullPath = path.join(dir, item.name);
|
|
289
|
-
|
|
290
|
-
if (item.isDirectory()) {
|
|
291
|
-
// Skip node_modules and hidden directories
|
|
292
|
-
if (item.name !== 'node_modules' && !item.name.startsWith('.')) {
|
|
293
|
-
results.push(...this.findFilesRecursively(fullPath, pattern));
|
|
294
|
-
}
|
|
295
|
-
} else if (item.isFile()) {
|
|
296
|
-
// Simple pattern matching
|
|
297
|
-
const regex = new RegExp(pattern.replace(/\*/g, '.*').replace(/\?/g, '.'));
|
|
298
|
-
if (regex.test(item.name)) {
|
|
299
|
-
results.push(fullPath);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
} catch (error) {
|
|
304
|
-
// Ignore permission errors
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return results;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Check for outdated packages (safe alternative to npm audit)
|
|
312
|
-
*/
|
|
313
|
-
checkOutdatedPackages(dependencies, packageLock) {
|
|
314
|
-
const outdated = [];
|
|
315
|
-
|
|
316
|
-
if (!packageLock.packages) return outdated;
|
|
317
|
-
|
|
318
|
-
Object.keys(dependencies || {}).forEach(depName => {
|
|
319
|
-
const requiredVersion = dependencies[depName];
|
|
320
|
-
const installed = packageLock.packages[`node_modules/${depName}`];
|
|
321
|
-
|
|
322
|
-
if (installed && installed.version) {
|
|
323
|
-
// Simple heuristic: if version doesn't match exactly, flag as outdated
|
|
324
|
-
if (!this.versionMatches(requiredVersion, installed.version)) {
|
|
325
|
-
outdated.push({
|
|
326
|
-
name: depName,
|
|
327
|
-
required: requiredVersion,
|
|
328
|
-
installed: installed.version,
|
|
329
|
-
severity: this.determineSeverity(depName, installed.version)
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
return outdated;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Check if version matches requirement (simplified)
|
|
340
|
-
*/
|
|
341
|
-
versionMatches(required, installed) {
|
|
342
|
-
// Simplified version check - exact match for now
|
|
343
|
-
return installed.startsWith(required.replace(/[^\d.]/g, ''));
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Determine severity based on package name (heuristic)
|
|
348
|
-
*/
|
|
349
|
-
determineSeverity(packageName, version) {
|
|
350
|
-
// High-risk packages that should be updated
|
|
351
|
-
const highRisk = ['lodash', 'moment', 'request', 'axios', 'express', 'react'];
|
|
352
|
-
if (highRisk.includes(packageName)) return 'high';
|
|
353
|
-
|
|
354
|
-
// Critical packages with known vulnerabilities
|
|
355
|
-
const criticalRisk = ['lodash', 'moment', 'handlebars', 'validator'];
|
|
356
|
-
if (criticalRisk.includes(packageName) && version.startsWith('1.')) return 'critical';
|
|
357
|
-
|
|
358
|
-
return 'moderate';
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Generate security report
|
|
363
|
-
*/
|
|
364
|
-
generateReport() {
|
|
365
|
-
if (this.isSilent) {
|
|
366
|
-
// In silent mode, just exit without showing any output
|
|
367
|
-
const summary = {
|
|
368
|
-
PASS: 0,
|
|
369
|
-
WARN: 0,
|
|
370
|
-
FAIL: 0,
|
|
371
|
-
INFO: 0
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
this.checks.forEach(check => {
|
|
375
|
-
summary[check.status]++;
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
// Still exit with appropriate code for CI/CD
|
|
379
|
-
if (summary.FAIL > 0) {
|
|
380
|
-
process.exit(1);
|
|
381
|
-
} else {
|
|
382
|
-
process.exit(0);
|
|
383
|
-
}
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
this.log('\nš Security Check Report\n');
|
|
388
|
-
|
|
389
|
-
const summary = {
|
|
390
|
-
PASS: 0,
|
|
391
|
-
WARN: 0,
|
|
392
|
-
FAIL: 0,
|
|
393
|
-
INFO: 0
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
this.checks.forEach(check => {
|
|
397
|
-
summary[check.status]++;
|
|
398
|
-
const icon = {
|
|
399
|
-
PASS: 'ā
',
|
|
400
|
-
WARN: 'ā ļø',
|
|
401
|
-
FAIL: 'ā',
|
|
402
|
-
INFO: 'ā¹ļø'
|
|
403
|
-
}[check.status];
|
|
404
|
-
|
|
405
|
-
this.log(`${icon} ${check.name}: ${check.message}`);
|
|
406
|
-
if (check.issues) {
|
|
407
|
-
check.issues.forEach(issue => this.log(` - ${issue}`));
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
this.log('\nš Summary:');
|
|
412
|
-
this.log(`ā
PASS: ${summary.PASS}`);
|
|
413
|
-
this.log(`ā ļø WARN: ${summary.WARN}`);
|
|
414
|
-
this.log(`ā FAIL: ${summary.FAIL}`);
|
|
415
|
-
this.log(`ā¹ļø INFO: ${summary.INFO}`);
|
|
416
|
-
|
|
417
|
-
// Provide recommendations
|
|
418
|
-
this.log('\nš§ Recommendations:');
|
|
419
|
-
|
|
420
|
-
if (summary.FAIL > 0) {
|
|
421
|
-
this.log('šØ Critical issues found - address immediately:');
|
|
422
|
-
this.log(' - Run: npm audit fix');
|
|
423
|
-
this.log(' - Review and update default passwords');
|
|
424
|
-
this.log(' - Check .gitignore for sensitive files');
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (summary.WARN > 0) {
|
|
428
|
-
this.log('ā ļø Warnings to address:');
|
|
429
|
-
this.log(' - Review file permissions');
|
|
430
|
-
this.log(' - Update dependencies');
|
|
431
|
-
this.log(' - Create .env.example if missing');
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
this.log('\nš For more information, see:');
|
|
435
|
-
this.log(' - SECURITY.md - Complete security guide');
|
|
436
|
-
this.log(' - npm run security:config - Generate secure configuration');
|
|
437
|
-
this.log(' - npm run security:audit - Run vulnerability scan');
|
|
438
|
-
|
|
439
|
-
// Exit with appropriate code
|
|
440
|
-
if (summary.FAIL > 0) {
|
|
441
|
-
process.exit(1);
|
|
442
|
-
} else if (summary.WARN > 0) {
|
|
443
|
-
process.exit(0); // Warnings don't fail the build
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// Run security checks if called directly
|
|
449
|
-
if (require.main === module) {
|
|
450
|
-
const checker = new SecurityChecker();
|
|
451
|
-
checker.runSecurityChecks().catch(console.error);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
module.exports = SecurityChecker;
|