axiodb 11.9.14 โ 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 +183 -5
- package/lib/Services/Indexation.operation.d.ts +3 -0
- package/lib/Services/Indexation.operation.js +28 -4
- package/lib/Services/Indexation.operation.js.map +1 -1
- package/lib/client/AxioDBCloud.client.d.ts +39 -43
- package/lib/client/AxioDBCloud.client.js +134 -258
- package/lib/client/AxioDBCloud.client.js.map +1 -1
- package/lib/client/PooledConnection.d.ts +66 -0
- package/lib/client/PooledConnection.js +281 -0
- package/lib/client/PooledConnection.js.map +1 -0
- package/lib/client/types/client.types.d.ts +20 -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 +56 -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)
|
|
@@ -126,6 +127,26 @@ console.log(result.data.documents[0].message); // Hello, Developer! ๐
|
|
|
126
127
|
|
|
127
128
|
> **Only one `AxioDB` instance per application.** It's a singleton by design โ create it once, then create as many databases and collections as you need under it.
|
|
128
129
|
|
|
130
|
+
### `new AxioDB(options?)` โ all constructor options
|
|
131
|
+
|
|
132
|
+
| Option | Type | Default | Description |
|
|
133
|
+
| --- | --- | --- | --- |
|
|
134
|
+
| `GUI` | `boolean` | `false` | Enable the web-based GUI dashboard at `localhost:27018` |
|
|
135
|
+
| `RootName` | `string` | `"AxioDB"` | Name of the root folder database files are stored under |
|
|
136
|
+
| `CustomPath` | `string` | current working directory | Custom filesystem path for database storage |
|
|
137
|
+
| `TCP` | `boolean` | `false` | Enable the AxioDBCloud TCP server on port 27019 |
|
|
138
|
+
| `TCPAuth` | `boolean` | `false` | Require username/password authentication on TCP connections (same RBAC accounts as the GUI) โ see [Advanced: TCP authentication](#advanced-tcp-authentication) |
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
const db = new AxioDB({
|
|
142
|
+
GUI: true,
|
|
143
|
+
RootName: 'MyDB',
|
|
144
|
+
CustomPath: './data',
|
|
145
|
+
TCP: true,
|
|
146
|
+
TCPAuth: true,
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
129
150
|
---
|
|
130
151
|
|
|
131
152
|
## ๐ Features
|
|
@@ -192,7 +213,9 @@ await session.withTransaction(async (tx) => {
|
|
|
192
213
|
- **๐ Auto-Reconnect:** exponential backoff, up to 10 retry attempts
|
|
193
214
|
- **๐ Heartbeat Monitoring:** `PING`/`PONG` every 30 seconds
|
|
194
215
|
- **๐ Request Correlation:** UUID-based request/response matching
|
|
195
|
-
- **๐งต Connection Pooling:**
|
|
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
|
|
196
219
|
- **๐ TypeScript Support:** full type definitions included
|
|
197
220
|
|
|
198
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).
|
|
@@ -260,7 +283,56 @@ await client.login('admin', 'admin');
|
|
|
260
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.
|
|
261
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.
|
|
262
285
|
|
|
263
|
-
**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.
|
|
264
336
|
|
|
265
337
|
๐ **[Full AxioDBCloud Documentation](https://axiodb.in/cloud)** โ setup guides, API reference, Docker examples
|
|
266
338
|
|
|
@@ -296,6 +368,27 @@ Your credentials are correct, but that account is still flagged for a forced pas
|
|
|
296
368
|
|
|
297
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.
|
|
298
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
|
+
|
|
299
392
|
### `403` โ "This is a reserved system database"
|
|
300
393
|
|
|
301
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.
|
|
@@ -310,6 +403,37 @@ You (or a client) tried to read/write a database literally named `config` โ th
|
|
|
310
403
|
|
|
311
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).
|
|
312
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
|
+
|
|
313
437
|
---
|
|
314
438
|
|
|
315
439
|
## ๐ณ Docker Deployment
|
|
@@ -342,12 +466,15 @@ Every option below has a default matching the image's previous fixed behavior
|
|
|
342
466
|
| `AXIODB_GUI` | `true` | Enable the HTTP Control Server / web GUI on port 27018 |
|
|
343
467
|
| `AXIODB_TCP` | `true` | Enable the AxioDBCloud TCP server on port 27019 |
|
|
344
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` |
|
|
345
472
|
| `AXIODB_ROOT_NAME` | `AxioDB` | Name of the root database folder created under the data volume |
|
|
346
473
|
| `AXIODB_CUSTOM_PATH` | *(container's working directory)* | Custom path for database storage inside the container |
|
|
347
474
|
|
|
348
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`.
|
|
349
476
|
|
|
350
|
-
**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)):
|
|
351
478
|
```bash
|
|
352
479
|
docker run -d \
|
|
353
480
|
--name axiodb-server \
|
|
@@ -382,6 +509,34 @@ volumes:
|
|
|
382
509
|
axiodb-data:
|
|
383
510
|
```
|
|
384
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
|
+
|
|
385
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.
|
|
386
541
|
|
|
387
542
|
---
|
|
@@ -425,7 +580,7 @@ A Super Admin can create additional roles from the predefined permission catalog
|
|
|
425
580
|
|
|
426
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).
|
|
427
582
|
|
|
428
|
-
> **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.
|
|
429
584
|
|
|
430
585
|
---
|
|
431
586
|
|
|
@@ -552,6 +707,29 @@ const user = await users.query({ username: 'johndoe' }).exec();
|
|
|
552
707
|
- `dropIndex(indexName: string): Promise<SuccessInterface | ErrorInterface>`
|
|
553
708
|
- `getIndexes(): Promise<SuccessInterface | ErrorInterface>` โ lists all indexes registered on the collection
|
|
554
709
|
|
|
710
|
+
### Updater / Deleter
|
|
711
|
+
|
|
712
|
+
`update(query)` and `delete(query)` on their own don't change anything โ they return a chainable object. Call one of the methods below to actually apply the change:
|
|
713
|
+
|
|
714
|
+
- `updater.UpdateOne(data: object): Promise<SuccessInterface | ErrorInterface>` โ applies `data` to the first document matching `query`
|
|
715
|
+
- `updater.UpdateMany(data: object): Promise<SuccessInterface | ErrorInterface>` โ applies `data` to every document matching `query`
|
|
716
|
+
- `deleter.deleteOne(): Promise<SuccessInterface | ErrorInterface>` โ deletes the first document matching `query`
|
|
717
|
+
- `deleter.deleteMany(): Promise<SuccessInterface | ErrorInterface>` โ deletes every document matching `query`
|
|
718
|
+
|
|
719
|
+
```javascript
|
|
720
|
+
// Update the first matching document
|
|
721
|
+
await collection.update({ name: 'Alice' }).UpdateOne({ status: 'active' });
|
|
722
|
+
|
|
723
|
+
// Update every matching document
|
|
724
|
+
await collection.update({ role: 'trial' }).UpdateMany({ role: 'active' });
|
|
725
|
+
|
|
726
|
+
// Delete the first matching document
|
|
727
|
+
await collection.delete({ name: 'Alice' }).deleteOne();
|
|
728
|
+
|
|
729
|
+
// Delete every matching document
|
|
730
|
+
await collection.delete({ status: 'inactive' }).deleteMany();
|
|
731
|
+
```
|
|
732
|
+
|
|
555
733
|
### Reader
|
|
556
734
|
|
|
557
735
|
- `Limit(limit: number): Reader`
|
|
@@ -721,7 +899,7 @@ Yes. Full type definitions are included โ no separate `@types` package needed.
|
|
|
721
899
|
No. AxioDB requires Node.js (v20+) and the filesystem โ server-side and desktop only.
|
|
722
900
|
|
|
723
901
|
**Q: What is AxioDBCloud?**
|
|
724
|
-
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.
|
|
725
903
|
|
|
726
904
|
---
|
|
727
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,8 +118,14 @@ 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...");
|
|
104
|
-
|
|
121
|
+
Console_helper_1.default.green(this.TLS ? "Starting AxioDB TCP Server (TLS)..." : "Starting AxioDB TCP Server...");
|
|
122
|
+
// Start the TCP Server with the AxioDB instance
|
|
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) => {
|
|
127
|
+
console.error("[AxioDB TCP Server] Failed to start:", error);
|
|
128
|
+
});
|
|
105
129
|
}
|
|
106
130
|
});
|
|
107
131
|
}
|
|
@@ -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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"}
|
|
@@ -4,75 +4,70 @@ import { AxioDBCloudOptions, AuthenticatedUser, ConnectionState } from './types/
|
|
|
4
4
|
import DatabaseProxy from './DatabaseProxy';
|
|
5
5
|
/**
|
|
6
6
|
* AxioDBCloud - TCP Client for remote AxioDB access
|
|
7
|
+
*
|
|
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 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.
|
|
7
15
|
*/
|
|
8
16
|
export declare class AxioDBCloud extends EventEmitter {
|
|
9
17
|
private host;
|
|
10
18
|
private port;
|
|
11
|
-
private
|
|
12
|
-
private messageBuffer;
|
|
13
|
-
private pendingRequests;
|
|
14
|
-
private connectionState;
|
|
19
|
+
private pool;
|
|
15
20
|
private options;
|
|
16
|
-
private reconnectAttempt;
|
|
17
|
-
private heartbeatInterval;
|
|
18
21
|
private credentials?;
|
|
19
|
-
private
|
|
22
|
+
private readonly tlsCA?;
|
|
20
23
|
constructor(connectionString: string, options?: AxioDBCloudOptions);
|
|
21
24
|
/**
|
|
22
25
|
* Parse connection string: axiodb://host:port
|
|
23
26
|
*/
|
|
24
27
|
private parseConnectionString;
|
|
25
28
|
/**
|
|
26
|
-
*
|
|
29
|
+
* Open the connection pool. Authenticates the first connection alone (if credentials are
|
|
30
|
+
* provided) before opening the rest of the pool - this avoids multiplying failed-login
|
|
31
|
+
* attempts against the server's shared per-IP rate limiter N times over for a single bad
|
|
32
|
+
* -credentials connect() call, and ensures a bad-credentials failure never leaves any pool
|
|
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.
|
|
27
41
|
*/
|
|
28
42
|
connect(): Promise<void>;
|
|
43
|
+
private createPooledConnection;
|
|
29
44
|
/**
|
|
30
45
|
* Authenticate with username/password (same RBAC users as the GUI Control Server).
|
|
31
46
|
* Only required when the server was started with `TCPAuth: true`.
|
|
32
47
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
48
|
+
* Authenticates every currently-connected pool member and stashes the credentials so a
|
|
49
|
+
* later automatic reconnect replays login on any member that drops - otherwise a network
|
|
50
|
+
* blip after a runtime `login()` call would silently leave the reconnected member
|
|
51
|
+
* unauthenticated.
|
|
36
52
|
*/
|
|
37
53
|
login(username: string, password: string): Promise<AuthenticatedUser>;
|
|
38
54
|
/**
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
private performAuthenticate;
|
|
42
|
-
/**
|
|
43
|
-
* The currently authenticated identity, if `login()` (or constructor credentials) succeeded.
|
|
55
|
+
* The currently authenticated identity, if `login()` (or constructor credentials)
|
|
56
|
+
* succeeded on at least one pool member.
|
|
44
57
|
*/
|
|
45
58
|
get authenticatedUser(): AuthenticatedUser | undefined;
|
|
46
59
|
/**
|
|
47
|
-
*
|
|
48
|
-
*/
|
|
49
|
-
private setupSocketHandlers;
|
|
50
|
-
/**
|
|
51
|
-
* Handle server response
|
|
52
|
-
*/
|
|
53
|
-
private handleResponse;
|
|
54
|
-
/**
|
|
55
|
-
* Handle disconnection
|
|
60
|
+
* Send command to server - picks the least-busy connected pool member.
|
|
56
61
|
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Attempt to reconnect
|
|
60
|
-
*/
|
|
61
|
-
private attemptReconnect;
|
|
62
|
-
/**
|
|
63
|
-
* Start heartbeat
|
|
64
|
-
*/
|
|
65
|
-
private startHeartbeat;
|
|
66
|
-
/**
|
|
67
|
-
* Stop heartbeat
|
|
68
|
-
*/
|
|
69
|
-
private stopHeartbeat;
|
|
62
|
+
sendCommand(command: CommandType, params: any): Promise<any>;
|
|
70
63
|
/**
|
|
71
|
-
*
|
|
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.
|
|
72
67
|
*/
|
|
73
|
-
|
|
68
|
+
private pickConnection;
|
|
74
69
|
/**
|
|
75
|
-
* Disconnect from server
|
|
70
|
+
* Disconnect from server - closes every connection in the pool.
|
|
76
71
|
*/
|
|
77
72
|
disconnect(): Promise<void>;
|
|
78
73
|
/**
|
|
@@ -83,11 +78,12 @@ export declare class AxioDBCloud extends EventEmitter {
|
|
|
83
78
|
isDatabaseExists(name: string): Promise<boolean>;
|
|
84
79
|
getInstanceInfo(): Promise<any>;
|
|
85
80
|
/**
|
|
86
|
-
* Get current connection state
|
|
81
|
+
* Get current connection state - CONNECTED if at least one pool member is connected,
|
|
82
|
+
* otherwise the "best" state across the pool (RECONNECTING > CONNECTING > FAILED).
|
|
87
83
|
*/
|
|
88
84
|
get state(): ConnectionState;
|
|
89
85
|
/**
|
|
90
|
-
* Check if connected
|
|
86
|
+
* Check if connected - true when at least one pool member is connected.
|
|
91
87
|
*/
|
|
92
88
|
get isConnected(): boolean;
|
|
93
89
|
}
|