axiodb 11.9.16 โ 12.10.17
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 +140 -5
- package/lib/Services/Indexation.operation.d.ts +3 -0
- package/lib/Services/Indexation.operation.js +25 -4
- package/lib/Services/Indexation.operation.js.map +1 -1
- package/lib/client/AxioDBCloud.client.d.ts +20 -6
- package/lib/client/AxioDBCloud.client.js +48 -17
- package/lib/client/AxioDBCloud.client.js.map +1 -1
- package/lib/client/PooledConnection.d.ts +7 -0
- package/lib/client/PooledConnection.js +26 -6
- package/lib/client/PooledConnection.js.map +1 -1
- package/lib/client/types/client.types.d.ts +19 -0
- package/lib/client/types/client.types.js.map +1 -1
- package/lib/config/Interfaces/Operation/Indexation.operation.interface.d.ts +6 -0
- package/lib/tcp/config/keys.d.ts +15 -0
- package/lib/tcp/config/keys.js +20 -1
- package/lib/tcp/config/keys.js.map +1 -1
- package/lib/tcp/config/server.d.ts +6 -1
- package/lib/tcp/config/server.js +46 -15
- package/lib/tcp/config/server.js.map +1 -1
- package/lib/tcp/connection/ConnectionManager.d.ts +17 -1
- package/lib/tcp/connection/ConnectionManager.js +51 -3
- package/lib/tcp/connection/ConnectionManager.js.map +1 -1
- package/lib/tcp/connection/ConnectionRateLimiter.d.ts +31 -0
- package/lib/tcp/connection/ConnectionRateLimiter.js +83 -0
- package/lib/tcp/connection/ConnectionRateLimiter.js.map +1 -0
- 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
|
|
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:**
|
|
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
|
|
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
|
|
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
|
|
|
@@ -19,6 +19,7 @@ const FileManager_1 = __importDefault(require("../engine/Filesystem/FileManager"
|
|
|
19
19
|
const FolderManager_1 = __importDefault(require("../engine/Filesystem/FolderManager"));
|
|
20
20
|
const Keys_1 = require("../config/Keys/Keys");
|
|
21
21
|
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const fs_1 = __importDefault(require("fs"));
|
|
22
23
|
const database_operation_1 = __importDefault(require("./Database/database.operation"));
|
|
23
24
|
// import startWebServer from "../server/Fastify";
|
|
24
25
|
// Helper Classes
|
|
@@ -50,11 +51,12 @@ class AxioDB {
|
|
|
50
51
|
this.GUI = Keys_1.General.DBMS_GUI_Enable;
|
|
51
52
|
this.TCP = false;
|
|
52
53
|
this.TCPAuth = false;
|
|
54
|
+
this.TLS = false;
|
|
53
55
|
if (AxioDB._instance) {
|
|
54
56
|
throw new Error("Only one instance of AxioDB is allowed.");
|
|
55
57
|
}
|
|
56
58
|
AxioDB._instance = this;
|
|
57
|
-
const { GUI, RootName, CustomPath, TCP, TCPAuth } = options;
|
|
59
|
+
const { GUI, RootName, CustomPath, TCP, TCPAuth, TLS, TLSCertPath, TLSKeyPath } = options;
|
|
58
60
|
// Default Vlaues
|
|
59
61
|
this.RootName = RootName || Keys_1.General.DBMS_Name; // Set the root name
|
|
60
62
|
this.currentPATH = path_1.default.resolve(CustomPath || "."); // Set the current path
|
|
@@ -66,7 +68,23 @@ class AxioDB {
|
|
|
66
68
|
this.GUI = GUI !== undefined ? GUI : Keys_1.General.DBMS_GUI_Enable; // Set GUI option
|
|
67
69
|
this.TCP = TCP !== undefined ? TCP : false; // Set TCP option
|
|
68
70
|
this.TCPAuth = TCPAuth !== undefined ? TCPAuth : false; // Set TCPAuth option
|
|
69
|
-
this.
|
|
71
|
+
this.TLS = TLS !== undefined ? TLS : false; // Set TLS option
|
|
72
|
+
this.TLSCertPath = TLSCertPath;
|
|
73
|
+
this.TLSKeyPath = TLSKeyPath;
|
|
74
|
+
// Fail fast: never silently fall back to plaintext because a cert/key path was
|
|
75
|
+
// missing or unreadable - that would be a silent security downgrade.
|
|
76
|
+
if (this.TLS) {
|
|
77
|
+
if (!this.TLSCertPath || !this.TLSKeyPath) {
|
|
78
|
+
throw new Error("TLS: true requires both TLSCertPath and TLSKeyPath to be set.");
|
|
79
|
+
}
|
|
80
|
+
if (!fs_1.default.existsSync(this.TLSCertPath)) {
|
|
81
|
+
throw new Error(`TLSCertPath does not exist: ${this.TLSCertPath}`);
|
|
82
|
+
}
|
|
83
|
+
if (!fs_1.default.existsSync(this.TLSKeyPath)) {
|
|
84
|
+
throw new Error(`TLSKeyPath does not exist: ${this.TLSKeyPath}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.initializeRoot(); // Ensure root initialization (reads GUI/TCP/TCPAuth/TLS, so runs after they're set)
|
|
70
88
|
}
|
|
71
89
|
/**
|
|
72
90
|
* Initializes the root directory for the AxioDB.
|
|
@@ -100,9 +118,12 @@ class AxioDB {
|
|
|
100
118
|
(0, server_1.default)(this); // Start the web Control Server with the AxioDB instance
|
|
101
119
|
}
|
|
102
120
|
if (this.TCP) {
|
|
103
|
-
Console_helper_1.default.green("Starting AxioDB TCP Server...");
|
|
121
|
+
Console_helper_1.default.green(this.TLS ? "Starting AxioDB TCP Server (TLS)..." : "Starting AxioDB TCP Server...");
|
|
104
122
|
// Start the TCP Server with the AxioDB instance
|
|
105
|
-
|
|
123
|
+
const tlsOptions = this.TLS
|
|
124
|
+
? { certPath: this.TLSCertPath, keyPath: this.TLSKeyPath }
|
|
125
|
+
: undefined;
|
|
126
|
+
(0, server_2.default)(this, undefined, this.TCPAuth, tlsOptions).catch((error) => {
|
|
106
127
|
console.error("[AxioDB TCP Server] Failed to start:", error);
|
|
107
128
|
});
|
|
108
129
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Indexation.operation.js","sourceRoot":"","sources":["../../source/Services/Indexation.operation.ts"],"names":[],"mappings":";AAAA,uDAAuD;;;;;;;;;;;;;;;AAEvD,mBAAmB;AACnB,mFAA2D;AAC3D,uFAA+D;AAC/D,8CAA8C;AAC9C,gDAAwB;AACxB,uFAAqD;AACrD,kDAAkD;AAElD,iBAAiB;AACjB,kFAAmD;AACnD,8EAA+C;AAC/C,0DAAwD;AACxD,gFAAuD;AAQvD,qEAAgE;AAEhE,kEAAyD;AACzD,mFAAmD;AACnD,4DAA8D;AAC9D,+FAA+D;AAE/D;;;;;;;;;;;;;GAaG;AACH;
|
|
1
|
+
{"version":3,"file":"Indexation.operation.js","sourceRoot":"","sources":["../../source/Services/Indexation.operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,18 +6,20 @@ import DatabaseProxy from './DatabaseProxy';
|
|
|
6
6
|
* AxioDBCloud - TCP Client for remote AxioDB access
|
|
7
7
|
*
|
|
8
8
|
* Maintains a pool of `maxPoolSize` concurrent TCP connections (default: 10, mirrors
|
|
9
|
-
* MongoDB's driver default naming/behavior) to the same server. Commands are
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* MongoDB's driver default naming/behavior) to the same server. Commands are routed to
|
|
10
|
+
* whichever connected pool member has the fewest in-flight requests, so a slow command
|
|
11
|
+
* on one connection doesn't queue new commands behind it while other members sit idle;
|
|
12
|
+
* each member independently reconnects (with exponential backoff) and re-authenticates,
|
|
13
|
+
* so one dropped connection never affects the others or blocks in-flight commands routed
|
|
14
|
+
* to healthy members.
|
|
13
15
|
*/
|
|
14
16
|
export declare class AxioDBCloud extends EventEmitter {
|
|
15
17
|
private host;
|
|
16
18
|
private port;
|
|
17
19
|
private pool;
|
|
18
|
-
private roundRobinIndex;
|
|
19
20
|
private options;
|
|
20
21
|
private credentials?;
|
|
22
|
+
private readonly tlsCA?;
|
|
21
23
|
constructor(connectionString: string, options?: AxioDBCloudOptions);
|
|
22
24
|
/**
|
|
23
25
|
* Parse connection string: axiodb://host:port
|
|
@@ -29,6 +31,13 @@ export declare class AxioDBCloud extends EventEmitter {
|
|
|
29
31
|
* attempts against the server's shared per-IP rate limiter N times over for a single bad
|
|
30
32
|
* -credentials connect() call, and ensures a bad-credentials failure never leaves any pool
|
|
31
33
|
* member mid-reconnect.
|
|
34
|
+
*
|
|
35
|
+
* The first connection must succeed or `connect()` rejects entirely (it's the signal that
|
|
36
|
+
* the server is reachable and credentials are valid at all). The rest of the pool uses
|
|
37
|
+
* allSettled rather than all: if `maxPoolSize` asks for more connections than the server
|
|
38
|
+
* allows from this IP (see the server's per-IP connection cap) or a handful hit a transient
|
|
39
|
+
* error, the pool still comes up with however many succeeded instead of failing outright -
|
|
40
|
+
* a smaller-than-requested pool is far more useful to the caller than no pool at all.
|
|
32
41
|
*/
|
|
33
42
|
connect(): Promise<void>;
|
|
34
43
|
private createPooledConnection;
|
|
@@ -48,9 +57,14 @@ export declare class AxioDBCloud extends EventEmitter {
|
|
|
48
57
|
*/
|
|
49
58
|
get authenticatedUser(): AuthenticatedUser | undefined;
|
|
50
59
|
/**
|
|
51
|
-
* Send command to server - picks
|
|
60
|
+
* Send command to server - picks the least-busy connected pool member.
|
|
52
61
|
*/
|
|
53
62
|
sendCommand(command: CommandType, params: any): Promise<any>;
|
|
63
|
+
/**
|
|
64
|
+
* Picks the connected pool member with the fewest in-flight requests (least-busy),
|
|
65
|
+
* rather than round-robin, so a connection stuck on a slow command doesn't receive
|
|
66
|
+
* more work while other members are idle.
|
|
67
|
+
*/
|
|
54
68
|
private pickConnection;
|
|
55
69
|
/**
|
|
56
70
|
* Disconnect from server - closes every connection in the pool.
|
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.AxioDBCloud = void 0;
|
|
16
16
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
17
17
|
const events_1 = require("events");
|
|
18
|
+
const fs_1 = __importDefault(require("fs"));
|
|
18
19
|
const PooledConnection_1 = __importDefault(require("./PooledConnection"));
|
|
19
20
|
const command_types_1 = require("../tcp/types/command.types");
|
|
20
21
|
const client_types_1 = require("./types/client.types");
|
|
@@ -24,16 +25,18 @@ const DEFAULT_MAX_POOL_SIZE = 10;
|
|
|
24
25
|
* AxioDBCloud - TCP Client for remote AxioDB access
|
|
25
26
|
*
|
|
26
27
|
* Maintains a pool of `maxPoolSize` concurrent TCP connections (default: 10, mirrors
|
|
27
|
-
* MongoDB's driver default naming/behavior) to the same server. Commands are
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* MongoDB's driver default naming/behavior) to the same server. Commands are routed to
|
|
29
|
+
* whichever connected pool member has the fewest in-flight requests, so a slow command
|
|
30
|
+
* on one connection doesn't queue new commands behind it while other members sit idle;
|
|
31
|
+
* each member independently reconnects (with exponential backoff) and re-authenticates,
|
|
32
|
+
* so one dropped connection never affects the others or blocks in-flight commands routed
|
|
33
|
+
* to healthy members.
|
|
31
34
|
*/
|
|
32
35
|
class AxioDBCloud extends events_1.EventEmitter {
|
|
33
36
|
constructor(connectionString, options) {
|
|
37
|
+
var _a, _b;
|
|
34
38
|
super();
|
|
35
39
|
this.pool = [];
|
|
36
|
-
this.roundRobinIndex = 0;
|
|
37
40
|
// Increase max listeners for reconnection scenarios
|
|
38
41
|
this.setMaxListeners(20);
|
|
39
42
|
// Default 'error' listener: Node's EventEmitter throws synchronously when 'error' is
|
|
@@ -59,7 +62,12 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
59
62
|
reconnectDelay: (options === null || options === void 0 ? void 0 : options.reconnectDelay) || 1000,
|
|
60
63
|
heartbeatInterval: (options === null || options === void 0 ? void 0 : options.heartbeatInterval) || 30000,
|
|
61
64
|
maxPoolSize: (options === null || options === void 0 ? void 0 : options.maxPoolSize) || DEFAULT_MAX_POOL_SIZE,
|
|
65
|
+
tls: (_a = options === null || options === void 0 ? void 0 : options.tls) !== null && _a !== void 0 ? _a : false,
|
|
66
|
+
tlsRejectUnauthorized: (_b = options === null || options === void 0 ? void 0 : options.tlsRejectUnauthorized) !== null && _b !== void 0 ? _b : true,
|
|
62
67
|
};
|
|
68
|
+
if (options === null || options === void 0 ? void 0 : options.tlsCAPath) {
|
|
69
|
+
this.tlsCA = fs_1.default.readFileSync(options.tlsCAPath);
|
|
70
|
+
}
|
|
63
71
|
if ((options === null || options === void 0 ? void 0 : options.username) && (options === null || options === void 0 ? void 0 : options.password)) {
|
|
64
72
|
this.credentials = { username: options.username, password: options.password };
|
|
65
73
|
}
|
|
@@ -83,6 +91,13 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
83
91
|
* attempts against the server's shared per-IP rate limiter N times over for a single bad
|
|
84
92
|
* -credentials connect() call, and ensures a bad-credentials failure never leaves any pool
|
|
85
93
|
* member mid-reconnect.
|
|
94
|
+
*
|
|
95
|
+
* The first connection must succeed or `connect()` rejects entirely (it's the signal that
|
|
96
|
+
* the server is reachable and credentials are valid at all). The rest of the pool uses
|
|
97
|
+
* allSettled rather than all: if `maxPoolSize` asks for more connections than the server
|
|
98
|
+
* allows from this IP (see the server's per-IP connection cap) or a handful hit a transient
|
|
99
|
+
* error, the pool still comes up with however many succeeded instead of failing outright -
|
|
100
|
+
* a smaller-than-requested pool is far more useful to the caller than no pool at all.
|
|
86
101
|
*/
|
|
87
102
|
connect() {
|
|
88
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -93,7 +108,17 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
93
108
|
this.pool = Array.from({ length: poolSize }, () => this.createPooledConnection());
|
|
94
109
|
yield this.pool[0].connect();
|
|
95
110
|
if (poolSize > 1) {
|
|
96
|
-
yield Promise.
|
|
111
|
+
const results = yield Promise.allSettled(this.pool.slice(1).map((connection) => connection.connect()));
|
|
112
|
+
const failures = results.filter((result) => result.status === 'rejected');
|
|
113
|
+
if (failures.length > 0) {
|
|
114
|
+
const event = {
|
|
115
|
+
requested: poolSize,
|
|
116
|
+
connected: poolSize - failures.length,
|
|
117
|
+
failed: failures.length,
|
|
118
|
+
errors: failures.map((failure) => failure.reason instanceof Error ? failure.reason : new Error(String(failure.reason))),
|
|
119
|
+
};
|
|
120
|
+
this.emit('poolDegraded', event);
|
|
121
|
+
}
|
|
97
122
|
}
|
|
98
123
|
this.emit('connected');
|
|
99
124
|
});
|
|
@@ -104,6 +129,9 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
104
129
|
reconnectAttempts: this.options.reconnectAttempts,
|
|
105
130
|
reconnectDelay: this.options.reconnectDelay,
|
|
106
131
|
heartbeatInterval: this.options.heartbeatInterval,
|
|
132
|
+
tls: this.options.tls,
|
|
133
|
+
tlsCA: this.tlsCA,
|
|
134
|
+
tlsRejectUnauthorized: this.options.tlsRejectUnauthorized,
|
|
107
135
|
}, () => this.credentials, {
|
|
108
136
|
onError: (error) => this.emit('error', error),
|
|
109
137
|
onDisconnected: (hadError) => this.emit('disconnected', hadError),
|
|
@@ -145,7 +173,7 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
145
173
|
return (_a = this.pool.find((connection) => connection.authUser)) === null || _a === void 0 ? void 0 : _a.authUser;
|
|
146
174
|
}
|
|
147
175
|
/**
|
|
148
|
-
* Send command to server - picks
|
|
176
|
+
* Send command to server - picks the least-busy connected pool member.
|
|
149
177
|
*/
|
|
150
178
|
sendCommand(command, params) {
|
|
151
179
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -156,19 +184,22 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
156
184
|
return connection.sendCommand(command, params);
|
|
157
185
|
});
|
|
158
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Picks the connected pool member with the fewest in-flight requests (least-busy),
|
|
189
|
+
* rather than round-robin, so a connection stuck on a slow command doesn't receive
|
|
190
|
+
* more work while other members are idle.
|
|
191
|
+
*/
|
|
159
192
|
pickConnection() {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (connection.state === client_types_1.ConnectionState.CONNECTED) {
|
|
168
|
-
return connection;
|
|
193
|
+
let best = null;
|
|
194
|
+
for (const connection of this.pool) {
|
|
195
|
+
if (connection.state !== client_types_1.ConnectionState.CONNECTED) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (best === null || connection.pendingCount < best.pendingCount) {
|
|
199
|
+
best = connection;
|
|
169
200
|
}
|
|
170
201
|
}
|
|
171
|
-
return
|
|
202
|
+
return best;
|
|
172
203
|
}
|
|
173
204
|
/**
|
|
174
205
|
* Disconnect from server - closes every connection in the pool.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AxioDBCloud.client.js","sourceRoot":"","sources":["../../source/client/AxioDBCloud.client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uDAAuD;AACvD,mCAAsC;AACtC,0EAAkD;AAClD,8DAAyD;AACzD,
|
|
1
|
+
{"version":3,"file":"AxioDBCloud.client.js","sourceRoot":"","sources":["../../source/client/AxioDBCloud.client.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,11 @@ export interface PooledConnectionOptions {
|
|
|
6
6
|
reconnectAttempts: number;
|
|
7
7
|
reconnectDelay: number;
|
|
8
8
|
heartbeatInterval: number;
|
|
9
|
+
/** Encrypt this connection with TLS instead of plaintext. */
|
|
10
|
+
tls?: boolean;
|
|
11
|
+
/** Pre-read CA certificate content (see AxioDBCloud's tlsCAPath) - read once at the pool level, not per connection. */
|
|
12
|
+
tlsCA?: Buffer;
|
|
13
|
+
tlsRejectUnauthorized?: boolean;
|
|
9
14
|
}
|
|
10
15
|
/** Callbacks a PooledConnection uses to surface lifecycle events to its owning AxioDBCloud pool. */
|
|
11
16
|
export interface PooledConnectionCallbacks {
|
|
@@ -34,6 +39,8 @@ export default class PooledConnection {
|
|
|
34
39
|
private heartbeatInterval;
|
|
35
40
|
state: ConnectionState;
|
|
36
41
|
authUser?: AuthenticatedUser;
|
|
42
|
+
/** Number of requests sent on this connection awaiting a response - used by the owning pool to route new commands to the least-busy member instead of blind round-robin. */
|
|
43
|
+
get pendingCount(): number;
|
|
37
44
|
constructor(host: string, port: number, options: PooledConnectionOptions, getCredentials: () => {
|
|
38
45
|
username: string;
|
|
39
46
|
password: string;
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
13
13
|
const net_1 = require("net");
|
|
14
|
+
const tls_1 = require("tls");
|
|
14
15
|
const crypto_1 = require("crypto");
|
|
15
16
|
const protocol_1 = require("../tcp/config/protocol");
|
|
16
17
|
const command_types_1 = require("../tcp/types/command.types");
|
|
@@ -21,6 +22,10 @@ const client_types_1 = require("./types/client.types");
|
|
|
21
22
|
* failure on one pooled connection never affects the others in the pool.
|
|
22
23
|
*/
|
|
23
24
|
class PooledConnection {
|
|
25
|
+
/** Number of requests sent on this connection awaiting a response - used by the owning pool to route new commands to the least-busy member instead of blind round-robin. */
|
|
26
|
+
get pendingCount() {
|
|
27
|
+
return this.pendingRequests.size;
|
|
28
|
+
}
|
|
24
29
|
constructor(host, port, options, getCredentials, callbacks) {
|
|
25
30
|
this.host = host;
|
|
26
31
|
this.port = port;
|
|
@@ -41,6 +46,7 @@ class PooledConnection {
|
|
|
41
46
|
*/
|
|
42
47
|
connect() {
|
|
43
48
|
return new Promise((resolve, reject) => {
|
|
49
|
+
var _a;
|
|
44
50
|
if (this.state === client_types_1.ConnectionState.CONNECTED) {
|
|
45
51
|
resolve();
|
|
46
52
|
return;
|
|
@@ -53,8 +59,6 @@ class PooledConnection {
|
|
|
53
59
|
this.socket = null;
|
|
54
60
|
}
|
|
55
61
|
this.state = client_types_1.ConnectionState.CONNECTING;
|
|
56
|
-
const socket = new net_1.Socket();
|
|
57
|
-
this.socket = socket;
|
|
58
62
|
const connectionTimeout = setTimeout(() => {
|
|
59
63
|
socket.destroy();
|
|
60
64
|
this.state = client_types_1.ConnectionState.FAILED;
|
|
@@ -70,9 +74,7 @@ class PooledConnection {
|
|
|
70
74
|
this.state = client_types_1.ConnectionState.FAILED;
|
|
71
75
|
reject(error);
|
|
72
76
|
};
|
|
73
|
-
|
|
74
|
-
this.setupSocketHandlers(socket);
|
|
75
|
-
socket.connect(this.port, this.host, () => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
const onReady = () => __awaiter(this, void 0, void 0, function* () {
|
|
76
78
|
clearTimeout(connectionTimeout);
|
|
77
79
|
socket.off('error', connectErrorHandler);
|
|
78
80
|
this.state = client_types_1.ConnectionState.CONNECTED;
|
|
@@ -96,7 +98,25 @@ class PooledConnection {
|
|
|
96
98
|
socket.destroy();
|
|
97
99
|
reject(authError);
|
|
98
100
|
}
|
|
99
|
-
})
|
|
101
|
+
});
|
|
102
|
+
// tls.connect() both creates and initiates the connection in one call (unlike
|
|
103
|
+
// net.Socket, which needs a separate .connect()), firing 'secureConnect' once the TLS
|
|
104
|
+
// handshake completes - a stronger readiness signal than plain TCP's 'connect', since
|
|
105
|
+
// it also implies certificate validation passed (rejectUnauthorized: true, the default).
|
|
106
|
+
const socket = this.options.tls
|
|
107
|
+
? (0, tls_1.connect)({
|
|
108
|
+
host: this.host,
|
|
109
|
+
port: this.port,
|
|
110
|
+
ca: this.options.tlsCA,
|
|
111
|
+
rejectUnauthorized: (_a = this.options.tlsRejectUnauthorized) !== null && _a !== void 0 ? _a : true,
|
|
112
|
+
}, onReady)
|
|
113
|
+
: new net_1.Socket();
|
|
114
|
+
this.socket = socket;
|
|
115
|
+
socket.once('error', connectErrorHandler);
|
|
116
|
+
this.setupSocketHandlers(socket);
|
|
117
|
+
if (!this.options.tls) {
|
|
118
|
+
socket.connect(this.port, this.host, onReady);
|
|
119
|
+
}
|
|
100
120
|
});
|
|
101
121
|
}
|
|
102
122
|
/** Sends the AUTHENTICATE command over this connection and stores the resulting identity. */
|