diff --git a/app/controllers/qr_codes_controller.rb b/app/controllers/qr_codes_controller.rb new file mode 100644 index 000000000..707166930 --- /dev/null +++ b/app/controllers/qr_codes_controller.rb @@ -0,0 +1,11 @@ +class QrCodesController < ApplicationController + allow_unauthenticated_access + + def show + qr_code_link = QrCodeLink.from_signed(params[:id]) + svg = RQRCode::QRCode.new(qr_code_link.url).as_svg(viewbox: true, fill: :white, color: :black) + + expires_in 1.year, public: true + render plain: svg, content_type: "image/svg+xml" + end +end diff --git a/app/controllers/sessions/transfers_controller.rb b/app/controllers/sessions/transfers_controller.rb new file mode 100644 index 000000000..d30c263b6 --- /dev/null +++ b/app/controllers/sessions/transfers_controller.rb @@ -0,0 +1,15 @@ +class Sessions::TransfersController < ApplicationController + require_unauthenticated_access + + def show + end + + def update + if user = User.active.find_by_transfer_id(params[:id]) + start_new_session_for user + redirect_to root_path + else + head :bad_request + end + end +end diff --git a/app/helpers/forms_helper.rb b/app/helpers/forms_helper.rb new file mode 100644 index 000000000..3220d2d78 --- /dev/null +++ b/app/helpers/forms_helper.rb @@ -0,0 +1,8 @@ +module FormsHelper + def auto_submit_form_with(**attributes, &) + data = attributes.delete(:data) || {} + data[:controller] = "auto-submit #{data[:controller]}".strip + + form_with **attributes, data: data, & + end +end diff --git a/app/helpers/qr_codes_helper.rb b/app/helpers/qr_codes_helper.rb new file mode 100644 index 000000000..64bf243a2 --- /dev/null +++ b/app/helpers/qr_codes_helper.rb @@ -0,0 +1,6 @@ +module QrCodesHelper + def qr_code_image(url) + qr_code_link = QrCodeLink.new(url) + image_tag qr_code_path(qr_code_link.signed), class: "qr-code center", alt: "QR Code" + end +end diff --git a/app/models/qr_code_link.rb b/app/models/qr_code_link.rb new file mode 100644 index 000000000..81a65fa25 --- /dev/null +++ b/app/models/qr_code_link.rb @@ -0,0 +1,26 @@ +class QrCodeLink + attr_reader :url + + def initialize(url) + @url = url + end + + def signed + self.class.verifier.generate(@url, purpose: :qr_code) + end + + def self.from_signed(signed) + new verifier.verify(signed, purpose: :qr_code) + end + + private + class << self + def verifier + ActiveSupport::MessageVerifier.new(secret, url_safe: true) + end + + def secret + Rails.application.key_generator.generate_key("qr_codes") + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index bfa562008..02c20ef98 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,6 @@ class User < ApplicationRecord + include Transferable + belongs_to :account has_many :sessions, dependent: :destroy diff --git a/app/models/user/transferable.rb b/app/models/user/transferable.rb new file mode 100644 index 000000000..096913aab --- /dev/null +++ b/app/models/user/transferable.rb @@ -0,0 +1,15 @@ +module User::Transferable + extend ActiveSupport::Concern + + TRANSFER_LINK_EXPIRY_DURATION = 4.hours + + class_methods do + def find_by_transfer_id(id) + find_signed(id, purpose: :transfer) + end + end + + def transfer_id + signed_id(purpose: :transfer, expires_in: TRANSFER_LINK_EXPIRY_DURATION) + end +end diff --git a/app/views/accounts/users/index.html.erb b/app/views/accounts/users/index.html.erb index 5d93666d8..1980efb1f 100644 --- a/app/views/accounts/users/index.html.erb +++ b/app/views/accounts/users/index.html.erb @@ -13,11 +13,6 @@ <%= image_tag "bolt.svg", aria: { hidden: true }, size: 24 %> Workflows <% end %> - - <%= button_to session_path, method: :delete, class: "btn" do %> - <%= image_tag "logout.svg", aria: { hidden: true }, size: 24 %> - Sign out - <% end %> <% end %> diff --git a/app/views/sessions/transfers/show.html.erb b/app/views/sessions/transfers/show.html.erb new file mode 100644 index 000000000..897e39922 --- /dev/null +++ b/app/views/sessions/transfers/show.html.erb @@ -0,0 +1 @@ +<%= auto_submit_form_with method: :put %> diff --git a/app/views/users/_transfer.html.erb b/app/views/users/_transfer.html.erb new file mode 100644 index 000000000..314d8ff39 --- /dev/null +++ b/app/views/users/_transfer.html.erb @@ -0,0 +1,37 @@ +