Skip to content

v0.7.13

Choose a tag to compare

@rmyndharis rmyndharis released this 29 Jun 13:16
· 1438 commits to main since this release

Fixed

  • Bulk batch ids are unique per session, not globally. A batch id claimed by one session no longer prevents another session from using the same id — the uniqueness constraint is now scoped to (session, batchId), matching the per-session lookup, so an explicit cross-session reuse no longer fails with a 500. Reusing an id within the same session is still rejected with a clear 400. Existing databases are migrated in place. (#531)
  • A message arriving while a session is being deleted is no longer persisted as an orphan. The inbound-message handler re-checks that the session is still live after its asynchronous processing, so a message that races a session deletion can't leave behind a messages row (which has no cascade) for a session that no longer exists. (#531)
  • Per-session stats return a consistent lastActive timestamp on SQLite and PostgreSQL. GET /stats/sessions/:id previously emitted a different topChats[].lastActive format depending on the database (an ISO date-time on PostgreSQL versus the stored text on SQLite); it is now formatted to a stable YYYY-MM-DD HH:MM:SS on both. (#533)
  • The uuid id default now works on PostgreSQL 12 and older. Id generation relies on a gen_random_uuid() column default, which is a core built-in only from PostgreSQL 13; on older servers it lives in the pgcrypto extension. The migration now enables pgcrypto first, so a fresh deploy against PostgreSQL ≤ 12 no longer fails on startup or first insert. (#533)
  • The audit-log listing no longer loads the whole table for a large limit. GET /audit clamps its page size to a maximum of 200, so an oversized limit can't pull the entire audit_logs table into a single response. (#536)
  • Migration reverts are idempotent on a synchronize-bootstrapped database. The baileys_stored_messages and webhook_delivery_failures migrations now drop their indexes with IF EXISTS, so a down() no longer errors when the named indexes were never created. (#536)
  • Bulk send always releases its in-flight marker. A batch whose session engine was missing, or that threw mid-processing, previously left a stale entry in an in-memory tracking map; the marker is now released on every exit path. (#536)

Security

  • Hook re-entrancy is now blocked for sandboxed plugins too. A plugin running in the worker-thread sandbox could re-fire the hook it was handling by issuing a capability call (for example, sending a message from within a message:sending handler), because the re-entrancy guard did not span the worker boundary — looping the event back into the plugin without bound. The host now runs each worker-initiated capability call inside the in-flight hook context, so such a re-fire is short-circuited exactly as it already was for in-process plugins. (#532)
  • Docker container teardown is constrained to OpenWA-managed services. The POST /infra/restart endpoint passed its profilesToRemove list straight to container removal, which resolved containers by a name substring — so an unrecognized or empty profile could stop and remove an unrelated container. Teardown is now restricted to the managed allowlist (postgres, redis, minio) and container resolution requires an exact openwa-<service> name match. (#534)
  • Failed API-key authentication attempts are now recorded in the audit log. Rejected or denied keys (invalid, disabled/expired, IP- or session-scope-denied, or insufficient role) previously left no audit entry; the gateway now logs an api_key_auth_failed event with the client IP, method, path, and reason, giving administrators a forensic trail for credential probing. Audit logging stays best-effort and never affects the request outcome. (#535)
  • The SSRF guard blocks the deprecated IPv6 site-local range (fec0::/10). Webhook and server-side media URLs are now rejected when they resolve into fec0::/10, closing a gap alongside the already-blocked unique-local and link-local ranges. (#536)
  • Session-scoped MCP tools require a session id before authorization. A session-scoped tool invoked without a session id is now rejected, so a session-restricted API key can't be used to drive such a tool against a session outside its scope. (#536)
  • Contact-card vCards are sanitized on both engines. Sending a contact whose name or number contained CR/LF could inject extra vCard fields on the whatsapp-web.js engine; both adapters now build the vCard through one shared sanitizing helper (CR/LF stripped, digits-only waid). (#537)