axiodb 11.9.16 → 12.10.18

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 (118) hide show
  1. package/README.md +140 -5
  2. package/lib/Helper/Converter.helper.d.ts +0 -25
  3. package/lib/Helper/Converter.helper.js +1 -26
  4. package/lib/Helper/Converter.helper.js.map +1 -1
  5. package/lib/Helper/Crypto.helper.d.ts +1 -44
  6. package/lib/Helper/Crypto.helper.js +1 -40
  7. package/lib/Helper/Crypto.helper.js.map +1 -1
  8. package/lib/Helper/DocumentLoader.helper.d.ts +3 -38
  9. package/lib/Helper/DocumentLoader.helper.js +4 -42
  10. package/lib/Helper/DocumentLoader.helper.js.map +1 -1
  11. package/lib/Helper/PathSanitizer.helper.js +6 -12
  12. package/lib/Helper/PathSanitizer.helper.js.map +1 -1
  13. package/lib/Helper/response.helper.d.ts +1 -42
  14. package/lib/Helper/response.helper.js +1 -43
  15. package/lib/Helper/response.helper.js.map +1 -1
  16. package/lib/Memory/memory.operation.d.ts +13 -93
  17. package/lib/Memory/memory.operation.js +20 -122
  18. package/lib/Memory/memory.operation.js.map +1 -1
  19. package/lib/Services/Indexation.operation.d.ts +3 -0
  20. package/lib/Services/Indexation.operation.js +25 -4
  21. package/lib/Services/Indexation.operation.js.map +1 -1
  22. package/lib/client/AggregationProxy.d.ts +1 -7
  23. package/lib/client/AggregationProxy.js +1 -7
  24. package/lib/client/AggregationProxy.js.map +1 -1
  25. package/lib/client/AxioDBCloud.client.d.ts +19 -16
  26. package/lib/client/AxioDBCloud.client.js +48 -31
  27. package/lib/client/AxioDBCloud.client.js.map +1 -1
  28. package/lib/client/CollectionProxy.d.ts +1 -37
  29. package/lib/client/CollectionProxy.js +1 -37
  30. package/lib/client/CollectionProxy.js.map +1 -1
  31. package/lib/client/DatabaseProxy.d.ts +1 -19
  32. package/lib/client/DatabaseProxy.js +1 -19
  33. package/lib/client/DatabaseProxy.js.map +1 -1
  34. package/lib/client/DeleteOperationProxy.d.ts +1 -10
  35. package/lib/client/DeleteOperationProxy.js +1 -10
  36. package/lib/client/DeleteOperationProxy.js.map +1 -1
  37. package/lib/client/PooledConnection.d.ts +7 -1
  38. package/lib/client/PooledConnection.js +27 -8
  39. package/lib/client/PooledConnection.js.map +1 -1
  40. package/lib/client/ReaderProxy.d.ts +1 -19
  41. package/lib/client/ReaderProxy.js +1 -19
  42. package/lib/client/ReaderProxy.js.map +1 -1
  43. package/lib/client/UpdateOperationProxy.d.ts +1 -10
  44. package/lib/client/UpdateOperationProxy.js +1 -10
  45. package/lib/client/UpdateOperationProxy.js.map +1 -1
  46. package/lib/client/types/client.types.d.ts +18 -10
  47. package/lib/client/types/client.types.js +0 -6
  48. package/lib/client/types/client.types.js.map +1 -1
  49. package/lib/config/DB.js +0 -3
  50. package/lib/config/DB.js.map +1 -1
  51. package/lib/config/Interfaces/Operation/Indexation.operation.interface.d.ts +6 -0
  52. package/lib/config/Keys/Keys.js +0 -1
  53. package/lib/config/Keys/Keys.js.map +1 -1
  54. package/lib/engine/Filesystem/FileManager.d.ts +4 -74
  55. package/lib/engine/Filesystem/FileManager.js +4 -76
  56. package/lib/engine/Filesystem/FileManager.js.map +1 -1
  57. package/lib/engine/Filesystem/FolderManager.d.ts +1 -31
  58. package/lib/engine/Filesystem/FolderManager.js +2 -47
  59. package/lib/engine/Filesystem/FolderManager.js.map +1 -1
  60. package/lib/engine/cli/worker_process.d.ts +1 -24
  61. package/lib/engine/cli/worker_process.js +1 -24
  62. package/lib/engine/cli/worker_process.js.map +1 -1
  63. package/lib/engine/node/WorkerForDataLoad.engine.js +3 -17
  64. package/lib/engine/node/WorkerForDataLoad.engine.js.map +1 -1
  65. package/lib/engine/node/WorkerForSearch.engine.js +2 -4
  66. package/lib/engine/node/WorkerForSearch.engine.js.map +1 -1
  67. package/lib/server/config/PortFreeChecker.d.ts +0 -26
  68. package/lib/server/config/PortFreeChecker.js +3 -29
  69. package/lib/server/config/PortFreeChecker.js.map +1 -1
  70. package/lib/server/config/keys.js +0 -2
  71. package/lib/server/config/keys.js.map +1 -1
  72. package/lib/server/config/server.js +13 -15
  73. package/lib/server/config/server.js.map +1 -1
  74. package/lib/server/controller/Collections/Collection.controller.d.ts +0 -48
  75. package/lib/server/controller/Collections/Collection.controller.js +2 -55
  76. package/lib/server/controller/Collections/Collection.controller.js.map +1 -1
  77. package/lib/server/controller/Database/Databse.controller.d.ts +2 -65
  78. package/lib/server/controller/Database/Databse.controller.js +3 -80
  79. package/lib/server/controller/Database/Databse.controller.js.map +1 -1
  80. package/lib/server/controller/Index/Index.controller.d.ts +3 -25
  81. package/lib/server/controller/Index/Index.controller.js +3 -25
  82. package/lib/server/controller/Index/Index.controller.js.map +1 -1
  83. package/lib/server/controller/Operation/CRUD.controller.d.ts +0 -167
  84. package/lib/server/controller/Operation/CRUD.controller.js +0 -195
  85. package/lib/server/controller/Operation/CRUD.controller.js.map +1 -1
  86. package/lib/server/controller/Stats.controller.d.ts +1 -22
  87. package/lib/server/controller/Stats.controller.js +2 -29
  88. package/lib/server/controller/Stats.controller.js.map +1 -1
  89. package/lib/server/helper/filesCounterInFolder.helper.d.ts +0 -15
  90. package/lib/server/helper/filesCounterInFolder.helper.js +0 -15
  91. package/lib/server/helper/filesCounterInFolder.helper.js.map +1 -1
  92. package/lib/server/helper/responseBuilder.helper.d.ts +0 -16
  93. package/lib/server/helper/responseBuilder.helper.js +0 -16
  94. package/lib/server/helper/responseBuilder.helper.js.map +1 -1
  95. package/lib/server/router/Router.d.ts +0 -6
  96. package/lib/server/router/Router.js +6 -22
  97. package/lib/server/router/Router.js.map +1 -1
  98. package/lib/server/router/Routers/Collection.routes.js +0 -4
  99. package/lib/server/router/Routers/Collection.routes.js.map +1 -1
  100. package/lib/server/router/Routers/DB.routes.js +1 -7
  101. package/lib/server/router/Routers/DB.routes.js.map +1 -1
  102. package/lib/server/router/Routers/Index.routes.js +0 -4
  103. package/lib/server/router/Routers/Index.routes.js.map +1 -1
  104. package/lib/server/router/Routers/Operation.routes.js +0 -9
  105. package/lib/server/router/Routers/Operation.routes.js.map +1 -1
  106. package/lib/tcp/config/keys.d.ts +15 -0
  107. package/lib/tcp/config/keys.js +20 -1
  108. package/lib/tcp/config/keys.js.map +1 -1
  109. package/lib/tcp/config/server.d.ts +6 -1
  110. package/lib/tcp/config/server.js +46 -15
  111. package/lib/tcp/config/server.js.map +1 -1
  112. package/lib/tcp/connection/ConnectionManager.d.ts +17 -1
  113. package/lib/tcp/connection/ConnectionManager.js +51 -3
  114. package/lib/tcp/connection/ConnectionManager.js.map +1 -1
  115. package/lib/tcp/connection/ConnectionRateLimiter.d.ts +31 -0
  116. package/lib/tcp/connection/ConnectionRateLimiter.js +83 -0
  117. package/lib/tcp/connection/ConnectionRateLimiter.js.map +1 -0
  118. package/package.json +2 -1
package/README.md CHANGED
@@ -29,6 +29,7 @@
29
29
  - [AxioDBCloud — Connecting Remotely](#-axiodbcloud--connecting-remotely)
30
30
  - [Simple: connect without authentication](#simple-connect-without-authentication)
31
31
  - [Advanced: TCP authentication](#advanced-tcp-authentication)
32
+ - [Advanced: TLS encryption](#advanced-tls-encryption)
32
33
  - [Troubleshooting](#-troubleshooting)
33
34
  - [Docker Deployment](#-docker-deployment)
34
35
  - [Simple: run the container](#simple-run-the-container)
@@ -212,7 +213,9 @@ await session.withTransaction(async (tx) => {
212
213
  - **🔁 Auto-Reconnect:** exponential backoff, up to 10 retry attempts
213
214
  - **💓 Heartbeat Monitoring:** `PING`/`PONG` every 30 seconds
214
215
  - **🆔 Request Correlation:** UUID-based request/response matching
215
- - **🧵 Connection Pooling:** client keeps a pool of `maxPoolSize` concurrent connections (default: 10, mirrors MongoDB's driver option) and distributes commands round-robin; server accepts 1,000+ concurrent connections total
216
+ - **🧵 Connection Pooling:** client keeps a pool of `maxPoolSize` concurrent connections (default: 10, mirrors MongoDB's driver option) and routes each command to the least-busy connected member (fewest in-flight requests); server accepts 1,000+ concurrent connections total, capped at 100 per remote IP (see the [file descriptor limit note](#connection-refused--too-many-open-files-errors-at-high-concurrency) below if you're running near that scale)
217
+ - **🛡️ Connection-Level DoS Protection:** per-IP concurrent connection cap (100) plus a separate per-IP connection-*attempt* rate limiter (300 attempts / 10s → 30s cooldown), so one client can't starve the server either by holding too many sockets open or by rapidly opening and dropping them
218
+ - **🔒 Optional TLS Encryption:** encrypt the wire protocol with your own cert (see [Advanced: TLS](#advanced-tls-encryption) below) — off by default, so existing plaintext deployments are unaffected unless you turn it on
216
219
  - **📐 TypeScript Support:** full type definitions included
217
220
 
218
221
  **Use cases:** microservices sharing one AxioDB instance, Electron apps connecting to a local or remote database, teams sharing a development database, container/cloud deployments (AWS, Azure, GCP, DigitalOcean).
@@ -280,7 +283,56 @@ await client.login('admin', 'admin');
280
283
  - **Accounts that still need their forced password change are rejected outright (`403`)**, not allowed through with a warning — there's no TCP command to change a password today, so log into the GUI (`http://localhost:27018`) to complete it first, or authenticate with an account that already has.
281
284
  - If a Super Admin resets a user's password, changes their role, or deletes them via the GUI while that user has an open TCP connection, the TCP connection is immediately forced to re-authenticate on its next command.
282
285
 
283
- **Known limitations:** the TCP protocol itself is unencrypted (no TLS) — deploy behind a private network, VPN, or your own TLS termination if connecting over an untrusted network. There's currently no TCP command to change a password; that must go through the GUI.
286
+ **Known limitations:** there's currently no TCP command to change a password; that must go through the GUI.
287
+
288
+ ### Advanced: TLS encryption
289
+
290
+ By default, the TCP protocol is **plaintext** — anyone who can capture the network traffic between client and server (e.g. Wireshark on a shared network) can read your data and, if `TCPAuth` is on, your password. TLS fixes this. It's **off by default** — nothing below is required, and existing plaintext deployments keep working exactly as before unless you turn it on.
291
+
292
+ **You must provide your own certificate + key.** AxioDB never generates one for you — that's a security decision only you can make (a real cert from a CA, or a self-signed one for local/private use).
293
+
294
+ **Step 1 — get a cert + key.** For local/dev/private use, generate a self-signed one (one-time, takes a second):
295
+ ```bash
296
+ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
297
+ ```
298
+ This creates two files, `cert.pem` and `key.pem`, in your current folder. For a real production deployment reachable from the internet, use a cert from a real CA (Let's Encrypt, your org's CA, your cloud provider's managed cert) instead — the rest of the setup below is identical either way.
299
+
300
+ **Step 2 — point the server at them:**
301
+ ```javascript
302
+ const { AxioDB } = require('axiodb');
303
+ const db = new AxioDB({
304
+ TCP: true,
305
+ TLS: true,
306
+ TLSCertPath: './cert.pem', // path to the file from step 1
307
+ TLSKeyPath: './key.pem',
308
+ });
309
+ ```
310
+ If `TLS: true` but either path is missing or unreadable, AxioDB throws immediately at startup — it never silently falls back to plaintext.
311
+
312
+ **Step 3 — point the client at the same cert** (only needed because it's self-signed; a real CA-issued cert wouldn't need this step, the same way your browser trusts `https://` sites without extra setup):
313
+ ```javascript
314
+ const { AxioDBCloud } = require('axiodb');
315
+ const client = new AxioDBCloud("axiodb://localhost:27019", {
316
+ tls: true,
317
+ tlsCAPath: './cert.pem', // same cert.pem from step 1 - proves this server is the real one
318
+ });
319
+ await client.connect();
320
+ ```
321
+ Without `tlsCAPath`, the client refuses to connect to a self-signed server by default (`tlsRejectUnauthorized` defaults to `true`) — this is intentional, it's the same protection that stops your browser from silently trusting a fake `https://` site. Only set `tlsRejectUnauthorized: false` for local/dev testing, never in production, since it turns that protection off entirely.
322
+
323
+ **Running this in Docker?** The cert/key files need to get *into* the container. The simplest way to think about it: your cert files live on your real machine; a Docker **bind mount** (`-v`) makes a folder from your machine visible inside the container at whatever path you choose, and you point `AXIODB_TLS_CERT_PATH`/`AXIODB_TLS_KEY_PATH` at *that in-container path*, not your real machine's path:
324
+ ```bash
325
+ # cert.pem and key.pem are really at /home/you/mycerts/ on your machine.
326
+ # "/certs" below is just a name we're choosing for where they'll appear inside the container.
327
+ docker run -d --name axiodb-server \
328
+ -p 27018:27018 -p 27019:27019 \
329
+ -v /home/you/mycerts:/certs:ro \
330
+ -e AXIODB_TLS=true \
331
+ -e AXIODB_TLS_CERT_PATH=/certs/cert.pem \
332
+ -e AXIODB_TLS_KEY_PATH=/certs/key.pem \
333
+ theankansaha/axiodb
334
+ ```
335
+ The rule: the `-e AXIODB_TLS_CERT_PATH=...` value must always match the *right-hand side* of the `-v` mount (`/certs/...`), never the real path on your machine (`/home/you/mycerts/...`) — the container can't see your machine's filesystem directly, only whatever you've explicitly mounted into it.
284
336
 
285
337
  👉 **[Full AxioDBCloud Documentation](https://axiodb.in/cloud)** — setup guides, API reference, Docker examples
286
338
 
@@ -316,6 +368,27 @@ Your credentials are correct, but that account is still flagged for a forced pas
316
368
 
317
369
  Five failed logins from your IP within 15 minutes trigger a 15-minute lockout, shared between TCP and the GUI. Double check the credentials you're sending, wait out the cooldown, or fix the underlying typo/config issue causing repeated failures — there's no way to clear the lockout early.
318
370
 
371
+ ### `429` — "Too many concurrent connections from this IP address"
372
+
373
+ Unrelated to the login lockout above — this fires at connection time, before any `AUTHENTICATE`, once a single remote IP has 100 concurrent open TCP sockets to the server (`MAX_CONNECTIONS_PER_IP`), regardless of whether any of those connections are authenticated. This caps how much of the server's total 1,000-connection budget one IP can claim, so one client can't starve every other client. It's per-*connection*, not per-*request* — a single `AxioDBCloud` client at the default `maxPoolSize: 10` is nowhere near this limit; you'd only hit it by running many separate client processes behind the same IP/NAT gateway, or a runaway reconnect loop leaking sockets. If you legitimately need more than 100 concurrent connections from one IP, that's a server-side constant (`MAX_CONNECTIONS_PER_IP` in `source/tcp/config/keys.ts`) — there's no runtime option to raise it yet.
374
+
375
+ If you do set a `maxPoolSize` that pushes past this cap (or any other subset of the pool fails for another reason, e.g. a network blip), `connect()` doesn't throw as long as at least one pool member connected — it resolves with a smaller-than-requested pool and emits a `poolDegraded` event so you know about it instead of silently running under capacity:
376
+
377
+ ```javascript
378
+ client.on('poolDegraded', ({ requested, connected, failed, errors }) => {
379
+ console.warn(`Pool came up smaller than requested: ${connected}/${requested} connected, ${failed} failed`);
380
+ console.warn(errors[0].message); // e.g. "Too many concurrent connections from this IP address"
381
+ });
382
+
383
+ await client.connect(); // resolves even if some pool members were rejected
384
+ ```
385
+
386
+ (The very first connection in the pool is the exception — if *that* one fails, `connect()` rejects entirely, since it's the signal that the server is reachable and credentials are valid at all.)
387
+
388
+ ### `429` — "Too many connection attempts from this IP address. Try again later."
389
+
390
+ Different from both `429`s above, and checked first: this guards against rapid connect-then-drop *churn*, which the concurrent-connection cap (`MAX_CONNECTIONS_PER_IP`) doesn't catch on its own — an attacker who never holds more than a few sockets open at once could still hammer the server with a high rate of connection attempts, each costing a TCP handshake and an accept/reject cycle, and stay under that cap the whole time. This is tracked separately, per IP, as a sliding window: once an IP crosses 300 connection attempts (successful or rejected, it doesn't matter which) within a trailing 10-second window, every new connection from that IP is rejected outright for the next 30 seconds. A normal `AxioDBCloud` client, even reconnecting a full `maxPoolSize: 10` pool repeatedly, is nowhere near this threshold — you'd only hit it via a genuine connection flood or a reconnect loop gone very wrong (e.g. retrying without backoff). There's no runtime option to raise these thresholds yet; they're constants in `source/tcp/config/keys.ts` (`CONNECTION_RATE_LIMIT_*`).
391
+
319
392
  ### `403` — "This is a reserved system database"
320
393
 
321
394
  You (or a client) tried to read/write a database literally named `config` — that name is reserved for AxioDB's own RBAC storage (`users`/`roles`/`permissions`) and is blocked on both the GUI and TCP, authenticated or not. Use a different database name.
@@ -330,6 +403,37 @@ You (or a client) tried to read/write a database literally named `config` — th
330
403
 
331
404
  See the [Docker Deployment](#-docker-deployment) section below, and `Docker/README.md` in the repository for a fuller Docker-specific troubleshooting guide (`docker logs`, port-conflict remapping, volume-mounting checklist).
332
405
 
406
+ ### Connection refused / "Too many open files" errors at high concurrency
407
+
408
+ Each `AxioDBCloud` client opens `maxPoolSize` TCP sockets (default: 10), and the server holds one socket per connected client — both count against the OS's open-file-descriptor limit. Most Linux distros default `ulimit -n` to 1024 per process, which is enough for only ~100 clients at the default pool size before the server starts refusing new connections with `EMFILE`/`ENFILE`.
409
+
410
+ If you're deploying towards the 1,000+ concurrent connections the server supports, raise the limit before starting the process:
411
+
412
+ ```bash
413
+ ulimit -n 65536 # current shell / process
414
+ node lib/config/DB.js
415
+ ```
416
+
417
+ In Docker, set it on the container instead of the host shell:
418
+
419
+ ```bash
420
+ docker run --ulimit nofile=65536:65536 -p 27018:27018 -p 27019:27019 theankansaha/axiodb
421
+ ```
422
+
423
+ or, in Compose:
424
+
425
+ ```yaml
426
+ services:
427
+ axiodb:
428
+ image: theankansaha/axiodb
429
+ ulimits:
430
+ nofile:
431
+ soft: 65536
432
+ hard: 65536
433
+ ```
434
+
435
+ On the client side, prefer a smaller `maxPoolSize` per instance rather than raising it — the least-busy routing (see [Connection Pooling](#-axiodbcloud--connecting-remotely) above) already avoids the head-of-line blocking a bigger pool would otherwise compensate for.
436
+
333
437
  ---
334
438
 
335
439
  ## 🐳 Docker Deployment
@@ -362,12 +466,15 @@ Every option below has a default matching the image's previous fixed behavior
362
466
  | `AXIODB_GUI` | `true` | Enable the HTTP Control Server / web GUI on port 27018 |
363
467
  | `AXIODB_TCP` | `true` | Enable the AxioDBCloud TCP server on port 27019 |
364
468
  | `AXIODB_TCP_AUTH` | `true` | Require username/password authentication on TCP connections (same RBAC accounts as the GUI) |
469
+ | `AXIODB_TLS` | `false` | Encrypt TCP connections with TLS instead of plaintext (see [Advanced: TLS encryption](#advanced-tls-encryption)) |
470
+ | `AXIODB_TLS_CERT_PATH` | *(none)* | Path **inside the container** to a PEM cert file - required when `AXIODB_TLS=true`. Mount the real file in with `-v` first (see the TLS section above) |
471
+ | `AXIODB_TLS_KEY_PATH` | *(none)* | Path **inside the container** to the matching PEM private key - required when `AXIODB_TLS=true` |
365
472
  | `AXIODB_ROOT_NAME` | `AxioDB` | Name of the root database folder created under the data volume |
366
473
  | `AXIODB_CUSTOM_PATH` | *(container's working directory)* | Custom path for database storage inside the container |
367
474
 
368
475
  > Ports themselves (27018/27019) aren't configurable via environment variable — remap them at the Docker layer with `-p <host-port>:27018` / `-p <host-port>:27019`.
369
476
 
370
- **Disabling TCP authentication** (only on a trusted private network — the wire is unencrypted; see [Known limitations](#advanced-tcp-authentication)):
477
+ **Disabling TCP authentication** (only on a trusted private network — the wire is plaintext unless you also enable `AXIODB_TLS`; see [Advanced: TLS encryption](#advanced-tls-encryption)):
371
478
  ```bash
372
479
  docker run -d \
373
480
  --name axiodb-server \
@@ -402,6 +509,34 @@ volumes:
402
509
  axiodb-data:
403
510
  ```
404
511
 
512
+ **The same, with TLS enabled** — note the two different kinds of entry under `volumes:`: `./mycerts:/certs:ro` is *your real folder* on the machine running Compose (because it contains a `/`), mounted read-only at `/certs` inside the container; `axiodb-data:/app` is a Docker-managed named volume (no `/`, just a label) for the actual database files:
513
+ ```yaml
514
+ version: "3.8"
515
+
516
+ services:
517
+ axiodb:
518
+ image: theankansaha/axiodb
519
+ container_name: axiodb-server
520
+ ports:
521
+ - "27018:27018"
522
+ - "27019:27019"
523
+ environment:
524
+ - AXIODB_GUI=true
525
+ - AXIODB_TCP=true
526
+ - AXIODB_TCP_AUTH=true
527
+ - AXIODB_TLS=true
528
+ - AXIODB_TLS_CERT_PATH=/certs/cert.pem
529
+ - AXIODB_TLS_KEY_PATH=/certs/key.pem
530
+ - AXIODB_ROOT_NAME=AxioDB
531
+ volumes:
532
+ - ./mycerts:/certs:ro # your real cert.pem/key.pem folder -> /certs in the container
533
+ - axiodb-data:/app # Docker-managed volume for database files
534
+ restart: unless-stopped
535
+
536
+ volumes:
537
+ axiodb-data:
538
+ ```
539
+
405
540
  **Building the image from source, and a fuller Docker troubleshooting guide** (container won't start, port-in-use, data-persistence checks) live in [`Docker/README.md`](Docker/README.md) — the canonical Docker doc, not duplicated here in full.
406
541
 
407
542
  ---
@@ -445,7 +580,7 @@ A Super Admin can create additional roles from the predefined permission catalog
445
580
 
446
581
  **Index management:** the Control Server also exposes `GET /api/index/list`, `POST /api/index/create`, and `DELETE /api/index/delete`, gated by the same `index:view` / `index:create` / `index:delete` permissions (View role gets view-only, Admin and Super Admin get all three).
447
582
 
448
- > **Security note:** RBAC protects the Control Server's HTTP API and TCP server; both are still intended for trusted local/network access, not public internet exposure. See [Troubleshooting](#-troubleshooting) for the TLS caveat on TCP.
583
+ > **Security note:** RBAC protects the Control Server's HTTP API and TCP server, but the HTTP GUI itself has no TLS support - keep it on a trusted local/private network, not public internet exposure. The TCP server *can* be encrypted (see [Advanced: TLS encryption](#advanced-tls-encryption)), which is recommended if it's reachable over any untrusted network.
449
584
 
450
585
  ---
451
586
 
@@ -764,7 +899,7 @@ Yes. Full type definitions are included — no separate `@types` package needed.
764
899
  No. AxioDB requires Node.js (v20+) and the filesystem — server-side and desktop only.
765
900
 
766
901
  **Q: What is AxioDBCloud?**
767
- TCP-based remote access for AxioDB. Deploy AxioDB in Docker, connect from multiple clients with the exact same API. Supports 1,000+ concurrent connections with auto-reconnect. Optional username/password authentication (`TCPAuth: true`) reuses the same RBAC accounts as the GUI — see [AxioDBCloud](#-axiodbcloud--connecting-remotely) above.
902
+ TCP-based remote access for AxioDB. Deploy AxioDB in Docker, connect from multiple clients with the exact same API. Supports 1,000+ concurrent connections with auto-reconnect. Optional username/password authentication (`TCPAuth: true`) reuses the same RBAC accounts as the GUI, and optional TLS encryption (`TLS: true`) protects the wire protocol on untrusted networks — see [AxioDBCloud](#-axiodbcloud--connecting-remotely) above.
768
903
 
769
904
  ---
770
905
 
@@ -1,34 +1,9 @@
1
1
  export default class Converter {
2
2
  static ToObject(): string;
3
3
  constructor();
4
- /**
5
- * Converts a string to a boolean.
6
- * @param value The string to convert.
7
- * @returns The boolean value.
8
- */
9
4
  ToBoolean(value: string): boolean;
10
- /**
11
- * Converts a string to a number.
12
- * @param value The string to convert.
13
- * @returns The number value.
14
- */
15
5
  ToNumber(value: string): number;
16
- /**
17
- * Converts a string to a JSON object.
18
- * @param value The string to convert.
19
- * @returns The JSON object.
20
- */
21
6
  ToObject(value: string): any;
22
- /**
23
- * Converts a JSON object to a string.
24
- * @param value The JSON object to convert.
25
- * @returns The string.
26
- */
27
7
  ToString(value: object): string;
28
- /**
29
- * Converts a string to a string array.
30
- * @param value The string to convert.
31
- * @returns The string array.
32
- */
33
8
  ToStringArray(value: string): string[];
34
9
  }
@@ -5,44 +5,19 @@ class Converter {
5
5
  static ToObject() {
6
6
  throw new Error("Method not implemented.");
7
7
  }
8
- constructor() { } // Empty constructor
9
- /**
10
- * Converts a string to a boolean.
11
- * @param value The string to convert.
12
- * @returns The boolean value.
13
- */
8
+ constructor() { }
14
9
  ToBoolean(value) {
15
10
  return value === "true";
16
11
  }
17
- /**
18
- * Converts a string to a number.
19
- * @param value The string to convert.
20
- * @returns The number value.
21
- */
22
12
  ToNumber(value) {
23
13
  return parseInt(value);
24
14
  }
25
- /**
26
- * Converts a string to a JSON object.
27
- * @param value The string to convert.
28
- * @returns The JSON object.
29
- */
30
15
  ToObject(value) {
31
16
  return JSON.parse(value);
32
17
  }
33
- /**
34
- * Converts a JSON object to a string.
35
- * @param value The JSON object to convert.
36
- * @returns The string.
37
- */
38
18
  ToString(value) {
39
19
  return JSON.stringify(value);
40
20
  }
41
- /**
42
- * Converts a string to a string array.
43
- * @param value The string to convert.
44
- * @returns The string array.
45
- */
46
21
  ToStringArray(value) {
47
22
  return value.split(",");
48
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Converter.helper.js","sourceRoot":"","sources":["../../source/Helper/Converter.helper.ts"],"names":[],"mappings":";;AAAA,uDAAuD;AACvD;IACE,MAAM,CAAC,QAAQ;QACb,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,gBAAe,CAAC,CAAC,oBAAoB;IAErC;;;;OAIG;IACI,SAAS,CAAC,KAAa;QAC5B,OAAO,KAAK,KAAK,MAAM,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IAEI,QAAQ,CAAC,KAAa;QAC3B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IAEI,aAAa,CAAC,KAAa;QAChC,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF"}
1
+ {"version":3,"file":"Converter.helper.js","sourceRoot":"","sources":["../../source/Helper/Converter.helper.ts"],"names":[],"mappings":";;AAAA,uDAAuD;AACvD;IACE,MAAM,CAAC,QAAQ;QACb,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,gBAAe,CAAC;IAET,SAAS,CAAC,KAAa;QAC5B,OAAO,KAAK,KAAK,MAAM,CAAC;IAC1B,CAAC;IAEM,QAAQ,CAAC,KAAa;QAC3B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAEM,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAEM,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAEM,aAAa,CAAC,KAAa;QAChC,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -1,57 +1,14 @@
1
1
  import { SuccessInterface } from "../config/Interfaces/Helper/response.helper.interface";
2
- /**
3
- * Helper class for cryptographic operations such as encryption and decryption.
4
- */
5
2
  export declare class CryptoHelper {
6
- /**
7
- * The encryption key used for cryptographic operations.
8
- */
9
3
  private encryptionKey;
10
- /**
11
- * Instance of ResponseHelper to handle responses.
12
- */
13
4
  private readonly responseHelper;
14
- /**
15
- * Instance of Cryptography class for performing cryptographic operations.
16
- */
17
5
  private readonly Cryptography;
18
- /**
19
- * Instance of Converter class for converting data formats.
20
- */
21
6
  private readonly Converter;
22
- /**
23
- * Constructor to initialize the CryptoHelper class.
24
- * @param encryptionKey - Optional encryption key. If not provided, a default key based on hostname and platform will be used.
25
- */
7
+ /** If no encryptionKey is given, falls back to a default key derived from hostname + platform. */
26
8
  constructor(encryptionKey?: string);
27
- /**
28
- * Sets a new encryption key.
29
- * @param encryptionKey - The new encryption key to be set.
30
- * @returns A promise that resolves to a success response.
31
- */
32
9
  setEncryptionKey(encryptionKey: string): Promise<SuccessInterface>;
33
- /**
34
- * Encrypts data asynchronously.
35
- * @param data - The data to be encrypted.
36
- * @returns A promise that resolves to the encrypted data as a string.
37
- */
38
10
  encrypt(data: string): Promise<string>;
39
- /**
40
- * Decrypts data asynchronously.
41
- * @param data - The data to be decrypted.
42
- * @returns A promise that resolves to the decrypted data as an object.
43
- */
44
11
  decrypt(data: string): Promise<any>;
45
- /**
46
- * Encrypts data synchronously.
47
- * @param data - The data to be encrypted.
48
- * @returns The encrypted data as a string.
49
- */
50
12
  encryptSync(data: string): string;
51
- /**
52
- * Decrypts data synchronously.
53
- * @param data - The data to be decrypted.
54
- * @returns The decrypted data as an object.
55
- */
56
13
  decryptSync(data: string): object;
57
14
  }
@@ -14,78 +14,39 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.CryptoHelper = void 0;
16
16
  /* eslint-disable @typescript-eslint/no-explicit-any */
17
- // All Imports
18
17
  const node_os_1 = require("node:os");
19
18
  const response_helper_1 = __importDefault(require("./response.helper"));
20
19
  const CryptoGraphy_helper_1 = __importDefault(require("./CryptoGraphy.helper"));
21
20
  const Converter_helper_1 = __importDefault(require("./Converter.helper"));
22
- /**
23
- * Helper class for cryptographic operations such as encryption and decryption.
24
- */
25
21
  class CryptoHelper {
26
- /**
27
- * Constructor to initialize the CryptoHelper class.
28
- * @param encryptionKey - Optional encryption key. If not provided, a default key based on hostname and platform will be used.
29
- */
22
+ /** If no encryptionKey is given, falls back to a default key derived from hostname + platform. */
30
23
  constructor(encryptionKey) {
31
- /**
32
- * Instance of ResponseHelper to handle responses.
33
- */
34
24
  this.responseHelper = new response_helper_1.default();
35
- /**
36
- * Instance of Converter class for converting data formats.
37
- */
38
25
  this.Converter = new Converter_helper_1.default();
39
26
  this.encryptionKey = encryptionKey || `${(0, node_os_1.hostname)()}-${(0, node_os_1.platform)()}`;
40
27
  this.responseHelper = new response_helper_1.default();
41
28
  this.Cryptography = new CryptoGraphy_helper_1.default(this.encryptionKey);
42
29
  this.Converter = new Converter_helper_1.default();
43
30
  }
44
- // methods
45
- /**
46
- * Sets a new encryption key.
47
- * @param encryptionKey - The new encryption key to be set.
48
- * @returns A promise that resolves to a success response.
49
- */
50
31
  setEncryptionKey(encryptionKey) {
51
32
  return __awaiter(this, void 0, void 0, function* () {
52
33
  this.encryptionKey = encryptionKey;
53
34
  return this.responseHelper.Success("Encryption key has been set successfully");
54
35
  });
55
36
  }
56
- /**
57
- * Encrypts data asynchronously.
58
- * @param data - The data to be encrypted.
59
- * @returns A promise that resolves to the encrypted data as a string.
60
- */
61
37
  encrypt(data) {
62
38
  return __awaiter(this, void 0, void 0, function* () {
63
39
  return yield this.Cryptography.Encrypt(data);
64
40
  });
65
41
  }
66
- /**
67
- * Decrypts data asynchronously.
68
- * @param data - The data to be decrypted.
69
- * @returns A promise that resolves to the decrypted data as an object.
70
- */
71
42
  decrypt(data) {
72
43
  return __awaiter(this, void 0, void 0, function* () {
73
44
  return this.Converter.ToObject(yield this.Cryptography.Decrypt(data));
74
45
  });
75
46
  }
76
- /**
77
- * Encrypts data synchronously.
78
- * @param data - The data to be encrypted.
79
- * @returns The encrypted data as a string.
80
- */
81
47
  encryptSync(data) {
82
48
  return this.Cryptography.EncryptSync(data);
83
49
  }
84
- /**
85
- * Decrypts data synchronously.
86
- * @param data - The data to be decrypted.
87
- * @returns The decrypted data as an object.
88
- */
89
50
  decryptSync(data) {
90
51
  return this.Converter.ToObject(this.Cryptography.DecryptSync(data));
91
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Crypto.helper.js","sourceRoot":"","sources":["../../source/Helper/Crypto.helper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uDAAuD;AACvD,cAAc;AACd,qCAA6C;AAC7C,wEAA+C;AAE/C,gFAAiD;AACjD,0EAA2C;AAE3C;;GAEG;AACH;IAsBE;;;OAGG;IACH,YAAY,aAAsB;QAnBlC;;WAEG;QACc,mBAAc,GAAmB,IAAI,yBAAc,EAAE,CAAC;QAOvE;;WAEG;QACc,cAAS,GAAG,IAAI,0BAAS,EAAE,CAAC;QAO3C,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,GAAG,IAAA,kBAAQ,GAAE,IAAI,IAAA,kBAAQ,GAAE,EAAE,CAAC;QACpE,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAc,EAAE,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,6BAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,IAAI,0BAAS,EAAE,CAAC;IACnC,CAAC;IAED,UAAU;IACV;;;;OAIG;IACU,gBAAgB,CAC3B,aAAqB;;YAErB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAChC,0CAA0C,CAC3C,CAAC;QACJ,CAAC;KAAA;IAED;;;;OAIG;IACU,OAAO,CAAC,IAAY;;YAC/B,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;KAAA;IAED;;;;OAIG;IACU,OAAO,CAAC,IAAY;;YAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACxE,CAAC;KAAA;IAED;;;;OAIG;IACI,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,CAAC;CACF"}
1
+ {"version":3,"file":"Crypto.helper.js","sourceRoot":"","sources":["../../source/Helper/Crypto.helper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uDAAuD;AACvD,qCAA6C;AAC7C,wEAA+C;AAE/C,gFAAiD;AACjD,0EAA2C;AAE3C;IAME,kGAAkG;IAClG,YAAY,aAAsB;QALjB,mBAAc,GAAmB,IAAI,yBAAc,EAAE,CAAC;QAEtD,cAAS,GAAG,IAAI,0BAAS,EAAE,CAAC;QAI3C,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,GAAG,IAAA,kBAAQ,GAAE,IAAI,IAAA,kBAAQ,GAAE,EAAE,CAAC;QACpE,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAc,EAAE,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,6BAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,IAAI,0BAAS,EAAE,CAAC;IACnC,CAAC;IAEY,gBAAgB,CAC3B,aAAqB;;YAErB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAChC,0CAA0C,CAC3C,CAAC;QACJ,CAAC;KAAA;IAEY,OAAO,CAAC,IAAY;;YAC/B,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;KAAA;IAEY,OAAO,CAAC,IAAY;;YAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACxE,CAAC;KAAA;IAEM,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAEM,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,CAAC;CACF"}
@@ -1,45 +1,10 @@
1
1
  import { SuccessInterface, ErrorInterface } from '../config/Interfaces/Helper/response.helper.interface';
2
2
  /**
3
- * DocumentLoader - Shared utility for loading documents from collection directories
4
- *
5
- * Provides a centralized method for loading document files using worker threads,
6
- * replacing duplicated code in Reader, Update, Delete, and Aggregation operations.
7
- *
8
- * @class DocumentLoader
3
+ * Centralizes document-loading logic that used to be duplicated across the Reader,
4
+ * Update, Delete, and Aggregation operations - handles both a direct file list and
5
+ * full directory scanning (filtered to `.axiodb` files), loaded via worker threads.
9
6
  */
10
7
  export default class DocumentLoader {
11
8
  private static readonly ResponseHelper;
12
- /**
13
- * Loads all documents from a collection directory using worker threads
14
- *
15
- * This method consolidates the LoadAllBufferRawData logic that was previously
16
- * duplicated across multiple CRUD operations. It handles both direct file
17
- * specification and directory scanning with .axiodb file filtering.
18
- *
19
- * @param collectionPath - Full path to collection directory
20
- * @param encryptionKey - Optional encryption key for encrypted documents
21
- * @param isEncrypted - Whether documents are encrypted (default: false)
22
- * @param documentFiles - Optional specific file names to load
23
- * @param includeFileName - Whether to include fileName in result (default: false)
24
- * @returns Success with document array or Error
25
- *
26
- * @example
27
- * // Load all documents from a collection
28
- * const result = await DocumentLoader.loadDocuments(
29
- * '/path/to/collection',
30
- * undefined,
31
- * false
32
- * );
33
- *
34
- * @example
35
- * // Load specific documents with filenames included
36
- * const result = await DocumentLoader.loadDocuments(
37
- * '/path/to/collection',
38
- * 'encryption-key',
39
- * true,
40
- * ['doc1.axiodb', 'doc2.axiodb'],
41
- * true
42
- * );
43
- */
44
9
  static loadDocuments(collectionPath: string, encryptionKey?: string, isEncrypted?: boolean, documentFiles?: string[], includeFileName?: boolean): Promise<SuccessInterface | ErrorInterface>;
45
10
  }
@@ -16,59 +16,21 @@ const FolderManager_1 = __importDefault(require("../engine/Filesystem/FolderMana
16
16
  const BufferLoaderWithWorker_utils_1 = __importDefault(require("../utility/BufferLoaderWithWorker.utils"));
17
17
  const response_helper_1 = __importDefault(require("./response.helper"));
18
18
  /**
19
- * DocumentLoader - Shared utility for loading documents from collection directories
20
- *
21
- * Provides a centralized method for loading document files using worker threads,
22
- * replacing duplicated code in Reader, Update, Delete, and Aggregation operations.
23
- *
24
- * @class DocumentLoader
19
+ * Centralizes document-loading logic that used to be duplicated across the Reader,
20
+ * Update, Delete, and Aggregation operations - handles both a direct file list and
21
+ * full directory scanning (filtered to `.axiodb` files), loaded via worker threads.
25
22
  */
26
23
  class DocumentLoader {
27
- /**
28
- * Loads all documents from a collection directory using worker threads
29
- *
30
- * This method consolidates the LoadAllBufferRawData logic that was previously
31
- * duplicated across multiple CRUD operations. It handles both direct file
32
- * specification and directory scanning with .axiodb file filtering.
33
- *
34
- * @param collectionPath - Full path to collection directory
35
- * @param encryptionKey - Optional encryption key for encrypted documents
36
- * @param isEncrypted - Whether documents are encrypted (default: false)
37
- * @param documentFiles - Optional specific file names to load
38
- * @param includeFileName - Whether to include fileName in result (default: false)
39
- * @returns Success with document array or Error
40
- *
41
- * @example
42
- * // Load all documents from a collection
43
- * const result = await DocumentLoader.loadDocuments(
44
- * '/path/to/collection',
45
- * undefined,
46
- * false
47
- * );
48
- *
49
- * @example
50
- * // Load specific documents with filenames included
51
- * const result = await DocumentLoader.loadDocuments(
52
- * '/path/to/collection',
53
- * 'encryption-key',
54
- * true,
55
- * ['doc1.axiodb', 'doc2.axiodb'],
56
- * true
57
- * );
58
- */
59
24
  static loadDocuments(collectionPath_1, encryptionKey_1) {
60
25
  return __awaiter(this, arguments, void 0, function* (collectionPath, encryptionKey, isEncrypted = false, documentFiles, includeFileName = false) {
61
26
  try {
62
27
  const dataFilesList = [];
63
28
  if (documentFiles !== undefined) {
64
- // Use provided file list
65
29
  dataFilesList.push(...documentFiles);
66
30
  }
67
31
  else {
68
- // Scan directory for .axiodb files
69
32
  const readResponse = yield new FolderManager_1.default().ListDirectory(collectionPath);
70
33
  if ("data" in readResponse) {
71
- // Filter for .axiodb files only
72
34
  const axiodbFiles = readResponse.data.filter((file) => file.endsWith(".axiodb"));
73
35
  dataFilesList.push(...axiodbFiles);
74
36
  }
@@ -76,7 +38,7 @@ class DocumentLoader {
76
38
  return this.ResponseHelper.Error("Failed to read directory");
77
39
  }
78
40
  }
79
- // Load all files using worker threads (parallel processing)
41
+ // Loaded via worker threads for parallelism
80
42
  const resultData = yield (0, BufferLoaderWithWorker_utils_1.default)(dataFilesList, encryptionKey, collectionPath, isEncrypted, includeFileName);
81
43
  return this.ResponseHelper.Success(resultData);
82
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentLoader.helper.js","sourceRoot":"","sources":["../../source/Helper/DocumentLoader.helper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,uFAA+D;AAC/D,2GAAuE;AACvE,wEAA+C;AAE/C;;;;;;;GAOG;AACH,MAAqB,cAAc;IAGjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,MAAM,CAAO,aAAa;6DACxB,cAAsB,EACtB,aAAsB,EACtB,WAAW,GAAY,KAAK,EAC5B,aAAwB,EACxB,eAAe,GAAY,KAAK;YAEhC,IAAI,CAAC;gBACH,MAAM,aAAa,GAAa,EAAE,CAAC;gBAEnC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;oBAChC,yBAAyB;oBACzB,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;gBACvC,CAAC;qBAAM,CAAC;oBACN,mCAAmC;oBACnC,MAAM,YAAY,GAAG,MAAM,IAAI,uBAAa,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;oBAE7E,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;wBAC3B,gCAAgC;wBAChC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAC5D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CACzB,CAAC;wBACF,aAAa,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;oBACrC,CAAC;yBAAM,CAAC;wBACN,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;gBAED,4DAA4D;gBAC5D,MAAM,UAAU,GAAG,MAAM,IAAA,sCAAgB,EACvC,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,CAChB,CAAC;gBAEF,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;KAAA;CACF;AA5EyB,6BAAc,GAAG,IAAI,yBAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"DocumentLoader.helper.js","sourceRoot":"","sources":["../../source/Helper/DocumentLoader.helper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,uFAA+D;AAC/D,2GAAuE;AACvE,wEAA+C;AAE/C;;;;GAIG;AACH,MAAqB,cAAc;IAGjC,MAAM,CAAO,aAAa;6DACxB,cAAsB,EACtB,aAAsB,EACtB,WAAW,GAAY,KAAK,EAC5B,aAAwB,EACxB,eAAe,GAAY,KAAK;YAEhC,IAAI,CAAC;gBACH,MAAM,aAAa,GAAa,EAAE,CAAC;gBAEnC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;oBAChC,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;gBACvC,CAAC;qBAAM,CAAC;oBACN,MAAM,YAAY,GAAG,MAAM,IAAI,uBAAa,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;oBAE7E,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;wBAC3B,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAC5D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CACzB,CAAC;wBACF,aAAa,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;oBACrC,CAAC;yBAAM,CAAC;wBACN,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;gBAED,4CAA4C;gBAC5C,MAAM,UAAU,GAAG,MAAM,IAAA,sCAAgB,EACvC,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,CAChB,CAAC;gBAEF,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;KAAA;CACF;AAzCyB,6BAAc,GAAG,IAAI,yBAAc,EAAE,CAAC"}
@@ -37,20 +37,17 @@ class PathSanitizer {
37
37
  if (!userInput || typeof userInput !== 'string') {
38
38
  throw new Error('Invalid path component: must be a non-empty string');
39
39
  }
40
- // Remove all directory traversal attempts
41
40
  let sanitized = userInput
42
- .replace(/\.\./g, '_') // Remove .. (parent directory)
43
- .replace(/\//g, '_') // Remove / (Unix path separator)
44
- .replace(/\\/g, '_') // Remove \ (Windows path separator)
45
- .replace(/\0/g, '_'); // Remove null bytes
46
- // Allow only alphanumeric, dash, underscore, and dot (for file extensions)
47
- // Note: We preserve dots for file extensions but removed '..' above
41
+ .replace(/\.\./g, '_') // parent directory
42
+ .replace(/\//g, '_') // Unix path separator
43
+ .replace(/\\/g, '_') // Windows path separator
44
+ .replace(/\0/g, '_'); // null bytes
45
+ // Dots are preserved (for file extensions) since '..' was already stripped above
48
46
  sanitized = sanitized.replace(/[^a-zA-Z0-9-_.]/g, '_');
49
- // Prevent empty result
50
47
  if (sanitized.length === 0) {
51
48
  throw new Error('Invalid path component: results in empty string after sanitization');
52
49
  }
53
- // Prevent starting with dot (hidden files) to avoid potential issues
50
+ // Avoid producing a hidden file
54
51
  if (sanitized.startsWith('.')) {
55
52
  sanitized = '_' + sanitized.substring(1);
56
53
  }
@@ -100,11 +97,8 @@ class PathSanitizer {
100
97
  * // Throws: Security violation (after sanitization and validation)
101
98
  */
102
99
  static safePath(basePath, ...components) {
103
- // Sanitize each component
104
100
  const sanitizedComponents = components.map(c => this.sanitizePathComponent(c));
105
- // Join paths using Node.js path.join (handles platform differences)
106
101
  const fullPath = path_1.default.join(basePath, ...sanitizedComponents);
107
- // Validate final path is within base (defense in depth)
108
102
  this.validatePath(basePath, fullPath);
109
103
  return fullPath;
110
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PathSanitizer.helper.js","sourceRoot":"","sources":["../../source/Helper/PathSanitizer.helper.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AAExB;;;;;;;;;;GAUG;AACH;IACE;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,qBAAqB,CAAC,SAAiB;QAC5C,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QAED,0CAA0C;QAC1C,IAAI,SAAS,GAAG,SAAS;aACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAI,+BAA+B;aACxD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAM,iCAAiC;aAC1D,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAM,oCAAoC;aAC7D,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAK,oBAAoB;QAEhD,2EAA2E;QAC3E,oEAAoE;QACpE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAEvD,uBAAuB;QACvB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QAED,qEAAqE;QACrE,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,SAAS,GAAG,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,YAAY,CAAC,QAAgB,EAAE,QAAgB;QACpD,MAAM,YAAY,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,YAAY,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAE5C,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAgB,EAAE,GAAG,UAAoB;QACvD,0BAA0B;QAC1B,MAAM,mBAAmB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/E,oEAAoE;QACpE,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,mBAAmB,CAAC,CAAC;QAE7D,wDAAwD;QACxD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEtC,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"PathSanitizer.helper.js","sourceRoot":"","sources":["../../source/Helper/PathSanitizer.helper.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AAExB;;;;;;;;;;GAUG;AACH;IACE;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,qBAAqB,CAAC,SAAiB;QAC5C,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,SAAS,GAAG,SAAS;aACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAI,mBAAmB;aAC5C,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAM,sBAAsB;aAC/C,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAM,yBAAyB;aAClD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAK,aAAa;QAEzC,iFAAiF;QACjF,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAEvD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QAED,gCAAgC;QAChC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,SAAS,GAAG,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,YAAY,CAAC,QAAgB,EAAE,QAAgB;QACpD,MAAM,YAAY,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,YAAY,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAE5C,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAgB,EAAE,GAAG,UAAoB;QACvD,MAAM,mBAAmB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,mBAAmB,CAAC,CAAC;QAC7D,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEtC,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}