i18ntk 1.7.0 → 1.7.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/README.md +18 -55
- package/main/i18ntk-analyze.js +2 -2
- package/main/i18ntk-autorun.js +1 -1
- package/main/i18ntk-complete.js +1 -1
- package/main/i18ntk-init.js +42 -9
- package/main/i18ntk-manage.js +236 -40
- package/main/i18ntk-sizing.js +2 -2
- package/main/i18ntk-summary.js +2 -2
- package/main/i18ntk-ui.js +6 -0
- package/main/i18ntk-usage.js +2 -2
- package/main/i18ntk-validate.js +47 -11
- package/package.json +7 -8
- package/scripts/admin-auth.test.js +21 -0
- package/scripts/prepublish.js +1 -1
- package/settings/.i18n-admin-config.json +2 -2
- package/settings/i18ntk-config.json +0 -1
- package/settings/initialization.json +7 -0
- package/settings/settings-cli.js +1 -1
- package/settings/settings-manager.js +2 -2
- package/ui-locales/de.json +2 -0
- package/ui-locales/en.json +2 -0
- package/ui-locales/es.json +2 -0
- package/ui-locales/fr.json +2 -0
- package/ui-locales/ja.json +2 -0
- package/ui-locales/ru.json +35 -33
- package/ui-locales/zh.json +2 -0
- package/utils/admin-auth.js +88 -19
- package/utils/admin-cli.js +15 -3
- package/utils/admin-pin.js +519 -526
- package/utils/cli-helper.js +84 -11
- package/utils/config-helper.js +60 -6
- package/utils/config-manager.js +2 -1
- package/utils/config.js +41 -0
- package/utils/i18n-helper.js +2 -1
- package/utils/promptPin.js +76 -0
- package/utils/security-check.js +6 -2
- package/utils/security.js +1 -1
package/utils/admin-auth.js
CHANGED
|
@@ -10,7 +10,8 @@ const configManager = require('./config-manager');
|
|
|
10
10
|
*/
|
|
11
11
|
class AdminAuth {
|
|
12
12
|
constructor() {
|
|
13
|
-
|
|
13
|
+
const settingsDir = require('../settings/settings-manager').configDir;
|
|
14
|
+
this.configPath = path.join(settingsDir, '.i18n-admin-config.json');
|
|
14
15
|
|
|
15
16
|
// Get settings from config manager
|
|
16
17
|
const settings = configManager.loadSettings ? configManager.loadSettings() : (configManager.getConfig ? configManager.getConfig() : {});
|
|
@@ -50,10 +51,18 @@ class AdminAuth {
|
|
|
50
51
|
await this.saveConfig(defaultConfig);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
SecurityUtils.logSecurityEvent(
|
|
54
|
+
SecurityUtils.logSecurityEvent(
|
|
55
|
+
'admin_auth_initialized',
|
|
56
|
+
'info',
|
|
57
|
+
{ message: 'Admin authentication system initialized' }
|
|
58
|
+
);
|
|
54
59
|
return true;
|
|
55
60
|
} catch (error) {
|
|
56
|
-
SecurityUtils.logSecurityEvent(
|
|
61
|
+
SecurityUtils.logSecurityEvent(
|
|
62
|
+
'admin_auth_init_error',
|
|
63
|
+
'error',
|
|
64
|
+
{ message: `Failed to initialize admin auth: ${error.message}` }
|
|
65
|
+
);
|
|
57
66
|
return false;
|
|
58
67
|
}
|
|
59
68
|
}
|
|
@@ -80,7 +89,11 @@ class AdminAuth {
|
|
|
80
89
|
const content = await fs.promises.readFile(this.configPath, 'utf8');
|
|
81
90
|
return SecurityUtils.safeParseJSON(content);
|
|
82
91
|
} catch (error) {
|
|
83
|
-
SecurityUtils.logSecurityEvent(
|
|
92
|
+
SecurityUtils.logSecurityEvent(
|
|
93
|
+
'admin_config_load_error',
|
|
94
|
+
'error',
|
|
95
|
+
{ message: `Failed to load admin config: ${error.message}` }
|
|
96
|
+
);
|
|
84
97
|
return null;
|
|
85
98
|
}
|
|
86
99
|
}
|
|
@@ -92,10 +105,18 @@ class AdminAuth {
|
|
|
92
105
|
try {
|
|
93
106
|
const content = JSON.stringify(config, null, 2);
|
|
94
107
|
await fs.promises.writeFile(this.configPath, content, { mode: 0o600 }); // Restrict permissions
|
|
95
|
-
SecurityUtils.logSecurityEvent(
|
|
108
|
+
SecurityUtils.logSecurityEvent(
|
|
109
|
+
'admin_config_saved',
|
|
110
|
+
'info',
|
|
111
|
+
{ message: 'Admin configuration saved' }
|
|
112
|
+
);
|
|
96
113
|
return true;
|
|
97
114
|
} catch (error) {
|
|
98
|
-
SecurityUtils.logSecurityEvent(
|
|
115
|
+
SecurityUtils.logSecurityEvent(
|
|
116
|
+
'admin_config_save_error',
|
|
117
|
+
'error',
|
|
118
|
+
{ message: `Failed to save admin config: ${error.message}` }
|
|
119
|
+
);
|
|
99
120
|
return false;
|
|
100
121
|
}
|
|
101
122
|
}
|
|
@@ -126,11 +147,19 @@ class AdminAuth {
|
|
|
126
147
|
if (success) {
|
|
127
148
|
// Reset failed attempts on successful PIN setup
|
|
128
149
|
this.failedAttempts.clear();
|
|
129
|
-
SecurityUtils.logSecurityEvent(
|
|
150
|
+
SecurityUtils.logSecurityEvent(
|
|
151
|
+
'admin_pin_setup',
|
|
152
|
+
'info',
|
|
153
|
+
{ message: 'Admin PIN configured successfully' }
|
|
154
|
+
);
|
|
130
155
|
}
|
|
131
156
|
return success;
|
|
132
157
|
} catch (error) {
|
|
133
|
-
SecurityUtils.logSecurityEvent(
|
|
158
|
+
SecurityUtils.logSecurityEvent(
|
|
159
|
+
'admin_pin_setup_error',
|
|
160
|
+
'error',
|
|
161
|
+
{ message: `Failed to setup PIN: ${error.message}` }
|
|
162
|
+
);
|
|
134
163
|
return false;
|
|
135
164
|
}
|
|
136
165
|
}
|
|
@@ -155,14 +184,22 @@ class AdminAuth {
|
|
|
155
184
|
// Check for lockout
|
|
156
185
|
const clientId = 'local'; // In a real app, this would be client IP or session ID
|
|
157
186
|
if (this.isLockedOut(clientId)) {
|
|
158
|
-
SecurityUtils.logSecurityEvent(
|
|
187
|
+
SecurityUtils.logSecurityEvent(
|
|
188
|
+
'admin_auth_lockout',
|
|
189
|
+
'warning',
|
|
190
|
+
{ message: 'Authentication attempt during lockout period' }
|
|
191
|
+
);
|
|
159
192
|
return false;
|
|
160
193
|
}
|
|
161
194
|
|
|
162
195
|
// Validate PIN format
|
|
163
|
-
if (!/^\d{4}$/.test(pin)) {
|
|
196
|
+
if (!/^\d{4,6}$/.test(pin)) {
|
|
164
197
|
this.recordFailedAttempt(clientId);
|
|
165
|
-
SecurityUtils.logSecurityEvent(
|
|
198
|
+
SecurityUtils.logSecurityEvent(
|
|
199
|
+
'admin_auth_invalid_format',
|
|
200
|
+
'warning',
|
|
201
|
+
{ message: 'Invalid PIN format attempted' }
|
|
202
|
+
);
|
|
166
203
|
return false;
|
|
167
204
|
}
|
|
168
205
|
|
|
@@ -172,15 +209,27 @@ class AdminAuth {
|
|
|
172
209
|
|
|
173
210
|
if (isValid) {
|
|
174
211
|
this.clearFailedAttempts(clientId);
|
|
175
|
-
SecurityUtils.logSecurityEvent(
|
|
212
|
+
SecurityUtils.logSecurityEvent(
|
|
213
|
+
'admin_auth_success',
|
|
214
|
+
'info',
|
|
215
|
+
{ message: 'Admin authentication successful' }
|
|
216
|
+
);
|
|
176
217
|
return true;
|
|
177
218
|
} else {
|
|
178
219
|
this.recordFailedAttempt(clientId);
|
|
179
|
-
SecurityUtils.logSecurityEvent(
|
|
220
|
+
SecurityUtils.logSecurityEvent(
|
|
221
|
+
'admin_auth_failure',
|
|
222
|
+
'warning',
|
|
223
|
+
{ message: 'Admin authentication failed' }
|
|
224
|
+
);
|
|
180
225
|
return false;
|
|
181
226
|
}
|
|
182
227
|
} catch (error) {
|
|
183
|
-
SecurityUtils.logSecurityEvent(
|
|
228
|
+
SecurityUtils.logSecurityEvent(
|
|
229
|
+
'admin_auth_error',
|
|
230
|
+
'error',
|
|
231
|
+
{ message: `Authentication error: ${error.message}` }
|
|
232
|
+
);
|
|
184
233
|
return false;
|
|
185
234
|
}
|
|
186
235
|
}
|
|
@@ -281,7 +330,11 @@ class AdminAuth {
|
|
|
281
330
|
this.currentSession = session;
|
|
282
331
|
this.sessionStartTime = new Date();
|
|
283
332
|
|
|
284
|
-
SecurityUtils.logSecurityEvent(
|
|
333
|
+
SecurityUtils.logSecurityEvent(
|
|
334
|
+
'session_created',
|
|
335
|
+
'info',
|
|
336
|
+
{ message: `Session ${sessionId} created` }
|
|
337
|
+
);
|
|
285
338
|
return sessionId;
|
|
286
339
|
}
|
|
287
340
|
|
|
@@ -309,7 +362,11 @@ class AdminAuth {
|
|
|
309
362
|
if (now > expires) {
|
|
310
363
|
this.activeSessions.delete(sessionId);
|
|
311
364
|
this.clearCurrentSession();
|
|
312
|
-
SecurityUtils.logSecurityEvent(
|
|
365
|
+
SecurityUtils.logSecurityEvent(
|
|
366
|
+
'session_expired',
|
|
367
|
+
'info',
|
|
368
|
+
{ message: `Session ${sessionId} expired` }
|
|
369
|
+
);
|
|
313
370
|
return false;
|
|
314
371
|
}
|
|
315
372
|
|
|
@@ -327,7 +384,11 @@ class AdminAuth {
|
|
|
327
384
|
clearCurrentSession() {
|
|
328
385
|
if (this.currentSession) {
|
|
329
386
|
this.activeSessions.delete(this.currentSession.id);
|
|
330
|
-
SecurityUtils.logSecurityEvent(
|
|
387
|
+
SecurityUtils.logSecurityEvent(
|
|
388
|
+
'session_cleared',
|
|
389
|
+
'info',
|
|
390
|
+
{ message: `Session ${this.currentSession.id} cleared` }
|
|
391
|
+
);
|
|
331
392
|
}
|
|
332
393
|
this.currentSession = null;
|
|
333
394
|
this.sessionStartTime = null;
|
|
@@ -376,13 +437,21 @@ class AdminAuth {
|
|
|
376
437
|
config.lastModified = new Date().toISOString();
|
|
377
438
|
const success = await this.saveConfig(config);
|
|
378
439
|
if (success) {
|
|
379
|
-
SecurityUtils.logSecurityEvent(
|
|
440
|
+
SecurityUtils.logSecurityEvent(
|
|
441
|
+
'admin_auth_disabled',
|
|
442
|
+
'info',
|
|
443
|
+
{ message: 'Admin authentication disabled' }
|
|
444
|
+
);
|
|
380
445
|
}
|
|
381
446
|
return success;
|
|
382
447
|
}
|
|
383
448
|
return true;
|
|
384
449
|
} catch (error) {
|
|
385
|
-
SecurityUtils.logSecurityEvent(
|
|
450
|
+
SecurityUtils.logSecurityEvent(
|
|
451
|
+
'admin_auth_disable_error',
|
|
452
|
+
'error',
|
|
453
|
+
{ message: `Failed to disable auth: ${error.message}` }
|
|
454
|
+
);
|
|
386
455
|
return false;
|
|
387
456
|
}
|
|
388
457
|
}
|
package/utils/admin-cli.js
CHANGED
|
@@ -84,7 +84,11 @@ class AdminCLI {
|
|
|
84
84
|
if (success) {
|
|
85
85
|
console.log(i18n.t('adminCli.pinProtectionEnabledSuccess'));
|
|
86
86
|
console.log(i18n.t('adminCli.pinRecoveryWarning'));
|
|
87
|
-
SecurityUtils.logSecurityEvent(
|
|
87
|
+
SecurityUtils.logSecurityEvent(
|
|
88
|
+
i18n.t('adminCli.adminPinSetupCli'),
|
|
89
|
+
'info',
|
|
90
|
+
{ message: 'Admin PIN setup completed via CLI' }
|
|
91
|
+
);
|
|
88
92
|
} else {
|
|
89
93
|
console.log(i18n.t('adminCli.setupPinProtectionFailed'));
|
|
90
94
|
}
|
|
@@ -140,7 +144,11 @@ class AdminCLI {
|
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
console.log(i18n.t('adminCli.authenticationFailedAccessDenied'));
|
|
143
|
-
SecurityUtils.logSecurityEvent(
|
|
147
|
+
SecurityUtils.logSecurityEvent(
|
|
148
|
+
i18n.t('adminCli.adminAuthFailedCli'),
|
|
149
|
+
'warning',
|
|
150
|
+
{ message: `Admin authentication failed after ${maxAttempts} attempts` }
|
|
151
|
+
);
|
|
144
152
|
this.closeReadline();
|
|
145
153
|
return false;
|
|
146
154
|
} catch (error) {
|
|
@@ -182,7 +190,11 @@ class AdminCLI {
|
|
|
182
190
|
|
|
183
191
|
if (success) {
|
|
184
192
|
console.log(i18n.t('adminCli.pinProtectionDisabledSuccess'));
|
|
185
|
-
SecurityUtils.logSecurityEvent(
|
|
193
|
+
SecurityUtils.logSecurityEvent(
|
|
194
|
+
i18n.t('adminCli.adminAuthDisabledCli'),
|
|
195
|
+
'info',
|
|
196
|
+
{ message: 'Admin PIN protection disabled via CLI' }
|
|
197
|
+
);
|
|
186
198
|
} else {
|
|
187
199
|
console.log(i18n.t('adminCli.disablePinProtectionFailed'));
|
|
188
200
|
}
|