- Grafana panel for webhook calls from App Suite Middleware fce845b
- Grafana panels for the socket registry prune pass 6c679b7
- Metrics for the socket registry prune pass 6e0779a
- Ignore unpatched braces advisory in UI audit 344506f
- Log expected auth failures and locked offline jobs at warn 6c97a5b
- Log per-connection and per-event lines with emails at debug dabf27f
- The unhandledRejection handler that couldn't keep pods alive 30bdf9e
- Allow configuring the database port in the Helm chart 0d3d85e
- Await the web push unsubscribe so a DB error can't stop the pod 97cd694
- Build the e2e image as nonroot so pnpm can install its own version 87e3c8d
- Build the e2e image with the e2e ignore file 07bf871
- Catch errors in all socket listeners ac7fcaf
- Catch failed Redis publishes from the Socket.IO adapter 1f8c7d4
- Count connected users without reading the whole list f316685
- Don't mark a user offline who reconnected before the job ran c2aaf72
- Generate VAPID keys without a running Switchboard pod a2f41c0
- Handle rejected offline-job removal on socket disconnect 587a007
- Keep connected users in a Set and clean up stale entries d48c072
- Keep stale users as prune candidates until their job ran 49fb3a7
- Keep the proxy URL out of the web push error log 2c1b3b2
- Load codeceptjs eslint plugin without FlatCompat 9b9ebde
- Log errors under err so type and stack are kept 3b7ab2e
- Prune the socket registry without flooding Redis pub/sub 2a1f34c
- Pull ox-common from appsuite-core-internal again 5f5af27
- Remove orphaned sockets only after two prune passes agree 0cb0367
- Skip web push on new mail when web push is disabled ea47615
- Stop logging JWT claims on failed token verification ec20523
- Stop the socket prune timers on shutdown 43b7ab6
- Time out web push sends after 5 seconds af8715e
- Wait for the Jitsi tab instead of a fixed 0.3s in e2e 392507a
- Dedicated ServiceAccount for switchboard (appsuite/support#1592)
- switchboard runs under its own ServiceAccount with no Kubernetes API token mounted, for CIS 5.1.5/5.1.6 compliance out of the box
- New serviceAccount.* and automountServiceAccountToken values
- Document PRESENCE_TTL_SECONDS and presence.ttlSeconds 4a4040b
- PodDisruptionBudget for switchboard (appsuite/support#1568)
- New pdb.* values render an optional PodDisruptionBudget for the switchboard pods (disabled by default)
- Presence.ttlSeconds chart value for PRESENCE_TTL_SECONDS 280bbe0
- Expose migrate Job TTL and annotations for Argo CD callers 574fddb
- Sign JWT sub as string; jose 6.2.12 rejects non-strings 2184dbe
- Trigger k6 load tests via k6-operator TestRun manifests bfbda76
- Prune socket registry against the cluster-wide socket set e77bdde
- Comprehensive documentation with VuePress ff10d9e
- Fake-webhook script to send signed push events for testing 031c56b
- Grafana panels for auth-error-by-reason and JWT verify latency 58c7cfb
- Grafana panels for per-pod socket metrics 0b8457f
- Informal language for de_DE e2b4338
- Opt-in migrate.triggerValue to preserve per-deploy rerun 511390b
- Reason label to switchboard_authentication_errors fa3563b
- Switchboard_jwt_verify_duration_seconds histogram 1b0a735
- Switchboard-specific Redis-state metrics and dashboard panels d97be17
- TLS support for mysql/mariadb connection a781c97
- Web push flow diagrams in docs 6b31a90
- Breaking change: Rename switchboard_authentication_errors to _total c54ae15
- Clarify switchboard_connected_users help text 249cff5
- Convert migrate Job to plain manifest with rotation suffix b34cc4f
- Stop logging raw JWTs and user-controlled socket payloads ffe21c3
- Bound Redis growth from offline-state queue and presence keys 1cad762
- Convert migrate Job to Helm hook for GitOps compatibility f138d0f
- Disable jwks by default 935acff
- Drop ky prefixUrl in webpush client so it works with ky v2 d48f107
- Promote chart-managed mysql Secret to pre-install/pre-upgrade hook cc577db
- Redact sensitive fields from webpush/webhook debug logs (support#1388)
- Web push click no longer opens login page in default browser a7fc52e