Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/channels/application_cable/channel.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
module ApplicationCable
class Channel < ActionCable::Channel::Base
# All current channels are public (Turbo::StreamsChannel for display pages).
# If an authenticated channel is added in the future, reject unauthorized
# connections in that channel's #subscribed method:
#
# def subscribed
# reject unless connection.current_shopkeeper
# end
end
end
21 changes: 21 additions & 0 deletions app/channels/application_cable/connection.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_shopkeeper, :current_account

def connect
self.current_shopkeeper = find_shopkeeper
self.current_account = find_account
end

private

def find_shopkeeper
env["warden"]&.user(:shopkeeper)
end

# Extract the account UUID from the WebSocket upgrade request path,
# matching how AccountMiddleware sets the current account for HTTP
# requests. Display page URLs (display/shops/...) don't include an
# account UUID, so this returns nil for public connections.
def find_account
_, account_id, = request.path.split("/", 3)
Account.find_by(id: account_id) if AccountMiddleware::UUID_MATCHER.match?(account_id)
end
end
end
1 change: 1 addition & 0 deletions app/views/display/shops/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<%# These streams are public by design — display pages are unauthenticated %>
<%= turbo_stream_from @shop, :tb_stream_full_reload_entire_page %>
<%= turbo_stream_from @shop, :tb_stream_update_item_tags %>

Expand Down
38 changes: 31 additions & 7 deletions test/channels/application_cable/connection_test.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
require "test_helper"

class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
# test "connects with cookies" do
# cookies.signed[:user_id] = 42
#
# connect
#
# assert_equal connection.user_id, "42"
# end
test "anonymous connection succeeds with nil shopkeeper and account" do
connect

assert_nil connection.current_shopkeeper
assert_nil connection.current_account
end

test "authenticated connection identifies shopkeeper and account" do
shopkeeper = shopkeepers(:one)
account = shopkeeper.create_default_account
warden = Minitest::Mock.new
warden.expect(:user, shopkeeper, [:shopkeeper])

connect "/#{account.id}/cable", env: {"warden" => warden}

assert_equal shopkeeper, connection.current_shopkeeper
assert_equal account, connection.current_account
warden.verify
end

test "connection without account UUID in path has nil account" do
shopkeeper = shopkeepers(:one)
warden = Minitest::Mock.new
warden.expect(:user, shopkeeper, [:shopkeeper])

connect "/cable", env: {"warden" => warden}

assert_equal shopkeeper, connection.current_shopkeeper
assert_nil connection.current_account
warden.verify
end
end