Skip to content

v0.13.0

Latest

Choose a tag to compare

@rmyndharis rmyndharis released this 03 Aug 06:55

Added

  • BAILEYS_MARK_ONLINE_ON_CONNECT=false keeps phone push notifications alive while a Baileys gateway is connected (default true, prior behavior). (#871)

  • The catalog endpoints now work on the Baileys engine. GET /catalog, GET /catalog/products,
    GET /catalog/products/:id and POST /messages/send-product were 501 on both engines even
    though Baileys has exposed the full catalog surface (getCatalog/getCollections) for a while —
    the adapter simply never called it. The reads walk the library's cursor-based catalog in full and
    slice page/limit in memory, so pagination.total/totalPages are exact rather than estimated;
    catalog metadata is synthesized from the first collection (a business without collections gets
    null). sendProduct resolves the product from the catalog and sends it as a native product
    card — unknown ids come back 404, products without an image 400, since the card cannot render
    without one. send-catalog stays 501 on both engines: neither library has a catalog-share
    message type. whatsapp-web.js is unchanged (501 throughout — it has no catalog API). (#905)

  • Helm chart for Kubernetes deployments, under charts/openwa/. A single-replica
    StatefulSet with a PVC for /app/data (session auth, main DB, media, plugins), the
    docker-compose hardening mirrored (read-only rootfs, dropped capabilities, writable
    emptyDir at /tmp), free-form env/secretEnv maps covering every variable in
    .env.example, and optional Ingress, PodDisruptionBudget and ServiceMonitor.
    Datastores are not bundled — point env at your own or stay on the SQLite default.
    Closes #695.

Fixed

  • A contact who hides their number no longer keeps a stale lid -> phone mapping forever.
    SessionLidResolver only persisted positive resolutions, so once a @lid sender's phone became
    unresolvable (e.g. username adoption) the stored mapping was never corrected — the message from
    filter and the reverse lookup kept attributing that lid to the old number, and API responses kept
    returning a phone the user chose to hide. A definitive null answer from the engine now overwrites
    the mapping; transient failures (no live engine, call rejected) still never touch it. (#1058)

  • A key pasted with a stray space now authenticates on the WebSocket, not just over REST.
    validateApiKey hashed the raw string as given, and HTTP strips surrounding whitespace from header
    values in transit — so a padded key was accepted on every REST call while the Socket.IO handshake,
    which carries the literal string in its CONNECT payload, hashed to something else and was rejected.
    The failure was silent in the worst way: the dashboard's commands all went through, but not a single
    event arrived, so every session rendered as disconnected and restarting one looked inert — the
    restart ran, the UI just never heard about it. The key is now trimmed once in validateApiKey, which
    REST, the WebSocket gateway and the MCP mount all route through, so every surface agrees on what the
    credential is. Whitespace is never part of a key, so no legitimate credential changes meaning.

  • Image builds no longer walk all of node_modules to chown it. The production stage ended with
    chown -R openwa:openwa /app, which touched every installed dependency file — over half an hour on
    a small VPS, the slowest step of the build — and duplicated their metadata into a new image layer.
    It was redundant: runtime writes only happen under /app/data and /tmp, the entrypoint re-chowns
    /app/data at every container start, and the app tree only needs read access. The chown now covers
    ./data only, so the step is instant and the layer is gone. (#1045)