Skip to content

Releases: LabOverWire/MQDB

v0.7.6

09 May 16:50
v0.7.6
80ca5eb

Choose a tag to compare

2026-05-06 — mqdb-cli 0.7.6

Fixed

  • --timeout did not apply during the MQTT CONNECT handshake. connect_client in crates/mqdb-cli/src/common.rs only wrapped the request/response wait in tokio::time::timeout; the MqttClient::connect[_with_options] calls themselves had no timeout, so any command (mqdb list, read, create, update, delete, etc.) would hang indefinitely against a TCP listener that accepts the connection but never sends CONNACK (silent broker, half-open NAT, firewall drop after SYN-ACK).
  • Extracted a shared connect_with_timeout(client, client_id, conn) helper in common.rs that wraps both MqttClient::connect[_with_options] calls in tokio::time::timeout(Duration::from_secs(conn.timeout), …) and surfaces connect to {broker} timed out after {N}s on expiry. The helper also honors conn.insecure for self-signed TLS — previously only the bench paths set this, the CRUD path silently skipped it.
  • Routed every CLI bench/dev_bench connect through the new helper to close the same bug class for mqdb bench db (sync + async + cascade + unique + changefeed), mqdb bench pubsub, mqdb dev bench (db/pubsub/sub-pub), and the broker-readiness probes in both bench/common.rs::wait_for_broker_ready and dev_bench/helpers.rs::wait_for_broker_ready. Removed two now-redundant local connect_client helpers in db_cascade.rs and db_changefeed.rs. The pubsub.rs paths use custom ConnectOptions (clean-start, custom keep-alive) so their connect calls are wrapped inline with the same timeout pattern rather than going through the helper.
  • Regression test test_cli_connect_timeout_against_silent_listener in crates/mqdb-cli/tests/cli_test.rs spawns a TCP listener that accepts the connection without speaking MQTT and asserts mqdb list ... --timeout 2 exits within 5 seconds with a "timed out" error. Verified to fail on main (pre-fix exits at ~6s with "Connection reset by peer") and pass with the fix in place.

2026-05-06 — mqdb-cluster 0.3.4

Fixed

  • Partition snapshot import did not populate FkReverseIndex. This was the "Known gap" called out in the 0.3.2 entry. After a rebalance-driven replica promotion, the new primary held the imported db_data records and FK constraints but its in-memory reverse-index cache ((target_entity, target_id, source_entity, source_field) → {source_id, …}) was empty for those records. start_fk_reverse_lookup and handle_fk_reverse_lookup_request would return empty for any record sitting on a newly-imported partition, causing ON DELETE CASCADE to miss children that the new primary owned and ON DELETE RESTRICT to silently allow deletes that should have been blocked.
  • StoreManager::import_partition now calls a new private rebuild_fk_indexes_after_import step at the end of the import. It iterates every registered FK constraint and calls the existing rebuild_fk_index_for_constraint helper, which walks db_data.list(source_entity) (now populated with the just-imported records) and seeds the reverse index. Mirrors the existing pattern at apply.rs:215 where constraint Insert via Raft replication triggers the same rebuild.
  • Test coverage: 12 new tests (466 → 478 in the cluster lib). Direct FkReverseIndex unit tests in data_store.rs (insert/lookup/remove, idempotent inserts, removing unknown source ids, field-scoped keys), update_fk_reverse_index and rebuild_fk_index_for_constraint unit tests in constraint_ops.rs (Insert/Update/Delete paths, no-op when no constraints, malformed JSON, non-FK constraint), and a regression test import_partition_rebuilds_fk_reverse_index in partition_io.rs that confirmed by fail-on-disable / pass-on-restore that the rebuild call is what makes the assertion pass.
  • E2E in examples/cluster-rebalance-stores/run.sh now creates 20 extra child comments (2 per parent) spread across all 10 parents and adds a cascade-via-node-4 observation: deletes every parent through node 4 after rebalance, then prints how many of the eligible children were cascade-removed. Surfaced as an observation rather than a hard assertion because cascade outcomes through any specific node depend on whether that node has the FK constraint locally, which is governed by schema/constraint replication topology (separate concern; see below).

Discovered while running the new E2E (separate follow-up)

  • Constraints don't reach all nodes uniformly. Across runs of the new E2E, only the leader (node 1) consistently held both the unique and FK constraints locally; nodes 2/3 sometimes had a subset, and a freshly-joined node 4 had none. Because constraints route through schema_partition(entity), any node that doesn't own that partition reaches the constraint only via forwarding — not in its local db_constraints store. The FkReverseIndex rebuild this PR adds is correct in its scope (it rebuilds for whatever constraints the importing node has locally), but a fully-correct cascade through every node requires constraints to be cluster-wide broadcast state. Tracked as future work alongside the schema replication topology issue first noted in the 0.3.2 CHANGELOG entry.

v0.7.5

25 Apr 22:16
v0.7.5
8b2098e

Choose a tag to compare

Release 0.7.5

v0.7.3

22 Apr 23:28
v0.7.3
d5433d9

Choose a tag to compare

Release 0.7.3

v0.7.2

11 Apr 17:30
v0.7.2
d33b49e

Choose a tag to compare

Affected crates: mqdb-core (0.5.1), mqdb-agent (0.7.0), mqdb-cli (0.7.2).

Added

  • MqdbAgent::start() method that returns a JoinHandle and a watch::Receiver<bool> readiness signal, firing only after both the TCP accept loop and the internal $DB/# handler are ready
  • Handler readiness oneshot in spawn_handler_task — signals after the $DB/# subscribe succeeds

Fixed

  • Replace hardcoded 500ms sleep in CLI tests with deterministic start() + ready_rx readiness signal
  • Replace wait_for_port + wait_for_ready polling in admin tests with start() + ready_rx
  • Replace static port counters with OS-assigned ephemeral ports in all test suites (agent, cli, cluster) to eliminate cross-binary port collisions
  • Ensure database directory tree exists before fjall open to prevent EBADF on FROM scratch Docker images
  • Direct tracing subscriber output to stderr in CLI to prevent log lines from corrupting JSON stdout

v0.7.1

10 Apr 15:32
v0.7.1
741bd6f

Choose a tag to compare

Affected crates: mqdb-core (0.5.1), mqdb-agent (0.6.1).

Security

  • Cap password length at 256 bytes to prevent Argon2id CPU exhaustion
  • Add rate limiters to vault enable/change MQTT handlers and OAuth token refresh endpoint
  • Validate entity names (alphanumeric, _, -, max 128 chars) and record IDs (reject +, #, /, max 512 bytes) in topic parsers
  • Reject JSON payloads over 4 MiB before parsing
  • Normalize challenge error messages to prevent internal status leakage
  • Replace bare SHA256 with HMAC-SHA256 for email hash fallback

v0.7.0

09 Apr 21:11
v0.7.0
46c2dc3

Choose a tag to compare

Affected crates: mqdb-core (0.5.0), mqdb-agent (0.6.0), mqdb-cli (0.7.0).

Added

  • Password reset endpoints: POST /auth/password/reset/start and POST /auth/password/reset/submit (HTTP, unauthenticated) for "forgot password" flow
  • Password reset MQTT topics: $DB/_auth/password/reset/start and $DB/_auth/password/reset/submit for authenticated users
  • Challenge purpose field to distinguish password reset from email verification challenges
  • Purpose guard in handle_verify_submit to reject password reset challenges
  • --no-rate-limit now disables all HTTP rate limiters (login, register, verify, password change, password reset)
  • AdminRequired topic protection now falls through to ACL for non-admin users, enabling operator-provisioned service accounts

Security

  • Promote $DB/_verify/# to AdminRequired topic protection tier to prevent leakage of verification codes and receipt spoofing

v0.6.0

05 Apr 00:49
0418e37

Choose a tag to compare

Affected crates: mqdb-core (0.4.0), mqdb-agent (0.5.0), mqdb-cluster (0.3.0), mqdb-cli (0.6.0).

Added

  • Password change endpoint: POST /auth/password/change (HTTP) and $DB/_auth/password/change (MQTT) for email-auth users with verified email
  • $DB/_auth/ topic namespace for self-service auth operations, exempt from topic protection
  • MQTT 5.0 correlation_data echoing in all DB and admin response handlers, enabling mqttv5 --wait-response and standard request-response clients
  • Dedicated password_change_rate_limiter (HTTP) and reuse of vault_unlock_limiter (MQTT) for brute-force protection

Changed

  • Cluster mode returns explicit error for $DB/_auth/ topics (agent-only)

v0.5.0

04 Apr 02:48
v0.5.0
eaba5d8

Choose a tag to compare

Affected crates: mqdb-core (0.3.0), mqdb-agent (0.4.0), mqdb-cluster (0.2.0), mqdb-cli (0.5.0).

Added

  • MQTT vault admin operations: $DB/_vault/{enable,unlock,lock,disable,change,status} — self-service vault management over MQTT 5.0 request-response, no HTTP session required
  • Shared vault_ops module extracting transport-agnostic vault batch operations from HTTP handlers
  • Direct-DB vault operations (_db variants) for the MQTT handler path, avoiding deadlock from nested MQTT round-trips in the sequential message handler loop
  • ErrorCode::RateLimited (429) for vault unlock brute-force protection over MQTT
  • Topic protection exemptions for $DB/_vault/* and $DB/_verify/* (non-admin users can access these)
  • --vault-min-passphrase-length flag (env: MQDB_VAULT_MIN_PASSPHRASE_LENGTH, default 0) to enforce minimum passphrase length on vault enable and change operations

Changed

  • Vault HTTP handlers refactored to thin wrappers over shared vault_ops functions
  • Cluster mode returns explicit error for vault admin topics (vault requires agent mode)

v0.4.0

02 Apr 20:42
v0.4.0
6fc9193

Choose a tag to compare

add email verification protocol and email/password auth

v0.3.0

31 Mar 00:32
v0.3.0
a425b87

Choose a tag to compare

Affected crates: mqdb-cli.

Added

  • Environment variable support for all agent start and cluster start CLI flags (MQDB_BIND, MQDB_DB, MQDB_DURABILITY, MQDB_NODE_ID, etc.)
  • Inline content environment variables for file-path flags: MQDB_PASSWD, MQDB_ACL, MQDB_SCRAM, MQDB_JWT_KEY, MQDB_PASSPHRASE, MQDB_LICENSE, MQDB_QUIC_CERT, MQDB_QUIC_KEY, MQDB_QUIC_CA, MQDB_OAUTH_CLIENT_SECRET, MQDB_IDENTITY_KEY, MQDB_FEDERATED_JWT_CONFIG, MQDB_CERT_AUTH
  • Precedence: CLI flags > inline env vars (MQDB_*) > file-path env vars (MQDB_*_FILE)