-
Notifications
You must be signed in to change notification settings - Fork 66
feat: After user sign out all other tabs will disconnect #662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: After user sign out all other tabs will disconnect #662
Conversation
|
Thank you for the contribution @moutikabdessabour This is great work and definitely something I wanted to add. I'd like to make it a little more generic, however. Do you think we can make the code that works with the def success(conn, # ...
conn
|> # ...
|> set_live_socket_id(user)
# ...
end
def sign_out(conn, # ...
conn
|> # ...
|> disconnect_sessions(user)
endThat way we can add a new Also, do we need to test it? |
|
@jimsynz its a good point that we should do this on |
|
Oh good point. I think we need to go back and revisit the log out everywhere add on because we should provide a plug helper that triggers it so that folks can opt into it (for example a "log me out everywhere" checkbox on their logout screen). |
|
Oh, wait, if we use the JTI to generate the |
|
I think it should be done on the We would also need to provide an option to specify the endpoint where the reconnect notification will be sent. Also maybe we want to extend this to if the token expires and the user still has a websocket connection open, i.e he didn't explicitly logout. I have sth that resembles a PoC for this, using notifiers [as james proposed] but I still need to generalize it + the livesocket_id template thing. Acutally we don't even need to change the generator with this method because revoke_token and revoke_jti would trigger the notifier. |
We also need to be able to support multiple endpoints, so a
I agree. To manage this we may want to extend the expunger genserver to keep track of any JTI's expiring "soon" and publish disconnects for them at the appropriate time. |
|
this is the notifier I implemented after merging #666 this would actually trigger the disconnect the user [:revoke_token, :revoke_jti, :revoke_all_stored_by_subject] defmodule TokenRevokationNotifier do
use Ash.Notifier
require Logger
def notify(%Ash.Notifier.Notification{
changeset: %{attributes: "user"}
}),
do: :ok
def notify(%Ash.Notifier.Notification{
changeset: %{data: %{subject: "user"}}
}),
do: :ok
# data = notification.changeset.data
def notify(%Ash.Notifier.Notification{
changeset: %{
attributes: %{purpose: "revocation", jti: _} = data,
context: %{changed?: true}
}
}),
do: notify_all(data)
def notify(%Ash.Notifier.Notification{
changeset: %{
attributes: %{purpose: "revocation"},
data: data,
context: %{changed?: true}
}
}),
do: notify_all(data)
def notify(%Ash.Notifier.Notification{
changeset: %{data: %{purpose: "revocation"} = data, context: %{changed?: true}}
}),
do: notify_all(data)
defp notify_all(%{jti: jti} = data) do
TaleedWeb.Endpoint.broadcast("users_socket:#{jti}", "disconnect", %{})
end
def notify(n) do
:noop
end
end |
This is generated code right? So they can modify it as needed. |
|
I think with the notifier we don't even need to expose this as generated code, basically they can set it on the Dsl |
b80e928 to
99a0262
Compare
Implementation:
|
| {:ok, template_fn} <- | ||
| Info.token_live_socket_id_template(token_resource) do | ||
| conn | ||
| |> Plug.Conn.put_session(:live_socket_id, template_fn.(claims)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to handle failure here? We're not verifying the function, it's arity or the return value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should return the Plug.Conn, this is why I added the else. but are you speaking about whether the error path will ever be hit, it would happen because there is no default live_socket_id_template.
I think if I will need to modify the AshAuthentication.TokenResource.Transformer.transform if I want to set one by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right but what if a user provides a function that raises an exception or has the wrong arity or returns a nonsense value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could specify that the function should return a tuple, but this still doesn't solve the default value issue.
But if the user like on purpose returns the same livesocket I'd for all users then that's not our issue. As it will just reconnect the websockets [the token would still be valid] so it will pass through
Modified the igniter generated
auth_controller.exto auto disconnect user once he logs out