graphql_devise 0.18.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +25 -2
  3. data/.gitignore +4 -0
  4. data/.rubocop.yml +9 -10
  5. data/Appraisals +72 -35
  6. data/CHANGELOG.md +63 -0
  7. data/README.md +71 -142
  8. data/app/controllers/graphql_devise/graphql_controller.rb +3 -3
  9. data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +1 -5
  10. data/config/routes.rb +0 -2
  11. data/graphql_devise.gemspec +8 -6
  12. data/lib/generators/graphql_devise/install_generator.rb +1 -1
  13. data/lib/graphql_devise/concerns/additional_controller_methods.rb +48 -0
  14. data/lib/graphql_devise/concerns/additional_model_methods.rb +17 -0
  15. data/lib/graphql_devise/concerns/authenticatable.rb +1 -1
  16. data/lib/graphql_devise/concerns/controller_methods.rb +79 -91
  17. data/lib/graphql_devise/concerns/field_authentication.rb +14 -0
  18. data/lib/graphql_devise/concerns/set_user_by_token.rb +1 -1
  19. data/lib/graphql_devise/default_operations.rb +16 -0
  20. data/lib/graphql_devise/engine.rb +0 -2
  21. data/lib/graphql_devise/model/with_email_updater.rb +5 -30
  22. data/lib/graphql_devise/mount_method/operation_preparer.rb +0 -7
  23. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +1 -1
  24. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
  25. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +0 -12
  26. data/lib/graphql_devise/mount_method/option_sanitizer.rb +0 -2
  27. data/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb +2 -2
  28. data/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb +2 -2
  29. data/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb +1 -1
  30. data/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb +1 -1
  31. data/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +0 -2
  32. data/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +1 -1
  33. data/lib/graphql_devise/mount_method/option_validators/supported_operations_validator.rb +1 -1
  34. data/lib/graphql_devise/mount_method/options_validator.rb +0 -3
  35. data/lib/graphql_devise/mount_method/supported_options.rb +0 -5
  36. data/lib/graphql_devise/mutations/base.rb +1 -1
  37. data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +2 -2
  38. data/lib/graphql_devise/mutations/login.rb +2 -2
  39. data/lib/graphql_devise/mutations/register.rb +2 -2
  40. data/lib/graphql_devise/mutations/update_password_with_token.rb +2 -2
  41. data/lib/graphql_devise/resolvers/base.rb +1 -1
  42. data/lib/graphql_devise/resource_loader.rb +71 -39
  43. data/lib/graphql_devise/route_mounter.rb +13 -0
  44. data/lib/graphql_devise/schema_plugin.rb +11 -40
  45. data/lib/graphql_devise/types/authenticatable_type.rb +1 -1
  46. data/lib/graphql_devise/types/base_field.rb +9 -0
  47. data/lib/graphql_devise/types/base_type.rb +8 -0
  48. data/lib/graphql_devise/types/credential_type.rb +1 -1
  49. data/lib/graphql_devise/types/mutation_type.rb +1 -0
  50. data/lib/graphql_devise/types/query_type.rb +1 -0
  51. data/lib/graphql_devise/version.rb +1 -1
  52. data/lib/graphql_devise.rb +21 -29
  53. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +2 -16
  54. data/spec/dummy/app/graphql/dummy_schema.rb +1 -5
  55. data/spec/dummy/app/graphql/interpreter_schema.rb +6 -2
  56. data/spec/dummy/app/graphql/mutations/base_mutation.rb +6 -0
  57. data/spec/dummy/app/graphql/mutations/update_user.rb +2 -4
  58. data/spec/dummy/app/graphql/types/admin_type.rb +1 -1
  59. data/spec/dummy/app/graphql/types/custom_admin_type.rb +1 -1
  60. data/spec/dummy/app/graphql/types/mutation_type.rb +3 -1
  61. data/spec/dummy/app/graphql/types/query_type.rb +3 -1
  62. data/spec/dummy/app/graphql/types/user_type.rb +1 -1
  63. data/spec/dummy/config/environments/test.rb +1 -1
  64. data/spec/dummy/config/routes.rb +5 -9
  65. data/spec/generators/graphql_devise/install_generator_spec.rb +2 -2
  66. data/spec/graphql_devise/model/with_email_updater_spec.rb +17 -35
  67. data/spec/rails_helper.rb +5 -5
  68. data/spec/requests/mutations/login_spec.rb +34 -0
  69. data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +2 -3
  70. data/spec/requests/user_controller_spec.rb +1 -33
  71. data/spec/services/resource_loader_spec.rb +53 -3
  72. data/spec/spec_helper.rb +1 -1
  73. metadata +62 -55
  74. data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +0 -72
  75. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +0 -21
  76. data/app/helpers/graphql_devise/mailer_helper.rb +0 -37
  77. data/app/models/graphql_devise/concerns/additional_model_methods.rb +0 -21
  78. data/app/models/graphql_devise/concerns/model.rb +0 -25
  79. data/lib/graphql_devise/default_operations/mutations.rb +0 -32
  80. data/lib/graphql_devise/default_operations/resolvers.rb +0 -14
  81. data/lib/graphql_devise/mutations/resend_confirmation.rb +0 -45
  82. data/lib/graphql_devise/mutations/send_password_reset.rb +0 -38
  83. data/lib/graphql_devise/mutations/sign_up.rb +0 -61
  84. data/lib/graphql_devise/mutations/update_password.rb +0 -46
  85. data/lib/graphql_devise/rails/routes.rb +0 -15
  86. data/lib/graphql_devise/resolvers/check_password_token.rb +0 -43
  87. data/lib/graphql_devise/resolvers/confirm_account.rb +0 -42
  88. data/spec/dummy/app/graphql/mutations/sign_up.rb +0 -14
  89. data/spec/dummy/app/graphql/resolvers/confirm_admin_account.rb +0 -13
  90. data/spec/requests/mutations/resend_confirmation_spec.rb +0 -153
  91. data/spec/requests/mutations/send_password_reset_spec.rb +0 -103
  92. data/spec/requests/mutations/sign_up_spec.rb +0 -170
  93. data/spec/requests/mutations/update_password_spec.rb +0 -116
  94. data/spec/requests/queries/check_password_token_spec.rb +0 -149
  95. data/spec/requests/queries/confirm_account_spec.rb +0 -137
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Resend confirmation' do
6
- include_context 'with graphql query request'
7
-
8
- let(:confirmed_at) { nil }
9
- let!(:user) { create(:user, confirmed_at: nil, email: 'mwallace@wallaceinc.com') }
10
- let(:email) { user.email }
11
- let(:id) { user.id }
12
- let(:redirect) { 'https://google.com' }
13
- let(:query) do
14
- <<-GRAPHQL
15
- mutation {
16
- userResendConfirmation(
17
- email:"#{email}",
18
- redirectUrl:"#{redirect}"
19
- ) {
20
- message
21
- }
22
- }
23
- GRAPHQL
24
- end
25
-
26
- context 'when redirect_url is not whitelisted' do
27
- let(:redirect) { 'https://not-safe.com' }
28
-
29
- it 'returns a not whitelisted redirect url error' do
30
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
31
-
32
- expect(json_response[:errors]).to containing_exactly(
33
- hash_including(
34
- message: "Redirect to '#{redirect}' not allowed.",
35
- extensions: { code: 'USER_ERROR' }
36
- )
37
- )
38
- end
39
- end
40
-
41
- context 'when params are correct' do
42
- context 'when using the gem schema' do
43
- it 'sends an email to the user with confirmation url and returns a success message' do
44
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
45
- expect(json_response[:data][:userResendConfirmation]).to include(
46
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
47
- )
48
-
49
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
50
- link = email.css('a').first
51
- confirm_link_msg_text = email.css('p')[1].inner_html
52
- confirm_account_link_text = link.inner_html
53
-
54
- expect(link['href']).to include('/api/v1/graphql_auth?')
55
- expect(confirm_link_msg_text).to eq('You can confirm your account email through the link below:')
56
- expect(confirm_account_link_text).to eq('Confirm my account')
57
-
58
- expect do
59
- get link['href']
60
- user.reload
61
- end.to change(user, :confirmed_at).from(NilClass).to(ActiveSupport::TimeWithZone)
62
- end
63
- end
64
-
65
- context 'when using a custom schema' do
66
- let(:custom_path) { '/api/v1/graphql' }
67
-
68
- it 'sends an email to the user with confirmation url and returns a success message' do
69
- expect { post_request(custom_path) }.to change(ActionMailer::Base.deliveries, :count).by(1)
70
- expect(json_response[:data][:userResendConfirmation]).to include(
71
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
72
- )
73
-
74
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
75
- link = email.css('a').first
76
- confirm_link_msg_text = email.css('p')[1].inner_html
77
- confirm_account_link_text = link.inner_html
78
-
79
- expect(link['href']).to include("#{custom_path}?")
80
- expect(confirm_link_msg_text).to eq('You can confirm your account email through the link below:')
81
- expect(confirm_account_link_text).to eq('Confirm my account')
82
-
83
- expect do
84
- get link['href']
85
- user.reload
86
- end.to change(user, :confirmed_at).from(NilClass).to(ActiveSupport::TimeWithZone)
87
- end
88
- end
89
-
90
- context 'when email address uses different casing' do
91
- let(:email) { 'mWallace@wallaceinc.com' }
92
-
93
- it 'honors devise configuration for case insensitive fields' do
94
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
95
- expect(json_response[:data][:userResendConfirmation]).to include(
96
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
97
- )
98
- end
99
- end
100
-
101
- context 'when the user has already been confirmed' do
102
- before { user.confirm }
103
-
104
- it 'does *NOT* send an email and raises an error' do
105
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
106
- expect(json_response[:data][:userResendConfirmation]).to be_nil
107
- expect(json_response[:errors]).to contain_exactly(
108
- hash_including(
109
- message: 'Email was already confirmed, please try signing in',
110
- extensions: { code: 'USER_ERROR' }
111
- )
112
- )
113
- end
114
- end
115
- end
116
-
117
- context 'when the email was changed' do
118
- let(:confirmed_at) { 2.seconds.ago }
119
- let(:email) { 'new-email@wallaceinc.com' }
120
- let(:new_email) { email }
121
-
122
- before do
123
- user.update_with_email(
124
- email: new_email,
125
- schema_url: 'http://localhost/test',
126
- confirmation_success_url: 'https://google.com'
127
- )
128
- end
129
-
130
- it 'sends new confirmation email' do
131
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
132
- expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(new_email)
133
- expect(json_response[:data][:userResendConfirmation]).to include(
134
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
135
- )
136
- end
137
- end
138
-
139
- context "when the email isn't in the system" do
140
- let(:email) { 'nothere@gmail.com' }
141
-
142
- it 'does *NOT* send an email and raises an error' do
143
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
144
- expect(json_response[:data][:userResendConfirmation]).to be_nil
145
- expect(json_response[:errors]).to contain_exactly(
146
- hash_including(
147
- message: "Unable to find user with email '#{email}'.",
148
- extensions: { code: 'USER_ERROR' }
149
- )
150
- )
151
- end
152
- end
153
- end
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Send Password Reset Requests' do
6
- include_context 'with graphql query request'
7
-
8
- let!(:user) { create(:user, :confirmed, email: 'jwinnfield@wallaceinc.com') }
9
- let(:email) { user.email }
10
- let(:redirect_url) { 'https://google.com' }
11
- let(:query) do
12
- <<-GRAPHQL
13
- mutation {
14
- userSendPasswordReset(
15
- email: "#{email}",
16
- redirectUrl: "#{redirect_url}"
17
- ) {
18
- message
19
- }
20
- }
21
- GRAPHQL
22
- end
23
-
24
- context 'when redirect_url is not whitelisted' do
25
- let(:redirect_url) { 'https://not-safe.com' }
26
-
27
- it 'returns a not whitelisted redirect url error' do
28
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
29
-
30
- expect(json_response[:errors]).to containing_exactly(
31
- hash_including(
32
- message: "Redirect to '#{redirect_url}' not allowed.",
33
- extensions: { code: 'USER_ERROR' }
34
- )
35
- )
36
- end
37
- end
38
-
39
- context 'when params are correct' do
40
- context 'when using the gem schema' do
41
- it 'sends password reset email' do
42
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
43
-
44
- expect(json_response[:data][:userSendPasswordReset]).to include(
45
- message: 'You will receive an email with instructions on how to reset your password in a few minutes.'
46
- )
47
-
48
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
49
- link = email.css('a').first
50
- expect(link['href']).to include('/api/v1/graphql_auth?')
51
-
52
- expect do
53
- get link['href']
54
- user.reload
55
- end.to change(user, :allow_password_change).from(false).to(true)
56
- end
57
- end
58
-
59
- context 'when using a custom schema' do
60
- let(:custom_path) { '/api/v1/graphql' }
61
-
62
- it 'sends password reset email' do
63
- expect { post_request(custom_path) }.to change(ActionMailer::Base.deliveries, :count).by(1)
64
-
65
- expect(json_response[:data][:userSendPasswordReset]).to include(
66
- message: 'You will receive an email with instructions on how to reset your password in a few minutes.'
67
- )
68
-
69
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
70
- link = email.css('a').first
71
- expect(link['href']).to include("#{custom_path}?")
72
-
73
- expect do
74
- get link['href']
75
- user.reload
76
- end.to change(user, :allow_password_change).from(false).to(true)
77
- end
78
- end
79
- end
80
-
81
- context 'when email address uses different casing' do
82
- let(:email) { 'jWinnfield@wallaceinc.com' }
83
-
84
- it 'honors devise configuration for case insensitive fields' do
85
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
86
- expect(json_response[:data][:userSendPasswordReset]).to include(
87
- message: 'You will receive an email with instructions on how to reset your password in a few minutes.'
88
- )
89
- end
90
- end
91
-
92
- context 'when user email is not found' do
93
- let(:email) { 'nothere@gmail.com' }
94
-
95
- before { post_request }
96
-
97
- it 'returns an error' do
98
- expect(json_response[:errors]).to contain_exactly(
99
- hash_including(message: 'User was not found or was not logged in.', extensions: { code: 'USER_ERROR' })
100
- )
101
- end
102
- end
103
- end
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Sign Up process' do
6
- include_context 'with graphql query request'
7
-
8
- let(:name) { Faker::Name.name }
9
- let(:password) { Faker::Internet.password }
10
- let(:email) { Faker::Internet.email }
11
- let(:redirect) { 'https://google.com' }
12
-
13
- context 'when using the user model' do
14
- let(:query) do
15
- <<-GRAPHQL
16
- mutation {
17
- userSignUp(
18
- email: "#{email}"
19
- name: "#{name}"
20
- password: "#{password}"
21
- passwordConfirmation: "#{password}"
22
- confirmSuccessUrl: "#{redirect}"
23
- ) {
24
- credentials { accessToken }
25
- user {
26
- email
27
- name
28
- }
29
- }
30
- }
31
- GRAPHQL
32
- end
33
-
34
- context 'when redirect_url is not whitelisted' do
35
- let(:redirect) { 'https://not-safe.com' }
36
-
37
- it 'returns a not whitelisted redirect url error' do
38
- expect { post_request }.to(
39
- not_change(User, :count)
40
- .and(not_change(ActionMailer::Base.deliveries, :count))
41
- )
42
-
43
- expect(json_response[:errors]).to containing_exactly(
44
- hash_including(
45
- message: "Redirect to '#{redirect}' not allowed.",
46
- extensions: { code: 'USER_ERROR' }
47
- )
48
- )
49
- end
50
- end
51
-
52
- context 'when params are correct' do
53
- it 'creates a new resource that requires confirmation' do
54
- expect { post_request }.to(
55
- change(User, :count).by(1)
56
- .and(change(ActionMailer::Base.deliveries, :count).by(1))
57
- )
58
-
59
- user = User.last
60
-
61
- expect(user).not_to be_active_for_authentication
62
- expect(user.confirmed_at).to be_nil
63
- expect(user).to be_valid_password(password)
64
- expect(json_response[:data][:userSignUp]).to include(
65
- credentials: nil,
66
- user: {
67
- email: email,
68
- name: name
69
- }
70
- )
71
-
72
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
73
- link = email.css('a').first
74
-
75
- expect do
76
- get link['href']
77
- user.reload
78
- end.to change { user.active_for_authentication? }.to(true)
79
- end
80
-
81
- context 'when email address uses different casing' do
82
- let(:email) { 'miaWallace@wallaceinc.com' }
83
-
84
- it 'honors devise configuration for case insensitive fields' do
85
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
86
- expect(User.last.email).to eq('miawallace@wallaceinc.com')
87
- expect(json_response[:data][:userSignUp]).to include(user: { email: 'miawallace@wallaceinc.com', name: name })
88
- end
89
- end
90
- end
91
-
92
- context 'when required params are missing' do
93
- let(:email) { '' }
94
-
95
- it 'does *NOT* create resource a resource nor send an email' do
96
- expect { post_request }.to(
97
- not_change(User, :count)
98
- .and(not_change(ActionMailer::Base.deliveries, :count))
99
- )
100
-
101
- expect(json_response[:data][:userSignUp]).to be_nil
102
- expect(json_response[:errors]).to containing_exactly(
103
- hash_including(
104
- message: "User couldn't be registered",
105
- extensions: { code: 'USER_ERROR', detailed_errors: ["Email can't be blank"] }
106
- )
107
- )
108
- end
109
- end
110
- end
111
-
112
- context 'when using the admin model' do
113
- let(:query) do
114
- <<-GRAPHQL
115
- mutation {
116
- adminSignUp(
117
- email: "#{email}"
118
- password: "#{password}"
119
- passwordConfirmation: "#{password}"
120
- confirmSuccessUrl: "#{redirect}"
121
- ) {
122
- authenticatable {
123
- email
124
- }
125
- }
126
- }
127
- GRAPHQL
128
- end
129
-
130
- before { post_request }
131
-
132
- it 'skips the sign up mutation' do
133
- expect(json_response[:errors]).to contain_exactly(
134
- hash_including(message: "Field 'adminSignUp' doesn't exist on type 'Mutation'")
135
- )
136
- end
137
- end
138
-
139
- context 'when using the guest model' do
140
- let(:query) do
141
- <<-GRAPHQL
142
- mutation {
143
- guestSignUp(
144
- email: "#{email}"
145
- password: "#{password}"
146
- passwordConfirmation: "#{password}"
147
- confirmSuccessUrl: "#{redirect}"
148
- ) {
149
- credentials { accessToken client uid }
150
- authenticatable {
151
- email
152
- }
153
- }
154
- }
155
- GRAPHQL
156
- end
157
-
158
- it 'returns credentials as no confirmation is required' do
159
- expect { post_request }.to change(Guest, :count).from(0).to(1)
160
-
161
- expect(json_response[:data][:guestSignUp]).to include(
162
- authenticatable: { email: email },
163
- credentials: hash_including(
164
- uid: email,
165
- client: Guest.last.tokens.keys.first
166
- )
167
- )
168
- end
169
- end
170
- end
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Update Password Requests' do
6
- shared_examples 'successful password update' do
7
- it 'updates the password' do
8
- expect do
9
- post_request
10
- user.reload
11
- end.to change(user, :encrypted_password)
12
-
13
- expect(response).to include_auth_headers
14
- expect(json_response[:data][:userUpdatePassword]).to match(
15
- authenticatable: { email: user.email }
16
- )
17
- expect(json_response[:errors]).to be_nil
18
- expect(user).to be_valid_password(password)
19
- end
20
- end
21
-
22
- include_context 'with graphql query request'
23
-
24
- let(:password) { 'safePassw0rd!' }
25
- let(:password_confirmation) { 'safePassw0rd!' }
26
- let(:original_password) { 'current_password' }
27
- let(:current_password) { original_password }
28
- let(:allow_password_change) { false }
29
- let(:user) { create(:user, :confirmed, password: original_password, allow_password_change: allow_password_change) }
30
- let(:query) do
31
- <<-GRAPHQL
32
- mutation {
33
- userUpdatePassword(
34
- password: "#{password}",
35
- passwordConfirmation: "#{password_confirmation}",
36
- currentPassword: "#{current_password}"
37
- ) {
38
- authenticatable { email }
39
- }
40
- }
41
- GRAPHQL
42
- end
43
-
44
- context 'when user is logged in' do
45
- let(:headers) { user.create_new_auth_token }
46
-
47
- context 'when currentPassword is not provided' do
48
- let(:current_password) { nil }
49
-
50
- context 'when allow_password_change is true' do
51
- let(:allow_password_change) { true }
52
-
53
- it_behaves_like 'successful password update'
54
-
55
- it 'sets allow_password_change to false' do
56
- expect do
57
- post_request
58
- user.reload
59
- end.to change(user, :allow_password_change).from(true).to(false)
60
- end
61
- end
62
-
63
- context 'when allow_password_change is false' do
64
- it 'does not update the password' do
65
- expect do
66
- post_request
67
- user.reload
68
- end.not_to change(user, :encrypted_password)
69
-
70
- expect(response).to include_auth_headers
71
- expect(json_response[:data][:userUpdatePassword]).to be_nil
72
- expect(json_response[:errors]).to contain_exactly(
73
- hash_including(
74
- message: 'Unable to update user password',
75
- extensions: { code: 'USER_ERROR', detailed_errors: ["Current password can't be blank"] }
76
- )
77
- )
78
- end
79
- end
80
- end
81
-
82
- context 'when currentPassword is provided' do
83
- context 'when allow_password_change is true' do
84
- let(:allow_password_change) { true }
85
-
86
- it_behaves_like 'successful password update'
87
-
88
- it 'sets allow_password_change to false' do
89
- expect do
90
- post_request
91
- user.reload
92
- end.to change(user, :allow_password_change).from(true).to(false)
93
- end
94
- end
95
-
96
- context 'when allow_password_change is false' do
97
- it_behaves_like 'successful password update'
98
- end
99
- end
100
- end
101
-
102
- context 'when user is not logged in' do
103
- it 'does not update the password' do
104
- expect do
105
- post_request
106
- user.reload
107
- end.not_to change(user, :encrypted_password)
108
-
109
- expect(response).not_to include_auth_headers
110
- expect(json_response[:data][:userUpdatePassword]).to be_nil
111
- expect(json_response[:errors]).to contain_exactly(
112
- hash_including(message: 'User is not logged in.', extensions: { code: 'USER_ERROR' })
113
- )
114
- end
115
- end
116
- end
@@ -1,149 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Check Password Token Requests' do
6
- include_context 'with graphql query request'
7
-
8
- let(:user) { create(:user, :confirmed) }
9
- let(:redirect_url) { 'https://google.com' }
10
-
11
- context 'when using the user model' do
12
- let(:query) do
13
- <<-GRAPHQL
14
- query {
15
- userCheckPasswordToken(
16
- resetPasswordToken: "#{token}",
17
- redirectUrl: "#{redirect_url}"
18
- ) {
19
- email
20
- }
21
- }
22
- GRAPHQL
23
- end
24
-
25
- context 'when reset password token is valid' do
26
- let(:token) { user.send(:set_reset_password_token) }
27
-
28
- context 'when redirect_url is not provided' do
29
- let(:redirect_url) { nil }
30
-
31
- it 'returns authenticatable and credentials in the headers' do
32
- get_request
33
-
34
- expect(response).to include_auth_headers
35
- expect(json_response[:data][:userCheckPasswordToken]).to match(
36
- email: user.email
37
- )
38
- end
39
- end
40
-
41
- context 'when redirect url is provided' do
42
- it 'redirects to redirect url' do
43
- expect do
44
- get_request
45
-
46
- user.reload
47
- end.to change { user.tokens.keys.count }.from(0).to(1).and(
48
- change(user, :allow_password_change).from(false).to(true)
49
- )
50
-
51
- expect(response).to redirect_to %r{\Ahttps://google.com}
52
- expect(response.body).to include("client=#{user.reload.tokens.keys.first}")
53
- expect(response.body).to include('access-token=')
54
- expect(response.body).to include('uid=')
55
- expect(response.body).to include('expiry=')
56
- end
57
-
58
- context 'when redirect_url is not whitelisted' do
59
- let(:redirect_url) { 'https://not-safe.com' }
60
-
61
- before { post_request }
62
-
63
- it 'returns a not whitelisted redirect url error' do
64
- expect(json_response[:errors]).to containing_exactly(
65
- hash_including(
66
- message: "Redirect to '#{redirect_url}' not allowed.",
67
- extensions: { code: 'USER_ERROR' }
68
- )
69
- )
70
- end
71
- end
72
- end
73
-
74
- context 'when token has expired' do
75
- it 'returns an expired token error' do
76
- travel_to 10.hours.ago do
77
- token
78
- end
79
-
80
- get_request
81
-
82
- expect(json_response[:errors]).to contain_exactly(
83
- hash_including(message: 'Reset password token is no longer valid.', extensions: { code: 'USER_ERROR' })
84
- )
85
- end
86
- end
87
- end
88
-
89
- context 'when reset password token is not found' do
90
- let(:token) { user.send(:set_reset_password_token) + 'invalid' }
91
-
92
- it 'returns an error message' do
93
- get_request
94
-
95
- expect(json_response[:errors]).to contain_exactly(
96
- hash_including(message: 'No user found for the specified reset token.', extensions: { code: 'USER_ERROR' })
97
- )
98
- end
99
- end
100
- end
101
-
102
- context 'when using the admin model' do
103
- let(:token) { 'not_important' }
104
- let(:query) do
105
- <<-GRAPHQL
106
- query {
107
- adminCheckPasswordToken(
108
- resetPasswordToken: "#{token}",
109
- redirectUrl: "#{redirect_url}"
110
- ) {
111
- email
112
- }
113
- }
114
- GRAPHQL
115
- end
116
-
117
- before { post_request }
118
-
119
- it 'skips the sign up mutation' do
120
- expect(json_response[:errors]).to contain_exactly(
121
- hash_including(message: "Field 'adminCheckPasswordToken' doesn't exist on type 'Query'")
122
- )
123
- end
124
- end
125
-
126
- context 'when using the guest model' do
127
- let(:token) { 'not_important' }
128
- let(:query) do
129
- <<-GRAPHQL
130
- query {
131
- guestCheckPasswordToken(
132
- resetPasswordToken: "#{token}",
133
- redirectUrl: "#{redirect_url}"
134
- ) {
135
- email
136
- }
137
- }
138
- GRAPHQL
139
- end
140
-
141
- before { post_request }
142
-
143
- it 'skips the sign up mutation' do
144
- expect(json_response[:errors]).to contain_exactly(
145
- hash_including(message: "Field 'guestCheckPasswordToken' doesn't exist on type 'Query'")
146
- )
147
- end
148
- end
149
- end