Commit Graph

420 Commits

Author SHA1 Message Date
Peter Steinberger
7418400c47 perf(test): speed up nostr profile fuzz 2026-02-14 20:12:26 +00:00
Peter Steinberger
5e496a1519 perf(test): mock lobster subprocess 2026-02-14 20:12:26 +00:00
Peter Steinberger
185792b6cd chore(deps): update dependencies 2026-02-14 21:10:20 +01:00
Peter Steinberger
743f4b2849 fix(security): harden BlueBubbles webhook auth behind proxies 2026-02-14 19:47:51 +01:00
Peter Steinberger
d0f64c955e refactor(tlon): centralize Urbit request helpers 2026-02-14 19:22:29 +01:00
Christian Klotz
df7464ddf6 fix(bluebubbles): include sender identity in group chat envelopes (#16326)
* fix(bluebubbles): include sender identity in group chat envelopes

Use formatInboundEnvelope (matching iMessage/Signal pattern) so group
messages show the group label in the envelope header and include the
sender name in the message body. ConversationLabel now resolves to the
group name for groups instead of being undefined.

Fixes #16210

Co-authored-by: zerone0x <hi@trine.dev>

* fix(bluebubbles): use finalizeInboundContext and set BodyForAgent to raw text

Wrap ctxPayload with finalizeInboundContext (matching iMessage/Signal/
every other channel) so field normalization, ChatType, ConversationLabel
fallback, and MediaType alignment are applied consistently.

Change BodyForAgent from the envelope-formatted body to rawBody so the
agent prompt receives clean message text instead of the [BlueBubbles ...]
envelope wrapper.

Co-authored-by: zerone0x <hi@trine.dev>

* docs: add changelog entry for BlueBubbles group sender fix (#16326)

* fix(bluebubbles): include id in fromLabel matching formatInboundFromLabel

Align fromLabel output with the shared formatInboundFromLabel pattern:
groups get 'GroupName id:peerId', DMs get 'Name id:senderId' when the
name differs from the id. Addresses PR review feedback.

Co-authored-by: zerone0x <hi@trine.dev>

---------

Co-authored-by: zerone0x <hi@trine.dev>
2026-02-14 18:17:26 +00:00
Peter Steinberger
f47584fec8 refactor(voice-call): centralize Telnyx webhook verification 2026-02-14 19:02:10 +01:00
Mariano
71f357d949 bluebubbles: harden local media path handling against LFI (#16322)
* bluebubbles: harden local media path handling

* bluebubbles: remove racy post-open symlink lstat

* fix: bluebubbles mediaLocalRoots docs + typing fix (#16322) (thanks @mbelinky)
2026-02-14 17:43:44 +00:00
Peter Steinberger
bfa7d21e99 fix(security): harden tlon Urbit requests against SSRF 2026-02-14 18:42:10 +01:00
Robby
8e5689a84d feat(telegram): add sendPoll support (#16193) (#16209)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: b58492cfed
Co-authored-by: robbyczgw-cla <239660374+robbyczgw-cla@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
2026-02-14 18:34:30 +01:00
Peter Steinberger
29b587e73c fix(voice-call): fail closed when Telnyx webhook public key missing 2026-02-14 18:17:20 +01:00
Peter Steinberger
ff11d8793b fix(voice-call): require Twilio signature in ngrok loopback mode 2026-02-14 18:14:59 +01:00
Peter Steinberger
188c4cd076 fix(security): reject ambiguous webhook target matches 2026-02-14 17:28:28 +01:00
Peter Steinberger
61d59a8028 fix(googlechat): reject ambiguous webhook routing 2026-02-14 17:11:55 +01:00
Peter Steinberger
3e0e78f82a fix(nostr): guard profile mutations 2026-02-14 16:51:04 +01:00
Peter Steinberger
5b4121d601 fix: harden Feishu media URL fetching (#16285) (thanks @mbelinky)
Security fix for Feishu extension media fetching.
2026-02-14 16:42:35 +01:00
Peter Steinberger
c8424bf29a fix(googlechat): deprecate users/<email> allowlists (#16243) 2026-02-14 15:31:26 +01:00
Tanwa Arpornthip
c76288bdf1 fix(slack): download all files in multi-image messages (#15447)
* fix(slack): download all files in multi-image messages

resolveSlackMedia() previously returned after downloading the first
file, causing multi-image Slack messages to lose all but the first
attachment. This changes the function to collect all successfully
downloaded files into an array, matching the pattern already used by
Telegram, Line, Discord, and iMessage adapters.

The prepare handler now populates MediaPaths, MediaUrls, and
MediaTypes arrays so downstream media processing (vision, sandbox
staging, media notes) works correctly with multiple attachments.

Fixes #11892, #7536

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(slack): preserve MediaTypes index alignment with MediaPaths/MediaUrls

The filter(Boolean) on MediaTypes removed entries with undefined contentType,
shrinking the array and breaking index correlation with MediaPaths and MediaUrls.
Downstream code (media-note.ts, attachments.ts) requires these arrays to have
equal lengths for correct per-attachment MIME type lookup. Replace filter(Boolean)
with a nullish coalescing fallback to "application/octet-stream".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(slack): align MediaType fallback and tests (#15447) (thanks @CommanderCrowCode)

* fix: unblock plugin-sdk account-id typing (#15447)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-14 14:16:02 +01:00
Peter Steinberger
ef70a55b7a refactor(reply): clarify explicit reply tags in off mode (#16189)
* refactor(reply): clarify explicit reply tags in off mode

* fix(plugin-sdk): alias account-id subpath for extensions
2026-02-14 14:15:37 +01:00
Peter Steinberger
6543ce717c perf(test): avoid plugin-sdk barrel imports 2026-02-14 12:42:19 +00:00
Artale
3a330e681b fix(feishu): remove typing indicator on NO_REPLY cleanup (openclaw#15508) thanks @arosstale
Verified:
- pnpm build
- pnpm check
- pnpm test

Co-authored-by: arosstale <117890364+arosstale@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-02-14 05:24:27 -06:00
Pejman Pour-Moezzi
c17a109daa fix: align extension plugin and docs with new replyToMode default
Update the Telegram extension channel plugin fallback and documentation
to reflect the new "off" default, as flagged by Greptile review.
2026-02-13 23:31:17 -08:00
Peter Steinberger
db72184de6 perf(test): speed up Matrix send tests 2026-02-14 05:25:40 +00:00
Tyler Yust
45e12d2388 bluebubbles: gracefully handle disabled private API with action/tool filtering and fallbacks (#16002)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 243cc0cc9a
Co-authored-by: tyler6204 <243?+tyler6204@users.noreply.github.com>
Co-authored-by: tyler6204 <64381258+tyler6204@users.noreply.github.com>
Reviewed-by: @tyler6204
2026-02-13 21:15:56 -08:00
Peter Steinberger
e6d5b5fb11 perf(test): remove slow port inspection and reconnect sleeps 2026-02-14 04:57:28 +00:00
Peter Steinberger
89574f30cb refactor(voice-call): split manager into facade and context slices 2026-02-14 03:39:33 +01:00
Peter Steinberger
edbd86074f refactor(mattermost): extract websocket monitor and reconnect policies 2026-02-14 03:39:19 +01:00
Peter Steinberger
6ebf503fa8 refactor(media): centralize voice compatibility policy 2026-02-14 03:17:40 +01:00
Marcus Castro
2b154e0458 fix(mattermost): add WebSocket reconnection with exponential backoff (#14962)
* fix(mattermost): add WebSocket reconnection with exponential backoff

Fixes #13980

The Mattermost WebSocket monitor had no error handling around the
reconnection loop. When connectOnce() threw (e.g. 'fetch failed' from
network issues), the error propagated through the while loop, causing
the gateway to log 'channel exited' and never restart.

Extract runWithReconnect() utility that:
- Catches thrown errors from connectFn and retries
- Uses exponential backoff (2s→4s→8s→...→60s cap)
- Resets backoff after successful connections
- Stops cleanly on abort signal
- Reports errors and reconnect delays via callbacks

* fix(mattermost): make backoff sleep abort-aware and reject on WS connect failure

* fix(mattermost): clean up abort listener on normal timeout to prevent leak

* fix(mattermost): skip error reporting when abort causes connection rejection

* fix(mattermost): use try/finally for abort listener cleanup in connectOnce

* fix: force-close WebSocket on error to prevent reconnect hang

* fix: use ws.terminate() on abort for reliable teardown during CONNECTING state

* fix(mattermost): use initial retry delay for reconnect backoff

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-14 03:10:22 +01:00
David Cantú Martínez
9443c638f4 voice-call: hang up rejected inbounds, idempotency and logging (#15892)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 36f826ea23
Co-authored-by: dcantu96 <32658690+dcantu96@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
2026-02-14 03:09:31 +01:00
Azade 🐐
1b95220a99 fix(media): recognize MP3 and M4A as voice-compatible audio (#15438)
* fix(media): recognize MP3 and M4A as voice-compatible audio

Telegram sendVoice supports OGG/Opus, MP3, and M4A, but
isVoiceCompatibleAudio only recognized OGG/Opus formats.

- Add MP3 and M4A extensions and MIME types
- Use explicit MIME set instead of substring matching
- Handle MIME parameters (e.g. 'audio/ogg; codecs=opus')
- Add test coverage for all supported and unsupported formats

* fix: narrow MIME allowlist per review feedback

Remove audio/mp4 and audio/aac from voice MIME types — too broad.
Keep only M4A-specific types (audio/x-m4a, audio/m4a).
Add audio/mp4 and audio/aac as negative test cases.

* fix: align voice compatibility and channel coverage (#15438) (thanks @azade-c)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-14 03:03:02 +01:00
Peter Steinberger
51296e770c feat(slack): land thread-ownership from @DarlingtonDeveloper (#15775)
Land PR #15775 by @DarlingtonDeveloper:
- add thread-ownership plugin and Slack message_sending hook wiring
- include regression tests and changelog update

Co-authored-by: Mike <108890394+DarlingtonDeveloper@users.noreply.github.com>
2026-02-13 23:37:05 +00:00
Peter Steinberger
93dd51bce0 perf(matrix): lazy-load music-metadata parsing 2026-02-13 21:23:50 +00:00
Peter Steinberger
2b685b08c2 fix: harden matrix multi-account routing (#7286) (thanks @emonty) 2026-02-13 20:39:58 +01:00
Monty Taylor
a76ac1344e fix: resolveAllowFrom uses cfg+accountId params, not account 2026-02-13 20:39:58 +01:00
Monty Taylor
1a17466a60 fix: use account-aware config paths in resolveDmPolicy and resolveAllowFrom 2026-02-13 20:39:58 +01:00
Monty Taylor
3985ef7b37 fix: merge top-level config into per-account config so inherited settings apply 2026-02-13 20:39:58 +01:00
Monty Taylor
ed5a8dff8a chore: fix CHANGELOG.md formatting 2026-02-13 20:39:58 +01:00
Monty Taylor
da00f6cf8e fix: deep-merge nested config, prefer default account in send fallback, simplify credential filenames 2026-02-13 20:39:58 +01:00
Monty Taylor
1a72902991 refactor: read accounts from cfg.channels.matrix.accounts directly for clarity 2026-02-13 20:39:58 +01:00
Monty Taylor
bf4e348440 fix: de-duplicate normalized account IDs and add case-insensitive config lookup to send/client 2026-02-13 20:39:58 +01:00
Monty Taylor
a6dd50fede fix: normalize account config keys for case-insensitive matching 2026-02-13 20:39:58 +01:00
Monty Taylor
c89b8d99fc fix: normalize accountId in active-client and send/client for consistent keying 2026-02-13 20:39:58 +01:00
Monty Taylor
caf5d2dd7c feat(matrix): Add multi-account support to Matrix channel
The Matrix channel previously hardcoded `listMatrixAccountIds` to always
return only `DEFAULT_ACCOUNT_ID`, ignoring any accounts configured in
`channels.matrix.accounts`. This prevented running multiple Matrix bot
accounts simultaneously.

Changes:
- Update `listMatrixAccountIds` to read from `channels.matrix.accounts`
  config, falling back to `DEFAULT_ACCOUNT_ID` for legacy single-account
  configurations
- Add `resolveMatrixConfigForAccount` to resolve config for a specific
  account ID, merging account-specific values with top-level defaults
- Update `resolveMatrixAccount` to use account-specific config when
  available
- The multi-account config structure (channels.matrix.accounts) was not
  defined in the MatrixConfig type, causing TypeScript to not recognize
  the field. Added the accounts field to properly type the multi-account
  configuration.
- Add stopSharedClientForAccount() to stop only the specific account's
  client instead of all clients when an account shuts down
- Wrap dynamic import in try/finally to prevent startup mutex deadlock
  if the import fails
- Pass accountId to resolveSharedMatrixClient(), resolveMatrixAuth(),
  and createMatrixClient() to ensure the correct account's credentials
  are used for outbound messages
- Add accountId parameter to resolveMediaMaxBytes to check account-specific
  config before falling back to top-level config
- Maintain backward compatibility with existing single-account setups

This follows the same pattern already used by the WhatsApp channel for
multi-account support.

Fixes #3165
Fixes #3085

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 20:39:58 +01:00
Peter Steinberger
f02247b6c5 fix(ci): fix discord proxy websocket binding and bluebubbles timeout status 2026-02-13 19:35:55 +00:00
Mariano
7f0489e473 Security/Browser: constrain trace and download output paths to OpenClaw temp roots (#15652)
* Browser/Security: constrain trace and download output paths to temp roots

* Changelog: remove advisory ID from pre-public security note

* Browser/Security: constrain trace and download output paths to temp roots

* Changelog: remove advisory ID from pre-public security note

* test(bluebubbles): align timeout status expectation to 408

* test(discord): remove unused race-condition counter in threading test

* test(bluebubbles): align timeout status expectation to 408
2026-02-13 19:24:33 +00:00
Peter Steinberger
a1df0939db refactor(bluebubbles): split monitor parsing and processing modules 2026-02-13 19:08:37 +00:00
Peter Steinberger
a750a195e5 refactor(extensions): extract feishu dedup and mattermost onchar helpers 2026-02-13 19:08:37 +00:00
Peter Steinberger
3cbcba10cf fix(security): enforce bounded webhook body handling 2026-02-13 19:14:54 +01:00
Peter Steinberger
201ac2b72a perf: replace proper-lockfile with lightweight file locks 2026-02-13 17:57:30 +00:00