From ab9f44835e6bf30da7614352e1ac79520fff6604 Mon Sep 17 00:00:00 2001 From: David Revelo Date: Sun, 7 Aug 2022 13:51:34 +0200 Subject: [PATCH 1/4] Use controller set on devise config as the base controller for the engine --- app/controllers/graphql_devise/application_controller.rb | 5 +---- spec/dummy/app/controllers/application_controller.rb | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/controllers/graphql_devise/application_controller.rb b/app/controllers/graphql_devise/application_controller.rb index 2c9a3722..ade745e1 100644 --- a/app/controllers/graphql_devise/application_controller.rb +++ b/app/controllers/graphql_devise/application_controller.rb @@ -1,9 +1,6 @@ # frozen_string_literal: true module GraphqlDevise - ApplicationController = if Rails::VERSION::MAJOR >= 5 - Class.new(ActionController::API) - else - Class.new(ActionController::Base) + class ApplicationController < Devise.parent_controller.constantize end end diff --git a/spec/dummy/app/controllers/application_controller.rb b/spec/dummy/app/controllers/application_controller.rb index 280cc28c..0e622da7 100644 --- a/spec/dummy/app/controllers/application_controller.rb +++ b/spec/dummy/app/controllers/application_controller.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class ApplicationController < ActionController::Base - protect_from_forgery with: :exception + protect_from_forgery with: :null_session end From 5440bc286291be535628a3b1c9b458401178e9c4 Mon Sep 17 00:00:00 2001 From: David Revelo Date: Sun, 7 Aug 2022 13:52:17 +0200 Subject: [PATCH 2/4] Fix DTA cookies not set when app configured for it --- lib/graphql_devise/mutations/login.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/graphql_devise/mutations/login.rb b/lib/graphql_devise/mutations/login.rb index 9d35f79f..0df4a681 100644 --- a/lib/graphql_devise/mutations/login.rb +++ b/lib/graphql_devise/mutations/login.rb @@ -21,6 +21,9 @@ def resolve(email:, password:) new_headers = set_auth_headers(resource) controller.sign_in(:user, resource, store: false, bypass: false) + controller.resource = resource + controller.token.client = new_headers['client'] + controller.token.token = new_headers['access-token'] yield resource if block_given? From 88bf71c015f6826b66c34c5094a209dff09d07fa Mon Sep 17 00:00:00 2001 From: David Revelo Date: Tue, 9 Aug 2022 08:46:22 +0200 Subject: [PATCH 3/4] Support DTA's legacy token strategy --- .../concerns/additional_controller_methods.rb | 2 +- lib/graphql_devise/concerns/controller_methods.rb | 15 +++++++++++++-- .../mutations/confirm_registration_with_token.rb | 2 +- lib/graphql_devise/mutations/login.rb | 5 +---- lib/graphql_devise/mutations/register.rb | 2 +- .../mutations/update_password_with_token.rb | 2 +- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/graphql_devise/concerns/additional_controller_methods.rb b/lib/graphql_devise/concerns/additional_controller_methods.rb index 4e9e51e8..837aacb0 100644 --- a/lib/graphql_devise/concerns/additional_controller_methods.rb +++ b/lib/graphql_devise/concerns/additional_controller_methods.rb @@ -37,7 +37,7 @@ def set_resource_by_token(resource) def build_redirect_headers(access_token, client, redirect_header_options = {}) { - DeviseTokenAuth.headers_names[:"access-token"] => access_token, + DeviseTokenAuth.headers_names[:'access-token'] => access_token, DeviseTokenAuth.headers_names[:client] => client, :config => params[:config], :client_id => client, diff --git a/lib/graphql_devise/concerns/controller_methods.rb b/lib/graphql_devise/concerns/controller_methods.rb index cc3335c4..d79636c5 100644 --- a/lib/graphql_devise/concerns/controller_methods.rb +++ b/lib/graphql_devise/concerns/controller_methods.rb @@ -66,9 +66,20 @@ def client end end - def set_auth_headers(resource) + def generate_auth_headers(resource) auth_headers = resource.create_new_auth_token - response.headers.merge!(auth_headers) + controller.resource = resource + access_token_name = DeviseTokenAuth.headers_names[:'access-token'] + client_name = DeviseTokenAuth.headers_names[:'client'] + + # NOTE: Depending on the DTA version, the token will be an object or nil + if controller.token + controller.token.client = auth_headers[client_name] + controller.token.token = auth_headers[access_token_name] + else + controller.client_id = auth_headers[client_name] + controller.token = auth_headers[access_token_name] + end auth_headers end diff --git a/lib/graphql_devise/mutations/confirm_registration_with_token.rb b/lib/graphql_devise/mutations/confirm_registration_with_token.rb index 16f32934..cd587f67 100644 --- a/lib/graphql_devise/mutations/confirm_registration_with_token.rb +++ b/lib/graphql_devise/mutations/confirm_registration_with_token.rb @@ -18,7 +18,7 @@ def resolve(confirmation_token:) response_payload = { authenticatable: resource } - response_payload[:credentials] = set_auth_headers(resource) if resource.active_for_authentication? + response_payload[:credentials] = generate_auth_headers(resource) if resource.active_for_authentication? response_payload else diff --git a/lib/graphql_devise/mutations/login.rb b/lib/graphql_devise/mutations/login.rb index 0df4a681..78e6eb13 100644 --- a/lib/graphql_devise/mutations/login.rb +++ b/lib/graphql_devise/mutations/login.rb @@ -19,11 +19,8 @@ def resolve(email:, password:) raise_user_error(I18n.t('graphql_devise.sessions.bad_credentials')) end - new_headers = set_auth_headers(resource) + new_headers = generate_auth_headers(resource) controller.sign_in(:user, resource, store: false, bypass: false) - controller.resource = resource - controller.token.client = new_headers['client'] - controller.token.token = new_headers['access-token'] yield resource if block_given? diff --git a/lib/graphql_devise/mutations/register.rb b/lib/graphql_devise/mutations/register.rb index c021689b..bc353d79 100644 --- a/lib/graphql_devise/mutations/register.rb +++ b/lib/graphql_devise/mutations/register.rb @@ -38,7 +38,7 @@ def resolve(confirm_url: nil, **attrs) response_payload = { authenticatable: resource } - response_payload[:credentials] = set_auth_headers(resource) if resource.active_for_authentication? + response_payload[:credentials] = generate_auth_headers(resource) if resource.active_for_authentication? response_payload else diff --git a/lib/graphql_devise/mutations/update_password_with_token.rb b/lib/graphql_devise/mutations/update_password_with_token.rb index 02f8dc60..ad67ddf5 100644 --- a/lib/graphql_devise/mutations/update_password_with_token.rb +++ b/lib/graphql_devise/mutations/update_password_with_token.rb @@ -23,7 +23,7 @@ def resolve(reset_password_token:, **attrs) yield resource if block_given? response_payload = { authenticatable: resource } - response_payload[:credentials] = set_auth_headers(resource) if controller.signed_in?(resource_name) + response_payload[:credentials] = generate_auth_headers(resource) if controller.signed_in?(resource_name) response_payload else From 1e434c11d1563df1fae7732eb4257352aa14adc4 Mon Sep 17 00:00:00 2001 From: David Revelo Date: Sat, 13 Aug 2022 09:08:57 +0200 Subject: [PATCH 4/4] Add spec for cookie setting --- .../graphql_devise/application_controller.rb | 5 ++- .../controllers/api/v1/graphql_controller.rb | 1 + .../app/controllers/application_controller.rb | 2 +- spec/requests/mutations/login_spec.rb | 34 +++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/app/controllers/graphql_devise/application_controller.rb b/app/controllers/graphql_devise/application_controller.rb index ade745e1..2c9a3722 100644 --- a/app/controllers/graphql_devise/application_controller.rb +++ b/app/controllers/graphql_devise/application_controller.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true module GraphqlDevise - class ApplicationController < Devise.parent_controller.constantize + ApplicationController = if Rails::VERSION::MAJOR >= 5 + Class.new(ActionController::API) + else + Class.new(ActionController::Base) end end diff --git a/spec/dummy/app/controllers/api/v1/graphql_controller.rb b/spec/dummy/app/controllers/api/v1/graphql_controller.rb index b64911d0..29ea9111 100644 --- a/spec/dummy/app/controllers/api/v1/graphql_controller.rb +++ b/spec/dummy/app/controllers/api/v1/graphql_controller.rb @@ -4,6 +4,7 @@ module Api module V1 class GraphqlController < ApplicationController include GraphqlDevise::SetUserByToken + include ActionController::Cookies def graphql result = DummySchema.execute(params[:query], **execute_params(params)) diff --git a/spec/dummy/app/controllers/application_controller.rb b/spec/dummy/app/controllers/application_controller.rb index 0e622da7..280cc28c 100644 --- a/spec/dummy/app/controllers/application_controller.rb +++ b/spec/dummy/app/controllers/application_controller.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class ApplicationController < ActionController::Base - protect_from_forgery with: :null_session + protect_from_forgery with: :exception end diff --git a/spec/requests/mutations/login_spec.rb b/spec/requests/mutations/login_spec.rb index 5bf04c1a..a323e86a 100644 --- a/spec/requests/mutations/login_spec.rb +++ b/spec/requests/mutations/login_spec.rb @@ -184,4 +184,38 @@ ) end end + + + if DeviseTokenAuth.respond_to?(:cookie_enabled) + context 'when using cookies for auth' do + let!(:user) { create(:user, :confirmed, password: password, email: 'vvega@wallaceinc.com') } + let(:email) { user.email } + let(:query) do + <<-GRAPHQL + mutation { + userLogin( + email: "#{email}", + password: "#{password}" + ) { + authenticatable { email } + credentials { accessToken uid tokenType client expiry } + } + } + GRAPHQL + end + + around do |example| + DeviseTokenAuth.cookie_enabled = true + example.run + DeviseTokenAuth.cookie_enabled = false + end + + before { post_request('/api/v1/graphql') } + + it 'honors DTA configuration of setting auth info in cookies' do + cookie = cookies.get_cookie('auth_cookie') + expect(JSON.parse(cookie.value).keys).to include(*%w[uid access-token client]) + end + end + end end