I have an app where I broadcast some submissions for forms in the submission_controller, like this:
Formerer.Endpoint.broadcast("forms:#{form.id}", "new_submission", payload)
However, what I try to do now, is to make sure that only the current_user has access to the submissions broadcasted for its forms. (eg, current_user will have no way to see the submission for "forms:2" if form 2 belongs to another user).
I manage to do this in the channel join
action by filtering the forms only for the user id which I assigned to the channel in the connect action:
user = Repo.get(Formerer.User, socket.assigns.user_id)
But for the broadcast
I have no socket
available.
My questions:
Is there a way to find somehow the socket by the channel topic? something like:
%Phoenix.Socket{assigns: %{user_id: user_id}, topic: "forms:1"} = ALL_OPEN_SOCKETS?!
After that I could just see if user_id == submission.user_id
, and broadcast if true
- If that is not possible, what would be a best practice to do this, and to ensure only the current_user has access to their form submissions?
use the
intercept
api and create ahandle_out
function for the event. In thehandle_out
function you will have the socket. You can verify the user_id stored there. It its correct,push socket, event, message
, otherwise do nothing except{:ok, socket}
.Edit
Here is a code example:
Then you can just broadcast on the
new_submission
event anywhere and the socket will channel will take care of pushing the event out only three user defined in the payload.