@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.
Files changed (3) hide show
  1. package/README.md +87 -6
  2. package/dist/index.js +39 -32
  3. 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
- ## Security Considerations
397
+ ## CLI Tool
398
398
 
399
- 1. **Use TLS in production**: Always enable secure connections
400
- 2. **Strong passwords**: Use bcrypt hashes for stored passwords
401
- 3. **Network security**: Configure firewalls and limit access
402
- 4. **Regular updates**: Keep dependencies updated
403
- 5. **Monitor logs**: Regularly check for suspicious activity
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
- const nowTs = Date.now();
3477
- const ipRec = this.ipAttemptCache.get(remoteIP) || {
3478
- attempts: 0,
3479
- lockedUntil: 0,
3480
- expiresAt: nowTs + this._attemptCacheTTL
3481
- };
3482
- ipRec.attempts = (ipRec.attempts || 0) + 1;
3483
- ipRec.expiresAt = nowTs + this._attemptCacheTTL;
3484
- if (ipRec.attempts >= this.MAX_LOGIN_ATTEMPTS) {
3485
- ipRec.lockedUntil = nowTs + this.LOCK_DURATION_MS;
3486
- this.audit("ip.lockout", {
3487
- ip: remoteIP,
3488
- attempts: ipRec.attempts
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
- } catch (e) {}
3501
- break;
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
- const pwd = typeof u.password === "string" && u.password ? u.password : null;
4317
- if (uname && pwd) {
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.8",
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.8",
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.8",
45
- "@scriptdb/storage": "^1.0.8",
46
- "@scriptdb/system-modules": "^1.0.8",
47
- "@scriptdb/vm": "^1.0.8",
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",