Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add sendPasswordResetWithToken mutation
- Loading branch information
1 parent
8d05630
commit 88598b8
Showing
5 changed files
with
132 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
lib/graphql_devise/mutations/send_password_reset_with_token.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# frozen_string_literal: true | ||
|
||
module GraphqlDevise | ||
module Mutations | ||
class SendPasswordResetWithToken < Base | ||
argument :email, String, required: true | ||
argument :redirect_url, String, required: true | ||
|
||
field :message, String, null: false | ||
|
||
def resolve(email:, redirect_url:) | ||
check_redirect_url_whitelist!(redirect_url) | ||
|
||
resource = find_resource(:email, get_case_insensitive_field(:email, email)) | ||
|
||
if resource | ||
yield resource if block_given? | ||
|
||
resource.send_reset_password_instructions( | ||
email: email, | ||
provider: 'email', | ||
redirect_url: redirect_url, | ||
template_path: ['graphql_devise/mailer'] | ||
) | ||
|
||
if resource.errors.empty? | ||
{ message: I18n.t('graphql_devise.passwords.send_instructions') } | ||
else | ||
raise_user_error_list(I18n.t('graphql_devise.invalid_resource'), errors: resource.errors.full_messages) | ||
end | ||
else | ||
raise_user_error(I18n.t('graphql_devise.user_not_found')) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
spec/requests/mutations/send_password_reset_with_token_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe 'Send Password Reset Requests' do | ||
include_context 'with graphql query request' | ||
|
||
let!(:user) { create(:user, :confirmed, email: 'jwinnfield@wallaceinc.com') } | ||
let(:email) { user.email } | ||
let(:redirect_url) { 'https://google.com' } | ||
let(:query) do | ||
<<-GRAPHQL | ||
mutation { | ||
userSendPasswordResetWithToken( | ||
email: "#{email}", | ||
redirectUrl: "#{redirect_url}" | ||
) { | ||
message | ||
} | ||
} | ||
GRAPHQL | ||
end | ||
|
||
context 'when redirect_url is not whitelisted' do | ||
let(:redirect_url) { 'https://not-safe.com' } | ||
|
||
it 'returns a not whitelisted redirect url error' do | ||
expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count) | ||
|
||
expect(json_response[:errors]).to containing_exactly( | ||
hash_including( | ||
message: "Redirect to '#{redirect_url}' not allowed.", | ||
extensions: { code: 'USER_ERROR' } | ||
) | ||
) | ||
end | ||
end | ||
|
||
context 'when params are correct' do | ||
context 'when using the gem schema' do | ||
it 'sends password reset email' do | ||
expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1) | ||
|
||
expect(json_response[:data][:userSendPasswordResetWithToken]).to include( | ||
message: 'You will receive an email with instructions on how to reset your password in a few minutes.' | ||
) | ||
|
||
email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded) | ||
link = email.css('a').first | ||
|
||
expect(link['href']).to include(redirect_url + '?reset_password_token') | ||
end | ||
end | ||
end | ||
|
||
context 'when email address uses different casing' do | ||
let(:email) { 'jWinnfield@wallaceinc.com' } | ||
|
||
it 'honors devise configuration for case insensitive fields' do | ||
expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1) | ||
expect(json_response[:data][:userSendPasswordResetWithToken]).to include( | ||
message: 'You will receive an email with instructions on how to reset your password in a few minutes.' | ||
) | ||
end | ||
end | ||
|
||
context 'when user email is not found' do | ||
let(:email) { 'nothere@gmail.com' } | ||
|
||
before { post_request } | ||
|
||
it 'returns an error' do | ||
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 | ||
end |