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
8 changes: 4 additions & 4 deletions app/graphql/graphql_devise/mutations/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ module Mutations
class Base < GraphQL::Schema::Mutation
private

def raise_user_error(message)
raise GraphqlDevise::UserError, message
end

def remove_resource
controller.resource = nil
controller.client_id = nil
controller.token = nil
end

def single_error_object(error)
{ success: false, errors: [error] }
end

def request
controller.request
end
Expand Down
11 changes: 4 additions & 7 deletions app/graphql/graphql_devise/mutations/login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ class Login < Base
argument :email, String, required: true
argument :password, String, required: true

field :success, Boolean, null: false
field :errors, [String], null: false

def resolve(email:, password:)
resource = resource_class.find_by(email: email)

if resource && active_for_authentication?(resource)
if invalid_for_authentication?(resource, password)
return single_error_object(I18n.t('graphql_devise.sessions.bad_credentials'))
raise_user_error(I18n.t('graphql_devise.sessions.bad_credentials'))
end

set_auth_headers(resource)
Expand All @@ -23,12 +20,12 @@ def resolve(email:, password:)
{ success: true, authenticable: resource, errors: [] }
elsif resource && !active_for_authentication?(resource)
if locked?(resource)
single_error_object(I18n.t('graphql_devise.mailer.unlock_instructions.account_lock_msg'))
raise_user_error(I18n.t('graphql_devise.mailer.unlock_instructions.account_lock_msg'))
else
single_error_object(I18n.t('devise_token_auth.sessions.not_confirmed', email: resource.email))
raise_user_error(I18n.t('devise_token_auth.sessions.not_confirmed', email: resource.email))
end
else
single_error_object(I18n.t('graphql_devise.sessions.bad_credentials'))
raise_user_error(I18n.t('graphql_devise.sessions.bad_credentials'))
end
end

Expand Down
7 changes: 2 additions & 5 deletions app/graphql/graphql_devise/mutations/logout.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
module GraphqlDevise
module Mutations
class Logout < Base
field :success, Boolean, null: false
field :errors, [String], null: false

def resolve
if current_resource && client && current_resource.tokens[client]
current_resource.tokens.delete(client)
Expand All @@ -13,9 +10,9 @@ def resolve

yield current_resource if block_given?

{ success: true, errors: [], authenticable: current_resource }
{ authenticable: current_resource }
else
{ success: false, errors: [I18n.t('graphql_devise.user_not_found')] }
raise_user_error(I18n.t('graphql_devise.user_not_found'))
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/graphql_devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
module GraphqlDevise
class Error < StandardError; end
end

require 'graphql_devise/user_error'
7 changes: 7 additions & 0 deletions lib/graphql_devise/user_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module GraphqlDevise
class UserError < GraphQL::ExecutionError
def to_h
super.merge(extensions: { code: 'USER_ERROR' })
end
end
end
45 changes: 21 additions & 24 deletions spec/requests/mutations/login_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
password: "#{password}"
) {
user { email name signInCount }
success
errors
}
}
GRAPHQL
Expand All @@ -28,10 +26,9 @@
expect(response).to include_auth_headers
expect(user.reload.tokens.keys).to include(response.headers['client'])
expect(json_response[:data][:userLogin]).to match(
success: true,
errors: [],
user: { email: user.email, name: user.name, signInCount: 1 }
user: { email: user.email, name: user.name, signInCount: 1 }
)
expect(json_response[:errors]).to be_nil
end
end

Expand All @@ -40,10 +37,9 @@

it 'returns bad credentials error' do
expect(response).not_to include_auth_headers
expect(json_response[:data][:userLogin]).to match(
success: false,
errors: ['Invalid login credentials. Please try again.'],
user: nil
expect(json_response[:data][:userLogin]).to be_nil
expect(json_response[:errors]).to contain_exactly(
hash_including(message: 'Invalid login credentials. Please try again.', extensions: { code: 'USER_ERROR' })
)
end
end
Expand All @@ -54,13 +50,13 @@

it 'returns a must confirm account message' do
expect(response).not_to include_auth_headers
expect(json_response[:data][:userLogin]).to match(
success: false,
errors: [
"A confirmation email was sent to your account at '#{user.email}'. You must follow the instructions in the " \
"email before your account can be activated"
],
user: nil
expect(json_response[:data][:userLogin]).to be_nil
expect(json_response[:errors]).to contain_exactly(
hash_including(
message: "A confirmation email was sent to your account at '#{user.email}'. You must follow the " \
"instructions in the email before your account can be activated",
extensions: { code: 'USER_ERROR' }
)
)
end
end
Expand All @@ -70,10 +66,12 @@

it 'returns a must confirm account message' do
expect(response).not_to include_auth_headers
expect(json_response[:data][:userLogin]).to match(
success: false,
errors: ['Your account has been locked due to an excessive number of unsuccessful sign in attempts.'],
user: nil
expect(json_response[:data][:userLogin]).to be_nil
expect(json_response[:errors]).to contain_exactly(
hash_including(
message: 'Your account has been locked due to an excessive number of unsuccessful sign in attempts.',
extensions: { code: 'USER_ERROR' }
)
)
end
end
Expand All @@ -83,10 +81,9 @@

it 'returns a must confirm account message' do
expect(response).not_to include_auth_headers
expect(json_response[:data][:userLogin]).to match(
success: false,
errors: ['Invalid login credentials. Please try again.'],
user: nil
expect(json_response[:data][:userLogin]).to be_nil
expect(json_response[:errors]).to contain_exactly(
hash_including(message: 'Invalid login credentials. Please try again.', extensions: { code: 'USER_ERROR' })
)
end
end
Expand Down
12 changes: 4 additions & 8 deletions spec/requests/mutations/logout_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
mutation {
userLogout{
authenticable { email }
success
errors
}
}
GRAPHQL
Expand All @@ -25,21 +23,19 @@
expect(response).not_to include_auth_headers
expect(user.reload.tokens.keys).to be_empty
expect(json_response[:data][:userLogout]).to match(
success: true,
errors: [],
authenticable: { email: user.email }
)
expect(json_response[:errors]).to be_nil
end
end

context 'when user is not logged in' do
it 'returns an error' do
expect(response).not_to include_auth_headers
expect(user.reload.tokens.keys).to be_empty
expect(json_response[:data][:userLogout]).to match(
success: false,
errors: ['User was not found or was not logged in.'],
authenticable: nil
expect(json_response[:data][:userLogout]).to be_nil
expect(json_response[:errors]).to contain_exactly(
hash_including(message: 'User was not found or was not logged in.', extensions: { code: 'USER_ERROR' })
)
end
end
Expand Down