@scriptdb/server 1.0.8 → 1.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/README.md +87 -6
- package/dist/index.js +39 -32
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -394,13 +394,94 @@ npm run typecheck
|
|
|
394
394
|
npm run lint
|
|
395
395
|
```
|
|
396
396
|
|
|
397
|
-
##
|
|
397
|
+
## CLI Tool
|
|
398
398
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
399
|
+
ScriptDB provides a CLI tool for easy server management:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
# Install CLI globally
|
|
403
|
+
npm install -g @scriptdb/cli
|
|
404
|
+
|
|
405
|
+
# Start server in foreground
|
|
406
|
+
scriptdb start
|
|
407
|
+
|
|
408
|
+
# Start server in background (daemon mode with PM2)
|
|
409
|
+
scriptdb start -d
|
|
410
|
+
|
|
411
|
+
# Check server status
|
|
412
|
+
scriptdb status
|
|
413
|
+
|
|
414
|
+
# View real-time logs
|
|
415
|
+
scriptdb logs
|
|
416
|
+
|
|
417
|
+
# Monitor performance
|
|
418
|
+
scriptdb monit
|
|
419
|
+
|
|
420
|
+
# Stop server
|
|
421
|
+
scriptdb stop
|
|
422
|
+
|
|
423
|
+
# Restart server
|
|
424
|
+
scriptdb restart -d
|
|
425
|
+
|
|
426
|
+
# Start interactive shell
|
|
427
|
+
scriptdb shell
|
|
428
|
+
|
|
429
|
+
# Install packages to ScriptDB
|
|
430
|
+
scriptdb add lodash
|
|
431
|
+
|
|
432
|
+
# Install packages locally
|
|
433
|
+
scriptdb add --local lodash
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### CLI Configuration
|
|
437
|
+
|
|
438
|
+
The CLI reads configuration from `~/.scriptdb/config.json`:
|
|
439
|
+
|
|
440
|
+
```json
|
|
441
|
+
{
|
|
442
|
+
"host": "localhost",
|
|
443
|
+
"port": 1234,
|
|
444
|
+
"users": [
|
|
445
|
+
{
|
|
446
|
+
"username": "admin",
|
|
447
|
+
"password": "your-password",
|
|
448
|
+
"hash": false
|
|
449
|
+
}
|
|
450
|
+
],
|
|
451
|
+
"folder": "databases",
|
|
452
|
+
"secure": false
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Process Management
|
|
457
|
+
|
|
458
|
+
The CLI uses PM2 for daemon mode, providing:
|
|
459
|
+
|
|
460
|
+
- Automatic restart on failure
|
|
461
|
+
- Log management
|
|
462
|
+
- Performance monitoring
|
|
463
|
+
- Cluster mode support
|
|
464
|
+
|
|
465
|
+
PM2 files are stored in `~/.scriptdb/`:
|
|
466
|
+
- `ecosystem.config.js` - PM2 configuration
|
|
467
|
+
- `pm2-*.log` - Log files
|
|
468
|
+
|
|
469
|
+
## Changelog
|
|
470
|
+
|
|
471
|
+
### 1.1.0 (2025-01-16)
|
|
472
|
+
|
|
473
|
+
**Added**
|
|
474
|
+
- Native `scriptdb logs` command to view real-time logs
|
|
475
|
+
- Native `scriptdb monit` command to monitor performance
|
|
476
|
+
- Native `scriptdb restart` command to restart the server
|
|
477
|
+
- Native `scriptdb stop` command to stop the server
|
|
478
|
+
- ESLint configuration for TypeScript linting
|
|
479
|
+
|
|
480
|
+
**Fixed**
|
|
481
|
+
- Fixed TypeScript type mismatch in users config normalization
|
|
482
|
+
- Fixed TypeScript "used before assigned" error for storage variable
|
|
483
|
+
- Fixed TypeScript module resolution errors
|
|
484
|
+
- Improved error handling and Windows compatibility
|
|
404
485
|
|
|
405
486
|
## License
|
|
406
487
|
|
package/dist/index.js
CHANGED
|
@@ -2912,6 +2912,7 @@ class Protocal {
|
|
|
2912
2912
|
IP_FAIL_WINDOW_MS;
|
|
2913
2913
|
MAX_LOGIN_ATTEMPTS;
|
|
2914
2914
|
LOCK_DURATION_MS;
|
|
2915
|
+
ENABLE_IP_LOCKOUT;
|
|
2915
2916
|
MAX_MESSAGE_BYTES;
|
|
2916
2917
|
MAX_MESSAGES_PER_CONNECTION;
|
|
2917
2918
|
CONNECTION_TIMEOUT_MS;
|
|
@@ -3025,9 +3026,10 @@ class Protocal {
|
|
|
3025
3026
|
});
|
|
3026
3027
|
this.loginAttemptCache = new Map;
|
|
3027
3028
|
this.ipAttemptCache = new Map;
|
|
3028
|
-
this.IP_FAIL_WINDOW_MS = options.ipFailWindowMs || 15 * 60 * 1000;
|
|
3029
|
-
this.MAX_LOGIN_ATTEMPTS = options.maxLoginAttempts || 5;
|
|
3030
|
-
this.LOCK_DURATION_MS = options.lockDurationMs || 15 * 60 * 1000;
|
|
3029
|
+
this.IP_FAIL_WINDOW_MS = options.ipFailWindowMs || fileConfig.ipFailWindowMs || 15 * 60 * 1000;
|
|
3030
|
+
this.MAX_LOGIN_ATTEMPTS = options.maxLoginAttempts || fileConfig.maxLoginAttempts || 5;
|
|
3031
|
+
this.LOCK_DURATION_MS = options.lockDurationMs || fileConfig.lockDurationMs || 15 * 60 * 1000;
|
|
3032
|
+
this.ENABLE_IP_LOCKOUT = options.enableIpLockout !== undefined ? options.enableIpLockout : fileConfig.enableIpLockout !== undefined ? fileConfig.enableIpLockout : true;
|
|
3031
3033
|
this.MAX_MESSAGE_BYTES = options.maxMessageBytes || 64 * 1024;
|
|
3032
3034
|
this.MAX_MESSAGES_PER_CONNECTION = options.maxMessagesPerConnection || 1000;
|
|
3033
3035
|
this.CONNECTION_TIMEOUT_MS = typeof options.connectionTimeoutMs === "number" ? options.connectionTimeoutMs : typeof fileConfig.connectionTimeoutMs === "number" ? fileConfig.connectionTimeoutMs : 0;
|
|
@@ -3473,32 +3475,34 @@ class Protocal {
|
|
|
3473
3475
|
err: e && e.message || String(e)
|
|
3474
3476
|
});
|
|
3475
3477
|
}
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
ipRec.
|
|
3486
|
-
|
|
3487
|
-
ip
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
}
|
|
3491
|
-
this.ipAttemptCache.set(remoteIP, ipRec);
|
|
3492
|
-
if (ipRec.lockedUntil && ipRec.lockedUntil > nowTs) {
|
|
3493
|
-
this.audit("ip.locked", { ip: remoteIP });
|
|
3494
|
-
try {
|
|
3495
|
-
sendWithBackpressure({
|
|
3496
|
-
command: "login",
|
|
3497
|
-
message: "LOCKED_IP",
|
|
3498
|
-
data: null
|
|
3478
|
+
if (this.ENABLE_IP_LOCKOUT) {
|
|
3479
|
+
const nowTs = Date.now();
|
|
3480
|
+
const ipRec = this.ipAttemptCache.get(remoteIP) || {
|
|
3481
|
+
attempts: 0,
|
|
3482
|
+
lockedUntil: 0,
|
|
3483
|
+
expiresAt: nowTs + this._attemptCacheTTL
|
|
3484
|
+
};
|
|
3485
|
+
ipRec.attempts = (ipRec.attempts || 0) + 1;
|
|
3486
|
+
ipRec.expiresAt = nowTs + this._attemptCacheTTL;
|
|
3487
|
+
if (ipRec.attempts >= this.MAX_LOGIN_ATTEMPTS) {
|
|
3488
|
+
ipRec.lockedUntil = nowTs + this.LOCK_DURATION_MS;
|
|
3489
|
+
this.audit("ip.lockout", {
|
|
3490
|
+
ip: remoteIP,
|
|
3491
|
+
attempts: ipRec.attempts
|
|
3499
3492
|
});
|
|
3500
|
-
}
|
|
3501
|
-
|
|
3493
|
+
}
|
|
3494
|
+
this.ipAttemptCache.set(remoteIP, ipRec);
|
|
3495
|
+
if (ipRec.lockedUntil && ipRec.lockedUntil > nowTs) {
|
|
3496
|
+
this.audit("ip.locked", { ip: remoteIP });
|
|
3497
|
+
try {
|
|
3498
|
+
sendWithBackpressure({
|
|
3499
|
+
command: "login",
|
|
3500
|
+
message: "LOCKED_IP",
|
|
3501
|
+
data: null
|
|
3502
|
+
});
|
|
3503
|
+
} catch (e) {}
|
|
3504
|
+
break;
|
|
3505
|
+
}
|
|
3502
3506
|
}
|
|
3503
3507
|
const now = Date.now();
|
|
3504
3508
|
const record = this.loginAttemptCache.get(username) || {
|
|
@@ -4313,9 +4317,8 @@ export const ${databaseName} = {};
|
|
|
4313
4317
|
if (this.users && Array.isArray(this.users) && this.users.length > 0) {
|
|
4314
4318
|
const u = this.users[0] || { username: "" };
|
|
4315
4319
|
const uname = u.username || null;
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
cred = encodeURIComponent(String(uname)) + ":" + encodeURIComponent(String(pwd)) + "@";
|
|
4320
|
+
if (uname && typeof u.password === "string" && u.password) {
|
|
4321
|
+
cred = encodeURIComponent(String(uname)) + ":" + "*****" + "@";
|
|
4319
4322
|
} else if (uname) {
|
|
4320
4323
|
cred = encodeURIComponent(String(uname)) + "@";
|
|
4321
4324
|
}
|
|
@@ -4356,7 +4359,7 @@ import { spawn } from "node:child_process";
|
|
|
4356
4359
|
import Storage from "@scriptdb/storage";
|
|
4357
4360
|
var pkgData = `{
|
|
4358
4361
|
"name": "scriptdb-workspace",
|
|
4359
|
-
"version": "1.0
|
|
4362
|
+
"version": "1.1.0",
|
|
4360
4363
|
"description": "ScriptDB workspace for custom scripts, services, and databases",
|
|
4361
4364
|
"private": true,
|
|
4362
4365
|
"devDependencies": {
|
|
@@ -4443,6 +4446,10 @@ var configDefault = {
|
|
|
4443
4446
|
GITHUB_URL: "",
|
|
4444
4447
|
GITHUB_TOKEN: "",
|
|
4445
4448
|
GITHUB_BRANCH: "main",
|
|
4449
|
+
enableIpLockout: true,
|
|
4450
|
+
ipFailWindowMs: 900000,
|
|
4451
|
+
maxLoginAttempts: 5,
|
|
4452
|
+
lockDurationMs: 900000,
|
|
4446
4453
|
users: [
|
|
4447
4454
|
{
|
|
4448
4455
|
username: "admin",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scriptdb/server",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "server module resolver for script database",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"typescript": "^5.0.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@scriptdb/client": "^1.0
|
|
45
|
-
"@scriptdb/storage": "^1.0
|
|
46
|
-
"@scriptdb/system-modules": "^1.0
|
|
47
|
-
"@scriptdb/vm": "^1.0
|
|
44
|
+
"@scriptdb/client": "^1.1.0",
|
|
45
|
+
"@scriptdb/storage": "^1.1.0",
|
|
46
|
+
"@scriptdb/system-modules": "^1.1.0",
|
|
47
|
+
"@scriptdb/vm": "^1.1.0",
|
|
48
48
|
"@types/ws": "^8.18.1",
|
|
49
49
|
"bcryptjs": "^3.0.3",
|
|
50
50
|
"bottleneck": "^2.19.5",
|