29 Commits

Author SHA1 Message Date
Andrey Antukh
8f91f7cd4e ✨ Negotiate transit/JSON payload format on SSE and WebSocket
SSE endpoints always encoded event payloads in transit, ignoring
request content negotiation. WebSocket notifications always used
transit as well, with no way to request plain JSON.

Extract the response format negotiation (Accept header and _fmt
query param) into the shared app.http.content-negotiation helper
and reuse it from the response formatting middleware, the SSE
response builder and the WebSocket notifications endpoint. The
_fmt=json parameter takes precedence over Accept, transit stays
the default, and unknown formats fall back to transit.

SSE event payloads are now encoded as transit (default) or plain
JSON depending on the request, while the text/event-stream
transport remains unchanged. The WebSocket format is negotiated
once on the upgrade request and applies bidirectionally: outbound
notification messages use the negotiated encoder and inbound
client messages the matching decoder, with a normalization step
converting JSON messages (:type to keyword, entity ids to UUID)
into the same shape produced by transit.

The generic websocket listener now accepts encode/decode functions
as options (defaulting to the historical transit codecs) and
exposes the resolved options in the handler metadata under
::options for testing and introspection. The notifications
http-handler is now public so tests can cover the wiring.

On the frontend, stream requests accept a :response-format :json
option that switches the Accept header and decodes each event
with the plain JSON decoder.

Add unit tests for negotiate-format, SSE response encoding and
the WebSocket codec wiring (JSON via Accept header or _fmt param,
transit default for unsignaled requests).

Closes #11409

AI-assisted-by: glm-5.3-flash
AI-assisted-by: muse-spark-1.3-contributor
2026-11-12 09:11:38 +00:00
Andrey Antukh
b2c3fd872a
♻️ Scope organization notifications to specific WebSocket topics (#11460)
* ♻️ Scope organization notifications to specific WebSocket topics

Publish team/org notifications to team-id and organization-id topics
instead of broadcasting to all connections via uuid/zero. Dashboard and
workspace now subscribe to their current team and organization on
initialization, receiving only relevant events.

Backend: added subscribe-organization/unsubscribe-organization WebSocket
handlers and updated :close to clean up organization subscriptions.
Modified notify-team-change, notify-organization-deletion, and
notify-organization-change-sso to publish to specific topics.

Frontend: dashboard and workspace now subscribe to team-id and
organization-id (when applicable) on initialization, with nil-guard
in topic filters.

Closes #11455

AI-assisted-by: longcat-2.0

* 🔧 Remove unused session-id binding in unsubscribe-organization

Clj-kondo lint fix.

AI-assisted-by: longcat-2.0

* 🐛 Fix permission check on team ws connection

---------

Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
2026-10-01 13:16:12 +02:00
Andrey Antukh
d9e28fb1a4
🐛 Add authorization checks to WebSocket subscriptions (#11069)
Subscribe-file and subscribe-team handlers now verify the requesting
profile has read permissions on the target resource before creating
a subscription. Pointer-update handler now validates that the message
file-id matches the subscribed file-id before publishing.

Closes #11067

AI-assisted-by: mimo-v2.5-pro
2026-09-22 11:16:14 +02:00
Andrey Antukh
81c3b3cd56
📎 Update copyright name on file header (#11346) 2026-08-25 11:55:10 +02:00
Andrey Antukh
399b00b86d
🐛 Add permission checks to WebSocket subscription handlers (#11054)
* 🐛 Add permission checks to WebSocket subscription handlers

Check file and team read permissions before allowing WebSocket
subscriptions to prevent resource enumeration via presence
notifications.

AI-assisted-by: mimo-v2.5-pro

* 🐛 Fix random backend test failure
2026-08-07 11:24:24 +02:00
Yamila Moreno
ddba2ffa75
📎 Update Kaleidos Copyright (#9929) 2026-05-29 11:24:58 +02:00
Andrey Antukh
283eb0419c ♻️ Refactor time related namespaces
Mainly removes the custom app.util.time namespace
from frontend and backend and normalize all to use
the app.common.time namespace
2025-08-01 11:20:01 +02:00
Andrey Antukh
a209966427 🐛 Don't use schema uuid parsing function on websocket ns 2025-04-17 09:20:34 +02:00
Andrey Antukh
88fb5e7ab5 ♻️ Update integrant to latest version
This upgrade also includes complete elimination of use spec
from the backend codebase, completing the long running migration
to fully use malli for validation and decoding.
2024-11-13 19:09:19 +01:00
Andrey Antukh
97a1bf15ef ✨ Improve how topic is managed on ws notifications 2024-10-30 13:39:38 +01:00
Andrey Antukh
51ecbf15a9 ⬆️ Update yetti and http server dependency 2024-10-22 20:23:38 +02:00
Andrey Antukh
002b1679c3 ♻️ Clean assertion and schema chechking API 2024-10-08 15:30:33 +02:00
Andrey Antukh
9e94cf7b99 ♻️ Simplify internal implementation of sm/schema namespace 2024-09-13 11:30:55 +02:00
Andrey Antukh
b882b9e283 🔥 Remove usage of public usage of sm/define funcion 2024-09-13 11:30:55 +02:00
Andrey Antukh
87615ce221 💄 Fix format issues on backend module 2023-11-29 12:55:58 +01:00
Andrey Antukh
bb5a4c0fa5 ✨ Update yetti and adapt for ring-2.0 2023-11-27 14:25:12 +01:00
Andrey Antukh
e5dedb1e3d 🎉 Add push notifications support 2023-08-14 12:13:31 +02:00
Andrey Antukh
aafbf6bc15 ♻️ Refactor cocurrency model on backend
Mainly the followin changes:

- Pass majority of code to the old and plain synchronous style
  and start using virtual threads for the RPC (and partially some
  HTTP server middlewares).
- Make some improvements on how CLIMIT is handled, simplifying code
- Improve considerably performance reducing the reflection and
  unnecesary funcion calls on the whole stack-trace of an RPC call.
- Improve efficiency reducing considerably the total threads number.
2023-03-14 12:30:27 +01:00
Andrey Antukh
2e717882f1 ♻️ Refactor websockets impl to use virtual threads
Removing the use of core.async code and implement code using
plain old and familiar synchronous code
2023-03-14 12:30:27 +01:00
Andrey Antukh
db689d151e ♻️ Refactor profile and session handling
- makes the profile access more efficient (replace in-app joins to a
  simple select query on profile table
- add partial support for access-tokens (still missing some RPC methods)
- move router definitions to specific modules and simplify the main http
  module definitions to simple includes
- simplifiy authentication code related to access-tokens and sessions
- normalize db parameters with proper namespaced props
- more work on convert all modules initialization to use proper specs
  with fully-qualified keyword config props
2023-01-18 10:51:58 +01:00
Andrey Antukh
8fae7f7aa6 ♻️ Refactor internal websocket connection stage management 2022-10-03 13:40:33 +02:00
Andrey Antukh
41134f22e9 📎 Update license header 2022-09-20 23:23:22 +02:00
Andrey Antukh
a555e13b6a ✨ Improve msgbus internal API 2022-09-05 19:08:26 +02:00
Andrey Antukh
cbc5811290 ✨ Improve websockets impl
Make it more extensible and move all the websocket unrelated stuff
to the new hooks API. Also adds observability from repl.
2022-06-29 11:01:16 +02:00
Andrey Antukh
602b736163 📎 Update default scripts 2022-04-05 13:23:39 +02:00
Andrey Antukh
f60d8c6c96 ♻️ Refactor websockets subsystem (on backend)
- Refactor msgbus subsystem, simplifying many parts.
- Enable persistent websocket connection for the all session duration.
2022-03-22 11:34:32 +01:00
Andrey Antukh
7cf27ac86d ♻️ Refactor general resource and concurrency model on backend 2022-02-22 13:05:41 +01:00
Andrey Antukh
9ea90c3400 🐛 Fix unexpected exception on websockets. 2021-12-29 12:16:48 +01:00
Andrey Antukh
c394495a26 ♻️ Refactor websocket layer.
This commit replaces rj9a with funcool/yetti ring adapter.
Cleans the websocket api and makes it fully asynchronous.
Also a common websocket protocol abstraction that will allow
more easy path for creating new websocket based services.
2021-12-29 09:52:32 +01:00