graphql_devise 0.13.5 → 0.14.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +118 -0
  3. data/Appraisals +39 -5
  4. data/CHANGELOG.md +57 -6
  5. data/README.md +27 -7
  6. data/Rakefile +2 -1
  7. data/app/controllers/graphql_devise/graphql_controller.rb +1 -1
  8. data/app/views/graphql_devise/mailer/reset_password_instructions.html.erb +7 -1
  9. data/config/locales/en.yml +2 -1
  10. data/docs/usage/reset_password_flow.md +90 -0
  11. data/graphql_devise.gemspec +2 -2
  12. data/lib/graphql_devise/concerns/controller_methods.rb +6 -0
  13. data/lib/graphql_devise/default_operations/mutations.rb +10 -6
  14. data/lib/graphql_devise/mutations/resend_confirmation.rb +2 -0
  15. data/lib/graphql_devise/mutations/send_password_reset.rb +2 -0
  16. data/lib/graphql_devise/mutations/send_password_reset_with_token.rb +37 -0
  17. data/lib/graphql_devise/mutations/sign_up.rb +1 -3
  18. data/lib/graphql_devise/mutations/update_password_with_token.rb +38 -0
  19. data/lib/graphql_devise/resolvers/check_password_token.rb +1 -0
  20. data/lib/graphql_devise/resolvers/confirm_account.rb +2 -0
  21. data/lib/graphql_devise/schema_plugin.rb +22 -11
  22. data/lib/graphql_devise/version.rb +1 -1
  23. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +2 -2
  24. data/spec/dummy/app/graphql/dummy_schema.rb +4 -3
  25. data/spec/dummy/app/graphql/mutations/reset_admin_password_with_token.rb +13 -0
  26. data/spec/dummy/config/initializers/devise_token_auth.rb +2 -0
  27. data/spec/dummy/config/routes.rb +2 -1
  28. data/spec/dummy/db/migrate/20200623003142_create_schema_users.rb +0 -1
  29. data/spec/dummy/db/schema.rb +0 -1
  30. data/spec/graphql/user_queries_spec.rb +118 -0
  31. data/spec/requests/graphql_controller_spec.rb +12 -11
  32. data/spec/requests/mutations/additional_mutations_spec.rb +0 -1
  33. data/spec/requests/mutations/resend_confirmation_spec.rb +16 -1
  34. data/spec/requests/mutations/send_password_reset_spec.rb +16 -1
  35. data/spec/requests/mutations/send_password_reset_with_token_spec.rb +78 -0
  36. data/spec/requests/mutations/sign_up_spec.rb +19 -1
  37. data/spec/requests/mutations/update_password_with_token_spec.rb +119 -0
  38. data/spec/requests/queries/check_password_token_spec.rb +16 -1
  39. data/spec/requests/queries/confirm_account_spec.rb +17 -2
  40. data/spec/requests/queries/introspection_query_spec.rb +149 -0
  41. data/spec/requests/user_controller_spec.rb +9 -9
  42. data/spec/support/contexts/graphql_request.rb +12 -4
  43. data/spec/support/contexts/schema_test.rb +14 -0
  44. metadata +26 -11
  45. data/.travis.yml +0 -79
@@ -54,6 +54,21 @@ RSpec.describe 'Check Password Token Requests' do
54
54
  expect(response.body).to include('uid=')
55
55
  expect(response.body).to include('expiry=')
56
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
57
72
  end
58
73
 
59
74
  context 'when token has expired' do
@@ -74,7 +89,7 @@ RSpec.describe 'Check Password Token Requests' do
74
89
  context 'when reset password token is not found' do
75
90
  let(:token) { user.send(:set_reset_password_token) + 'invalid' }
76
91
 
77
- it 'redirects to redirect url' do
92
+ it 'returns an error message' do
78
93
  get_request
79
94
 
80
95
  expect(json_response[:errors]).to contain_exactly(
@@ -7,7 +7,7 @@ RSpec.describe 'Account confirmation' do
7
7
 
8
8
  context 'when using the user model' do
9
9
  let(:user) { create(:user, confirmed_at: nil) }
10
- let(:redirect) { Faker::Internet.url }
10
+ let(:redirect) { 'https://google.com' }
11
11
  let(:query) do
12
12
  <<-GRAPHQL
13
13
  {
@@ -43,6 +43,21 @@ RSpec.describe 'Account confirmation' do
43
43
  expect(user).to be_active_for_authentication
44
44
  end
45
45
 
46
+ context 'when redirect_url is not whitelisted' do
47
+ let(:redirect) { 'https://not-safe.com' }
48
+
49
+ it 'returns a not whitelisted redirect url error' do
50
+ expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
51
+
52
+ expect(json_response[:errors]).to containing_exactly(
53
+ hash_including(
54
+ message: "Redirect to '#{redirect}' not allowed.",
55
+ extensions: { code: 'USER_ERROR' }
56
+ )
57
+ )
58
+ end
59
+ end
60
+
46
61
  context 'when unconfirmed_email is present' do
47
62
  let(:user) { create(:user, :confirmed, unconfirmed_email: 'vvega@wallaceinc.com') }
48
63
 
@@ -81,7 +96,7 @@ RSpec.describe 'Account confirmation' do
81
96
 
82
97
  context 'when using the admin model' do
83
98
  let(:admin) { create(:admin, confirmed_at: nil) }
84
- let(:redirect) { Faker::Internet.url }
99
+ let(:redirect) { 'https://google.com' }
85
100
  let(:query) do
86
101
  <<-GRAPHQL
87
102
  {
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe 'Login Requests' do
6
+ include_context 'with graphql query request'
7
+
8
+ let(:query) do
9
+ <<-GRAPHQL
10
+ query IntrospectionQuery {
11
+ __schema {
12
+ queryType { name }
13
+ mutationType { name }
14
+ subscriptionType { name }
15
+ types {
16
+ ...FullType
17
+ }
18
+ directives {
19
+ name
20
+ description
21
+ args {
22
+ ...InputValue
23
+ }
24
+ onOperation
25
+ onFragment
26
+ onField
27
+ }
28
+ }
29
+ }
30
+
31
+ fragment FullType on __Type {
32
+ kind
33
+ name
34
+ description
35
+ fields(includeDeprecated: true) {
36
+ name
37
+ description
38
+ args {
39
+ ...InputValue
40
+ }
41
+ type {
42
+ ...TypeRef
43
+ }
44
+ isDeprecated
45
+ deprecationReason
46
+ }
47
+ inputFields {
48
+ ...InputValue
49
+ }
50
+ interfaces {
51
+ ...TypeRef
52
+ }
53
+ enumValues(includeDeprecated: true) {
54
+ name
55
+ description
56
+ isDeprecated
57
+ deprecationReason
58
+ }
59
+ possibleTypes {
60
+ ...TypeRef
61
+ }
62
+ }
63
+
64
+ fragment InputValue on __InputValue {
65
+ name
66
+ description
67
+ type { ...TypeRef }
68
+ defaultValue
69
+ }
70
+
71
+ fragment TypeRef on __Type {
72
+ kind
73
+ name
74
+ ofType {
75
+ kind
76
+ name
77
+ ofType {
78
+ kind
79
+ name
80
+ ofType {
81
+ kind
82
+ name
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ GRAPHQL
89
+ end
90
+
91
+ context 'when using a schema plugin to mount devise operations' do
92
+ context 'when schema plugin is set to authenticate by default' do
93
+ context 'when the resource is authenticated' do
94
+ let(:user) { create(:user, :confirmed) }
95
+ let(:headers) { user.create_new_auth_token }
96
+
97
+ it 'return the schema information' do
98
+ post_request('/api/v1/graphql')
99
+
100
+ expect(json_response[:data][:__schema].keys).to contain_exactly(
101
+ :queryType, :mutationType, :subscriptionType, :types, :directives
102
+ )
103
+ end
104
+ end
105
+
106
+ context 'when the resource is *NOT* authenticated' do
107
+ context 'and instrospection is set to be public' do
108
+ it 'return the schema information' do
109
+ post_request('/api/v1/graphql')
110
+
111
+ expect(json_response[:data][:__schema].keys).to contain_exactly(
112
+ :queryType, :mutationType, :subscriptionType, :types, :directives
113
+ )
114
+ end
115
+ end
116
+
117
+ context 'and introspection is set to require auth' do
118
+ before do
119
+ allow_any_instance_of(GraphqlDevise::SchemaPlugin).to(
120
+ receive(:public_introspection).and_return(false)
121
+ )
122
+ end
123
+
124
+ it 'return an error' do
125
+ post_request('/api/v1/graphql')
126
+
127
+ expect(json_response[:data]).to be_nil
128
+ expect(json_response[:errors]).to contain_exactly(
129
+ hash_including(
130
+ message: '__schema field requires authentication',
131
+ extensions: { code: 'AUTHENTICATION_ERROR' }
132
+ )
133
+ )
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ context 'when schema plugin is set *NOT* to authenticate by default' do
140
+ it 'return the schema information' do
141
+ post_request('/api/v1/interpreter')
142
+
143
+ expect(json_response[:data][:__schema].keys).to contain_exactly(
144
+ :queryType, :mutationType, :subscriptionType, :types, :directives
145
+ )
146
+ end
147
+ end
148
+ end
149
+ end
@@ -31,15 +31,6 @@ RSpec.describe "Integrations with the user's controller" do
31
31
  expect(json_response[:data][:publicField]).to eq('Field does not require authentication')
32
32
  end
33
33
  end
34
-
35
- context 'when using the failing route' do
36
- it 'raises an invalid resource_name error' do
37
- expect { post_request('/api/v1/failing') }.to raise_error(
38
- GraphqlDevise::Error,
39
- 'Invalid resource_name `fail` provided to `graphql_context`. Possible values are: [:user, :admin, :guest, :users_customer, :schema_user].'
40
- )
41
- end
42
- end
43
34
  end
44
35
 
45
36
  describe 'privateField' do
@@ -77,6 +68,15 @@ RSpec.describe "Integrations with the user's controller" do
77
68
  )
78
69
  end
79
70
  end
71
+
72
+ context 'when using the failing route' do
73
+ it 'raises an invalid resource_name error' do
74
+ expect { post_request('/api/v1/failing') }.to raise_error(
75
+ GraphqlDevise::Error,
76
+ 'Invalid resource_name `fail` provided to `graphql_context`. Possible values are: [:user, :admin, :guest, :users_customer, :schema_user].'
77
+ )
78
+ end
79
+ end
80
80
  end
81
81
 
82
82
  context 'when using an interpreter schema' do
@@ -4,18 +4,26 @@ RSpec.shared_context 'with graphql query request' do
4
4
  let(:headers) { {} }
5
5
  let(:variables) { {} }
6
6
  let(:graphql_params) do
7
- if Rails::VERSION::MAJOR >= 5
8
- [{ params: { query: query, variables: variables }, headers: headers }]
7
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') || Rails::VERSION::MAJOR >= 5
8
+ { params: { query: query, variables: variables }, headers: headers }
9
9
  else
10
10
  [{ query: query, variables: variables }, headers]
11
11
  end
12
12
  end
13
13
 
14
14
  def post_request(path = '/api/v1/graphql_auth')
15
- post path, *graphql_params
15
+ send_request(path, :post)
16
16
  end
17
17
 
18
18
  def get_request(path = '/api/v1/graphql_auth')
19
- get path, *graphql_params
19
+ send_request(path, :get)
20
+ end
21
+
22
+ def send_request(path, method)
23
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') || Rails::VERSION::MAJOR >= 5
24
+ public_send(method, path, **graphql_params)
25
+ else
26
+ public_send(method, path, *graphql_params)
27
+ end
20
28
  end
21
29
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_context 'with graphql schema test' do
4
+ let(:variables) { {} }
5
+ let(:resource_names) { [:user] }
6
+ let(:resource) { nil }
7
+ let(:controller) { instance_double(GraphqlDevise::GraphqlController) }
8
+ let(:context) do
9
+ { current_resource: resource, controller: controller, resource_name: resource_names }
10
+ end
11
+ let(:response) do
12
+ schema.execute(query, context: context, variables: variables).deep_symbolize_keys
13
+ end
14
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_devise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.5
4
+ version: 0.14.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Celi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-11-20 00:00:00.000000000 Z
12
+ date: 2021-04-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: devise_token_auth
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '1.8'
41
41
  - - "<"
42
42
  - !ruby/object:Gem::Version
43
- version: 1.12.0
43
+ version: 1.13.0
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  version: '1.8'
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: 1.12.0
53
+ version: 1.13.0
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rails
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -86,19 +86,19 @@ dependencies:
86
86
  - !ruby/object:Gem::Version
87
87
  version: '0'
88
88
  - !ruby/object:Gem::Dependency
89
- name: coveralls
89
+ name: coveralls-ruby
90
90
  requirement: !ruby/object:Gem::Requirement
91
91
  requirements:
92
- - - ">="
92
+ - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '0'
94
+ version: '0.2'
95
95
  type: :development
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - ">="
99
+ - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: '0.2'
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: factory_bot
104
104
  requirement: !ruby/object:Gem::Requirement
@@ -275,13 +275,13 @@ executables: []
275
275
  extensions: []
276
276
  extra_rdoc_files: []
277
277
  files:
278
+ - ".circleci/config.yml"
278
279
  - ".github/ISSUE_TEMPLATE/bug_report.md"
279
280
  - ".github/ISSUE_TEMPLATE/enhancement.md"
280
281
  - ".github/ISSUE_TEMPLATE/question.md"
281
282
  - ".gitignore"
282
283
  - ".rspec"
283
284
  - ".rubocop.yml"
284
- - ".travis.yml"
285
285
  - Appraisals
286
286
  - CHANGELOG.md
287
287
  - Gemfile
@@ -302,6 +302,7 @@ files:
302
302
  - bin/setup
303
303
  - config/locales/en.yml
304
304
  - config/routes.rb
305
+ - docs/usage/reset_password_flow.md
305
306
  - graphql_devise.gemspec
306
307
  - lib/generators/graphql_devise/install_generator.rb
307
308
  - lib/graphql_devise.rb
@@ -338,8 +339,10 @@ files:
338
339
  - lib/graphql_devise/mutations/logout.rb
339
340
  - lib/graphql_devise/mutations/resend_confirmation.rb
340
341
  - lib/graphql_devise/mutations/send_password_reset.rb
342
+ - lib/graphql_devise/mutations/send_password_reset_with_token.rb
341
343
  - lib/graphql_devise/mutations/sign_up.rb
342
344
  - lib/graphql_devise/mutations/update_password.rb
345
+ - lib/graphql_devise/mutations/update_password_with_token.rb
343
346
  - lib/graphql_devise/rails/routes.rb
344
347
  - lib/graphql_devise/resolvers/base.rb
345
348
  - lib/graphql_devise/resolvers/check_password_token.rb
@@ -362,6 +365,7 @@ files:
362
365
  - spec/dummy/app/graphql/interpreter_schema.rb
363
366
  - spec/dummy/app/graphql/mutations/login.rb
364
367
  - spec/dummy/app/graphql/mutations/register_confirmed_user.rb
368
+ - spec/dummy/app/graphql/mutations/reset_admin_password_with_token.rb
365
369
  - spec/dummy/app/graphql/mutations/sign_up.rb
366
370
  - spec/dummy/app/graphql/mutations/update_user.rb
367
371
  - spec/dummy/app/graphql/resolvers/confirm_admin_account.rb
@@ -428,6 +432,7 @@ files:
428
432
  - spec/factories/users.rb
429
433
  - spec/factories/users_customers.rb
430
434
  - spec/generators/graphql_devise/install_generator_spec.rb
435
+ - spec/graphql/user_queries_spec.rb
431
436
  - spec/graphql_devise/model/with_email_updater_spec.rb
432
437
  - spec/graphql_devise_spec.rb
433
438
  - spec/models/user_spec.rb
@@ -439,10 +444,13 @@ files:
439
444
  - spec/requests/mutations/logout_spec.rb
440
445
  - spec/requests/mutations/resend_confirmation_spec.rb
441
446
  - spec/requests/mutations/send_password_reset_spec.rb
447
+ - spec/requests/mutations/send_password_reset_with_token_spec.rb
442
448
  - spec/requests/mutations/sign_up_spec.rb
443
449
  - spec/requests/mutations/update_password_spec.rb
450
+ - spec/requests/mutations/update_password_with_token_spec.rb
444
451
  - spec/requests/queries/check_password_token_spec.rb
445
452
  - spec/requests/queries/confirm_account_spec.rb
453
+ - spec/requests/queries/introspection_query_spec.rb
446
454
  - spec/requests/user_controller_spec.rb
447
455
  - spec/services/mount_method/operation_preparer_spec.rb
448
456
  - spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb
@@ -465,6 +473,7 @@ files:
465
473
  - spec/services/schema_plugin_spec.rb
466
474
  - spec/spec_helper.rb
467
475
  - spec/support/contexts/graphql_request.rb
476
+ - spec/support/contexts/schema_test.rb
468
477
  - spec/support/factory_bot.rb
469
478
  - spec/support/matchers/auth_headers_matcher.rb
470
479
  - spec/support/matchers/not_change_matcher.rb
@@ -491,7 +500,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
491
500
  - !ruby/object:Gem::Version
492
501
  version: '0'
493
502
  requirements: []
494
- rubygems_version: 3.0.8
503
+ rubygems_version: 3.0.3
495
504
  signing_key:
496
505
  specification_version: 4
497
506
  summary: GraphQL queries and mutations on top of devise_token_auth
@@ -505,6 +514,7 @@ test_files:
505
514
  - spec/dummy/app/graphql/interpreter_schema.rb
506
515
  - spec/dummy/app/graphql/mutations/login.rb
507
516
  - spec/dummy/app/graphql/mutations/register_confirmed_user.rb
517
+ - spec/dummy/app/graphql/mutations/reset_admin_password_with_token.rb
508
518
  - spec/dummy/app/graphql/mutations/sign_up.rb
509
519
  - spec/dummy/app/graphql/mutations/update_user.rb
510
520
  - spec/dummy/app/graphql/resolvers/confirm_admin_account.rb
@@ -571,6 +581,7 @@ test_files:
571
581
  - spec/factories/users.rb
572
582
  - spec/factories/users_customers.rb
573
583
  - spec/generators/graphql_devise/install_generator_spec.rb
584
+ - spec/graphql/user_queries_spec.rb
574
585
  - spec/graphql_devise/model/with_email_updater_spec.rb
575
586
  - spec/graphql_devise_spec.rb
576
587
  - spec/models/user_spec.rb
@@ -582,10 +593,13 @@ test_files:
582
593
  - spec/requests/mutations/logout_spec.rb
583
594
  - spec/requests/mutations/resend_confirmation_spec.rb
584
595
  - spec/requests/mutations/send_password_reset_spec.rb
596
+ - spec/requests/mutations/send_password_reset_with_token_spec.rb
585
597
  - spec/requests/mutations/sign_up_spec.rb
586
598
  - spec/requests/mutations/update_password_spec.rb
599
+ - spec/requests/mutations/update_password_with_token_spec.rb
587
600
  - spec/requests/queries/check_password_token_spec.rb
588
601
  - spec/requests/queries/confirm_account_spec.rb
602
+ - spec/requests/queries/introspection_query_spec.rb
589
603
  - spec/requests/user_controller_spec.rb
590
604
  - spec/services/mount_method/operation_preparer_spec.rb
591
605
  - spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb
@@ -608,6 +622,7 @@ test_files:
608
622
  - spec/services/schema_plugin_spec.rb
609
623
  - spec/spec_helper.rb
610
624
  - spec/support/contexts/graphql_request.rb
625
+ - spec/support/contexts/schema_test.rb
611
626
  - spec/support/factory_bot.rb
612
627
  - spec/support/matchers/auth_headers_matcher.rb
613
628
  - spec/support/matchers/not_change_matcher.rb