Skip to content

v0.10.8

Choose a tag to compare

@rmyndharis rmyndharis released this 23 Jul 14:51
· 645 commits to main since this release

Added

  • Release images are now also published to Docker Hub. Every release image is dual-published,
    bit-identical, to docker.io/rmyndharis/openwa alongside ghcr.io/rmyndharis/openwa — the same
    X.Y.Z / X.Y / latest tags, with provenance and SBOM attestations, and both registries are
    verified publicly pullable before the release completes.

  • German (de) dashboard translation. The dashboard now ships a full German locale and offers
    "Deutsch" in the language switcher. All translation keys are covered, so German users get a
    fully localized UI instead of the English fallback. Thanks @rjsebening.

  • Audit-log coverage for sensitive infrastructure operations. The admin-only infrastructure
    endpoints that save configuration, restart the server, and export/import the full database or
    stored media now record an audit-log entry — attributing the operation to the calling API key and
    client IP, with non-sensitive context only (section names, row counts; secret values are never
    logged). Previously these operations, several of which expose or replace credential-bearing data,
    left no audit trail. The audit-vocabulary coverage gate is extended to these actions, so a future
    infrastructure operation cannot ship without one.

  • A single kind discriminator identifies every chat and message. Chat summaries and inbound
    messages now carry one canonical kind field — individual, group, channel, status,
    broadcast, or unknown — instead of leaving every consumer to infer the type from ad-hoc boolean
    flags or JID suffixes. The field is threaded consistently through the REST API, webhook payloads,
    the WebSocket event stream, plugins, and the typed SDKs, so a channel post or a status update is no
    longer indistinguishable from an ordinary chat message downstream. The existing isGroup and
    isStatusBroadcast fields are unchanged and keep working for integrations that already rely on them.

  • The dashboard Chats page is split into Chats, Channels, and Status tabs. Channel posts and
    status broadcasts previously showed up mixed into the same list as regular conversations. The new
    Channels tab lists the channels you're subscribed to, with a read-only view of their posts; it is
    available on the whatsapp-web.js engine. The Status tab keeps broadcast updates separate from
    one-on-one and group chats, so the main Chats list holds only actual conversations.

Fixed

  • Redis cache now recovers from an outage instead of dying permanently. When Redis restarted — or
    was unreachable at startup and came back later — the cache client gave up reconnecting after a few
    attempts and was never re-established, so caching stayed off until the entire gateway was restarted.
    The client now reconnects for as long as it takes (bounded backoff) and self-heals the moment Redis
    returns, and a cache operation attempted while disconnected fails fast to the source of truth rather
    than stalling the request. Caching remains best-effort throughout, so an outage only removes the
    speedup — never correctness — and is no longer a latent, restart-only failure.

  • Session scoping on the audit-log and webhook delivery-failure list endpoints. GET /api/audit
    and GET /api/webhooks/delivery-failures now scope their results to the calling key's allowed
    sessions, matching the rest of the API (GET /webhooks, GET /search). These two endpoints take
    sessionId as a query parameter, which the API-key session fence — resolved only from route
    params — did not cover, so a key restricted to a subset of sessions saw rows for every session
    (and GET /api/audit with no sessionId returned every session's rows). A query sessionId may
    now only narrow within the key's allowed sessions; unrestricted keys are unaffected. A structural
    test now fails the build if any handler accepts a sessionId query param without scoping to the
    calling key, so the gap cannot reappear.

  • Chat list unread badge shape and overflow. The unread-count badge in the chats sidebar rendered as an uneven oval and grew without bound as the count climbed. It now uses a fixed height with border-box sizing so a single digit is a true circle and larger counts form a rounded pill, and its label is capped at 99+. The badge also exposes the exact unread count to assistive technology and as a hover tooltip.