graphql_devise 0.18.2 → 1.0.0

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +7 -2
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +9 -10
  5. data/Appraisals +70 -18
  6. data/CHANGELOG.md +53 -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 +7 -5
  12. data/lib/graphql_devise/concerns/additional_controller_methods.rb +48 -0
  13. data/lib/graphql_devise/concerns/additional_model_methods.rb +17 -0
  14. data/lib/graphql_devise/concerns/authenticatable.rb +1 -1
  15. data/lib/graphql_devise/concerns/controller_methods.rb +70 -93
  16. data/lib/graphql_devise/concerns/field_authentication.rb +14 -0
  17. data/lib/graphql_devise/concerns/set_user_by_token.rb +1 -1
  18. data/lib/graphql_devise/default_operations.rb +16 -0
  19. data/lib/graphql_devise/engine.rb +0 -2
  20. data/lib/graphql_devise/model/with_email_updater.rb +5 -30
  21. data/lib/graphql_devise/mount_method/operation_preparer.rb +0 -7
  22. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +1 -1
  23. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
  24. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +0 -12
  25. data/lib/graphql_devise/mount_method/option_sanitizer.rb +0 -2
  26. data/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb +2 -2
  27. data/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb +2 -2
  28. data/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb +1 -1
  29. data/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb +1 -1
  30. data/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +0 -2
  31. data/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +1 -1
  32. data/lib/graphql_devise/mount_method/option_validators/supported_operations_validator.rb +1 -1
  33. data/lib/graphql_devise/mount_method/options_validator.rb +0 -3
  34. data/lib/graphql_devise/mount_method/supported_options.rb +0 -5
  35. data/lib/graphql_devise/mutations/base.rb +1 -1
  36. data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +1 -1
  37. data/lib/graphql_devise/mutations/login.rb +1 -1
  38. data/lib/graphql_devise/mutations/register.rb +1 -1
  39. data/lib/graphql_devise/mutations/update_password_with_token.rb +1 -1
  40. data/lib/graphql_devise/resolvers/base.rb +1 -1
  41. data/lib/graphql_devise/resource_loader.rb +71 -39
  42. data/lib/graphql_devise/route_mounter.rb +13 -0
  43. data/lib/graphql_devise/schema_plugin.rb +7 -40
  44. data/lib/graphql_devise/types/authenticatable_type.rb +1 -1
  45. data/lib/graphql_devise/types/base_field.rb +9 -0
  46. data/lib/graphql_devise/types/base_type.rb +8 -0
  47. data/lib/graphql_devise/types/credential_type.rb +1 -1
  48. data/lib/graphql_devise/types/mutation_type.rb +1 -0
  49. data/lib/graphql_devise/types/query_type.rb +1 -0
  50. data/lib/graphql_devise/version.rb +1 -1
  51. data/lib/graphql_devise.rb +21 -29
  52. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +1 -16
  53. data/spec/dummy/app/graphql/dummy_schema.rb +1 -5
  54. data/spec/dummy/app/graphql/interpreter_schema.rb +6 -2
  55. data/spec/dummy/app/graphql/mutations/base_mutation.rb +6 -0
  56. data/spec/dummy/app/graphql/mutations/update_user.rb +2 -4
  57. data/spec/dummy/app/graphql/types/admin_type.rb +1 -1
  58. data/spec/dummy/app/graphql/types/custom_admin_type.rb +1 -1
  59. data/spec/dummy/app/graphql/types/mutation_type.rb +3 -1
  60. data/spec/dummy/app/graphql/types/query_type.rb +3 -1
  61. data/spec/dummy/app/graphql/types/user_type.rb +1 -1
  62. data/spec/dummy/config/environments/test.rb +1 -1
  63. data/spec/dummy/config/routes.rb +5 -9
  64. data/spec/graphql_devise/model/with_email_updater_spec.rb +17 -35
  65. data/spec/rails_helper.rb +5 -5
  66. data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +2 -3
  67. data/spec/requests/user_controller_spec.rb +1 -33
  68. data/spec/services/resource_loader_spec.rb +14 -3
  69. metadata +55 -48
  70. data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +0 -72
  71. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +0 -21
  72. data/app/helpers/graphql_devise/mailer_helper.rb +0 -37
  73. data/app/models/graphql_devise/concerns/additional_model_methods.rb +0 -21
  74. data/app/models/graphql_devise/concerns/model.rb +0 -25
  75. data/lib/graphql_devise/default_operations/mutations.rb +0 -32
  76. data/lib/graphql_devise/default_operations/resolvers.rb +0 -14
  77. data/lib/graphql_devise/mutations/resend_confirmation.rb +0 -45
  78. data/lib/graphql_devise/mutations/send_password_reset.rb +0 -38
  79. data/lib/graphql_devise/mutations/sign_up.rb +0 -61
  80. data/lib/graphql_devise/mutations/update_password.rb +0 -46
  81. data/lib/graphql_devise/rails/routes.rb +0 -15
  82. data/lib/graphql_devise/resolvers/check_password_token.rb +0 -43
  83. data/lib/graphql_devise/resolvers/confirm_account.rb +0 -42
  84. data/spec/dummy/app/graphql/mutations/sign_up.rb +0 -14
  85. data/spec/dummy/app/graphql/resolvers/confirm_admin_account.rb +0 -13
  86. data/spec/requests/mutations/resend_confirmation_spec.rb +0 -153
  87. data/spec/requests/mutations/send_password_reset_spec.rb +0 -103
  88. data/spec/requests/mutations/sign_up_spec.rb +0 -170
  89. data/spec/requests/mutations/update_password_spec.rb +0 -116
  90. data/spec/requests/queries/check_password_token_spec.rb +0 -149
  91. data/spec/requests/queries/confirm_account_spec.rb +0 -137
@@ -6,7 +6,7 @@ module GraphqlDevise
6
6
 
7
7
  included do
8
8
  include DeviseTokenAuth::Concerns::SetUserByToken
9
- include GraphqlDevise::Concerns::AdditionalControllerMethods
9
+ include AdditionalControllerMethods
10
10
  end
11
11
  end
12
12
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlDevise
4
+ module DefaultOperations
5
+ QUERIES = {}.freeze
6
+ MUTATIONS = {
7
+ login: { klass: Mutations::Login, authenticatable: true },
8
+ logout: { klass: Mutations::Logout, authenticatable: true },
9
+ register: { klass: Mutations::Register, authenticatable: true },
10
+ update_password_with_token: { klass: Mutations::UpdatePasswordWithToken, authenticatable: true },
11
+ send_password_reset_with_token: { klass: Mutations::SendPasswordResetWithToken, authenticatable: false },
12
+ resend_confirmation_with_token: { klass: Mutations::ResendConfirmationWithToken, authenticatable: false },
13
+ confirm_registration_with_token: { klass: Mutations::ConfirmRegistrationWithToken, authenticatable: true }
14
+ }.freeze
15
+ end
16
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_devise/rails/routes'
4
-
5
3
  module GraphqlDevise
6
4
  class Engine < ::Rails::Engine
7
5
  isolate_namespace GraphqlDevise
@@ -9,15 +9,13 @@ module GraphqlDevise
9
9
  end
10
10
 
11
11
  def call
12
- check_deprecated_attributes
13
-
14
- resource_attributes = @attributes.except(:schema_url, :confirmation_success_url, :confirmation_url)
12
+ resource_attributes = @attributes.except(:confirmation_url)
15
13
  return @resource.update(resource_attributes) unless requires_reconfirmation?(resource_attributes)
16
14
 
17
15
  @resource.assign_attributes(resource_attributes)
18
16
 
19
17
  if @resource.email == email_in_database
20
- return @resource.save
18
+ @resource.save
21
19
  elsif required_reconfirm_attributes?
22
20
  return false unless @resource.valid?
23
21
 
@@ -28,7 +26,7 @@ module GraphqlDevise
28
26
  saved
29
27
  else
30
28
  raise(
31
- GraphqlDevise::Error,
29
+ ::GraphqlDevise::Error,
32
30
  'Method `update_with_email` requires attribute `confirmation_url` for email reconfirmation to work'
33
31
  )
34
32
  end
@@ -36,24 +34,8 @@ module GraphqlDevise
36
34
 
37
35
  private
38
36
 
39
- def check_deprecated_attributes
40
- if [@attributes[:schema_url], @attributes[:confirmation_success_url]].any?(&:present?)
41
- ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
42
- Providing `schema_url` and `confirmation_success_url` to `update_with_email` is deprecated and will be
43
- removed in a future version of this gem.
44
-
45
- Now you must only provide `confirmation_url` and the email will contain the new format of the confirmation
46
- url that needs to be used with the new `confirmRegistrationWithToken` on the client application.
47
- DEPRECATION
48
- end
49
- end
50
-
51
37
  def required_reconfirm_attributes?
52
- if @attributes[:schema_url].present?
53
- [@attributes[:confirmation_success_url], DeviseTokenAuth.default_confirm_success_url].any?(&:present?)
54
- else
55
- [@attributes[:confirmation_url], DeviseTokenAuth.default_confirm_success_url].any?(&:present?)
56
- end
38
+ [@attributes[:confirmation_url], DeviseTokenAuth.default_confirm_success_url].any?(&:present?)
57
39
  end
58
40
 
59
41
  def requires_reconfirmation?(resource_attributes)
@@ -78,14 +60,7 @@ module GraphqlDevise
78
60
  end
79
61
 
80
62
  def confirmation_method_params
81
- if @attributes[:schema_url].present?
82
- {
83
- redirect_url: @attributes[:confirmation_success_url] || DeviseTokenAuth.default_confirm_success_url,
84
- schema_url: @attributes[:schema_url]
85
- }
86
- else
87
- { redirect_url: @attributes[:confirmation_url] || DeviseTokenAuth.default_confirm_success_url }
88
- end
63
+ { redirect_url: @attributes[:confirmation_url] || DeviseTokenAuth.default_confirm_success_url }
89
64
  end
90
65
 
91
66
  def send_confirmation_instructions(saved)
@@ -1,12 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'operation_preparers/gql_name_setter'
4
- require_relative 'operation_preparers/mutation_field_setter'
5
- require_relative 'operation_preparers/resolver_type_setter'
6
- require_relative 'operation_preparers/resource_klass_setter'
7
- require_relative 'operation_preparers/default_operation_preparer'
8
- require_relative 'operation_preparers/custom_operation_preparer'
9
-
10
3
  module GraphqlDevise
11
4
  module MountMethod
12
5
  class OperationPreparer
@@ -11,7 +11,7 @@ module GraphqlDevise
11
11
  end
12
12
 
13
13
  def call
14
- mapping_name = GraphqlDevise.to_mapping_name(@model)
14
+ mapping_name = ::GraphqlDevise.to_mapping_name(@model)
15
15
 
16
16
  @custom_operations.slice(*@selected_keys).each_with_object({}) do |(action, operation), result|
17
17
  mapped_action = "#{mapping_name}_#{action}"
@@ -12,7 +12,7 @@ module GraphqlDevise
12
12
  end
13
13
 
14
14
  def call
15
- mapping_name = GraphqlDevise.to_mapping_name(@model)
15
+ mapping_name = ::GraphqlDevise.to_mapping_name(@model)
16
16
 
17
17
  @selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
18
18
  mapped_action = "#{mapping_name}_#{action}"
@@ -25,18 +25,6 @@ module GraphqlDevise
25
25
  else
26
26
  @default
27
27
  end
28
-
29
- operations.each do |operation, values|
30
- next if values[:deprecation_reason].blank?
31
-
32
- ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
33
- `#{operation}` is deprecated and will be removed in a future version of this gem.
34
- #{values[:deprecation_reason]}
35
-
36
- You can supress this message by skipping `#{operation}` on your ResourceLoader or the
37
- mount_graphql_devise_for method on your routes file.
38
- DEPRECATION
39
- end
40
28
  end
41
29
  end
42
30
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'supported_options'
4
-
5
3
  module GraphqlDevise
6
4
  module MountMethod
7
5
  class OptionSanitizer
@@ -13,11 +13,11 @@ module GraphqlDevise
13
13
  return @default_value if value.blank?
14
14
 
15
15
  unless value.instance_of?(Array)
16
- raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Array expected."
16
+ raise InvalidMountOptionsError, "`#{key}` option has an invalid value. Array expected."
17
17
  end
18
18
 
19
19
  unless value.all? { |element| element.instance_of?(@element_type) }
20
- raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has invalid elements. #{@element_type} expected."
20
+ raise InvalidMountOptionsError, "`#{key}` option has invalid elements. #{@element_type} expected."
21
21
  end
22
22
 
23
23
  value
@@ -12,11 +12,11 @@ module GraphqlDevise
12
12
  return if value.nil?
13
13
 
14
14
  unless value.instance_of?(Class)
15
- raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Class expected."
15
+ raise InvalidMountOptionsError, "`#{key}` option has an invalid value. Class expected."
16
16
  end
17
17
 
18
18
  unless @klass_array.any? { |klass| value.ancestors.include?(klass) }
19
- raise GraphqlDevise::InvalidMountOptionsError,
19
+ raise InvalidMountOptionsError,
20
20
  "`#{key}` option has an invalid value. #{@klass_array.join(', ')} or descendants expected. Got #{value}."
21
21
  end
22
22
 
@@ -13,7 +13,7 @@ module GraphqlDevise
13
13
  return @default_value if value.blank?
14
14
 
15
15
  unless value.instance_of?(Hash)
16
- raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got #{value.class}."
16
+ raise InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got #{value.class}."
17
17
  end
18
18
 
19
19
  value.each { |internal_key, klass| ClassChecker.new(@element_type_array).call!(klass, "#{key} -> #{internal_key}") }
@@ -12,7 +12,7 @@ module GraphqlDevise
12
12
  return @default_string if value.blank?
13
13
 
14
14
  unless value.instance_of?(String)
15
- raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. String expected."
15
+ raise InvalidMountOptionsError, "`#{key}` option has an invalid value. String expected."
16
16
  end
17
17
 
18
18
  value
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'supported_operations_validator'
4
-
5
3
  module GraphqlDevise
6
4
  module MountMethod
7
5
  module OptionValidators
@@ -11,7 +11,7 @@ module GraphqlDevise
11
11
  def validate!
12
12
  if [@options.skip, @options.only].all?(&:present?)
13
13
  raise(
14
- GraphqlDevise::InvalidMountOptionsError,
14
+ InvalidMountOptionsError,
15
15
  "Can't specify both `skip` and `only` options when mounting the route."
16
16
  )
17
17
  end
@@ -15,7 +15,7 @@ module GraphqlDevise
15
15
 
16
16
  if unsupported_operations.present?
17
17
  raise(
18
- GraphqlDevise::InvalidMountOptionsError,
18
+ InvalidMountOptionsError,
19
19
  "#{@key} option contains unsupported operations: \"#{unsupported_operations.join(', ')}\". Check for typos."
20
20
  )
21
21
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'option_validators/skip_only_validator'
4
- require_relative 'option_validators/provided_operations_validator'
5
-
6
3
  module GraphqlDevise
7
4
  module MountMethod
8
5
  class OptionsValidator
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'option_sanitizers/array_checker'
4
- require_relative 'option_sanitizers/hash_checker'
5
- require_relative 'option_sanitizers/string_checker'
6
- require_relative 'option_sanitizers/class_checker'
7
-
8
3
  module GraphqlDevise
9
4
  module MountMethod
10
5
  SUPPORTED_OPTIONS = {
@@ -5,7 +5,7 @@ require 'devise_token_auth/version'
5
5
  module GraphqlDevise
6
6
  module Mutations
7
7
  class Base < GraphQL::Schema::Mutation
8
- include Concerns::ControllerMethods
8
+ include ControllerMethods
9
9
  end
10
10
  end
11
11
  end
@@ -6,7 +6,7 @@ module GraphqlDevise
6
6
  argument :confirmation_token, String, required: true
7
7
 
8
8
  field :credentials,
9
- GraphqlDevise::Types::CredentialType,
9
+ Types::CredentialType,
10
10
  null: true,
11
11
  description: 'Authentication credentials. Null unless user is signed in after confirmation.'
12
12
 
@@ -6,7 +6,7 @@ module GraphqlDevise
6
6
  argument :email, String, required: true
7
7
  argument :password, String, required: true
8
8
 
9
- field :credentials, GraphqlDevise::Types::CredentialType, null: false
9
+ field :credentials, Types::CredentialType, null: false
10
10
 
11
11
  def resolve(email:, password:)
12
12
  resource = find_resource(
@@ -9,7 +9,7 @@ module GraphqlDevise
9
9
  argument :confirm_url, String, required: false
10
10
 
11
11
  field :credentials,
12
- GraphqlDevise::Types::CredentialType,
12
+ Types::CredentialType,
13
13
  null: true,
14
14
  description: 'Authentication credentials. Null if after signUp resource is not active for authentication (e.g. Email confirmation required).'
15
15
 
@@ -8,7 +8,7 @@ module GraphqlDevise
8
8
  argument :reset_password_token, String, required: true
9
9
 
10
10
  field :credentials,
11
- GraphqlDevise::Types::CredentialType,
11
+ Types::CredentialType,
12
12
  null: true,
13
13
  description: 'Authentication credentials. Resource must be signed_in for credentials to be returned.'
14
14
 
@@ -5,7 +5,7 @@ require 'devise_token_auth/version'
5
5
  module GraphqlDevise
6
6
  module Resolvers
7
7
  class Base < GraphQL::Schema::Resolver
8
- include Concerns::ControllerMethods
8
+ include ControllerMethods
9
9
  end
10
10
  end
11
11
  end
@@ -6,95 +6,127 @@ module GraphqlDevise
6
6
  @resource = resource
7
7
  @options = options
8
8
  @routing = routing
9
- @default_operations = GraphqlDevise::DefaultOperations::MUTATIONS.merge(GraphqlDevise::DefaultOperations::QUERIES)
9
+ @default_operations = DefaultOperations::MUTATIONS.merge(DefaultOperations::QUERIES)
10
10
  end
11
11
 
12
12
  def call(query, mutation)
13
13
  # clean_options responds to all keys defined in GraphqlDevise::MountMethod::SUPPORTED_OPTIONS
14
- clean_options = GraphqlDevise::MountMethod::OptionSanitizer.new(@options).call!
14
+ clean_options = MountMethod::OptionSanitizer.new(@options).call!
15
15
 
16
- model = if @resource.is_a?(String)
17
- ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
18
- Providing a String as the model you want to mount is deprecated and will be removed in a future version of
19
- this gem. Please use the actual model constant instead.
20
-
21
- EXAMPLE
22
-
23
- GraphqlDevise::ResourceLoader.new(User) # instead of GraphqlDevise::ResourceLoader.new('User')
24
-
25
- mount_graphql_devise_for User # instead of mount_graphql_devise_for 'User'
26
- DEPRECATION
27
- @resource.constantize
28
- else
29
- @resource
16
+ unless @resource.is_a?(Class)
17
+ raise(
18
+ InvalidMountOptionsError,
19
+ 'A class must be provided when mounting a model. String values are no longer supported.'
20
+ )
30
21
  end
31
22
 
32
23
  # Necesary when mounting a resource via route file as Devise forces the reloading of routes
33
- return clean_options if GraphqlDevise.resource_mounted?(model) && @routing
24
+ return clean_options if ::GraphqlDevise.resource_mounted?(@resource) && @routing
34
25
 
35
26
  validate_options!(clean_options)
36
27
 
37
28
  authenticatable_type = clean_options.authenticatable_type.presence ||
38
29
  "Types::#{@resource}Type".safe_constantize ||
39
- GraphqlDevise::Types::AuthenticatableType
30
+ Types::AuthenticatableType
40
31
 
41
- prepared_mutations = prepare_mutations(model, clean_options, authenticatable_type)
32
+ prepared_mutations = prepare_mutations(@resource, clean_options, authenticatable_type)
42
33
 
43
34
  if prepared_mutations.any? && mutation.blank?
44
- raise GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped'
35
+ raise ::GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped'
45
36
  end
46
37
 
47
- prepared_mutations.each do |action, prepared_mutation|
48
- mutation.field(action, mutation: prepared_mutation, authenticate: false)
38
+ begin
39
+ prepared_mutations.each do |action, prepared_mutation|
40
+ mutation.field(action, mutation: prepared_mutation, authenticate: false)
41
+ end
42
+ rescue ArgumentError
43
+ raise unless Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
44
+
45
+ raise_undefined_field_class_error('MutationType')
49
46
  end
50
47
 
51
- prepared_resolvers = prepare_resolvers(model, clean_options, authenticatable_type)
48
+ prepared_resolvers = prepare_resolvers(@resource, clean_options, authenticatable_type)
52
49
 
53
50
  if prepared_resolvers.any? && query.blank?
54
- raise GraphqlDevise::Error, 'You need to provide a query type unless all queries are skipped'
51
+ raise ::GraphqlDevise::Error, 'You need to provide a query type unless all queries are skipped'
55
52
  end
56
53
 
57
- prepared_resolvers.each do |action, resolver|
58
- query.field(action, resolver: resolver, authenticate: false)
54
+ begin
55
+ prepared_resolvers.each do |action, resolver|
56
+ query.field(action, resolver: resolver, authenticate: false)
57
+ end
58
+ rescue ArgumentError
59
+ raise unless Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
60
+
61
+ raise_undefined_field_class_error('QueryType')
59
62
  end
60
63
 
61
- GraphqlDevise.add_mapping(GraphqlDevise.to_mapping_name(@resource).to_sym, @resource)
62
- GraphqlDevise.mount_resource(model) if @routing
64
+ ::GraphqlDevise.add_mapping(::GraphqlDevise.to_mapping_name(@resource).to_sym, @resource)
65
+ ::GraphqlDevise.mount_resource(@resource) if @routing
63
66
 
64
67
  clean_options
65
68
  end
66
69
 
67
70
  private
68
71
 
72
+ def raise_undefined_field_class_error(type_class)
73
+ raise(
74
+ GraphqlDevise::Error,
75
+ <<~MESSAGE
76
+ To use this gem with graphql >= 2.0 you need to use a custom `field_class`
77
+ on your #{type_class}. You can use the `field_class` defined in this gem like this:
78
+
79
+ module Types
80
+ class #{type_class} < GraphQL::Schema::Object
81
+ field_class GraphqlDevise::Types::BaseField
82
+ end
83
+ end
84
+
85
+ If you already have a `field_class` set on your #{type_class}, you can include our concern
86
+ to make this work
87
+
88
+ module Types
89
+ class BaseField < GraphQL::Schema::Field
90
+ include GraphqlDevise::FieldAuthentication
91
+ end
92
+ end
93
+
94
+ The concern will define an initializer, if your custom field logic is not standard, you can look
95
+ at the `GraphqlDevise::FieldAuthentication` implementation to add what is required to your own
96
+ field class
97
+ MESSAGE
98
+ )
99
+ end
100
+
69
101
  def prepare_resolvers(model, clean_options, authenticatable_type)
70
- GraphqlDevise::MountMethod::OperationPreparer.new(
102
+ MountMethod::OperationPreparer.new(
71
103
  model: model,
72
104
  custom: clean_options.operations,
73
105
  additional_operations: clean_options.additional_queries,
74
- preparer: GraphqlDevise::MountMethod::OperationPreparers::ResolverTypeSetter.new(authenticatable_type),
75
- selected_operations: GraphqlDevise::MountMethod::OperationSanitizer.call(
76
- default: GraphqlDevise::DefaultOperations::QUERIES, only: clean_options.only, skipped: clean_options.skip
106
+ preparer: MountMethod::OperationPreparers::ResolverTypeSetter.new(authenticatable_type),
107
+ selected_operations: MountMethod::OperationSanitizer.call(
108
+ default: DefaultOperations::QUERIES, only: clean_options.only, skipped: clean_options.skip
77
109
  )
78
110
  ).call
79
111
  end
80
112
 
81
113
  def prepare_mutations(model, clean_options, authenticatable_type)
82
- GraphqlDevise::MountMethod::OperationPreparer.new(
114
+ MountMethod::OperationPreparer.new(
83
115
  model: model,
84
116
  custom: clean_options.operations,
85
117
  additional_operations: clean_options.additional_mutations,
86
- preparer: GraphqlDevise::MountMethod::OperationPreparers::MutationFieldSetter.new(authenticatable_type),
87
- selected_operations: GraphqlDevise::MountMethod::OperationSanitizer.call(
88
- default: GraphqlDevise::DefaultOperations::MUTATIONS, only: clean_options.only, skipped: clean_options.skip
118
+ preparer: MountMethod::OperationPreparers::MutationFieldSetter.new(authenticatable_type),
119
+ selected_operations: MountMethod::OperationSanitizer.call(
120
+ default: DefaultOperations::MUTATIONS, only: clean_options.only, skipped: clean_options.skip
89
121
  )
90
122
  ).call
91
123
  end
92
124
 
93
125
  def validate_options!(clean_options)
94
- GraphqlDevise::MountMethod::OptionsValidator.new(
126
+ MountMethod::OptionsValidator.new(
95
127
  [
96
- GraphqlDevise::MountMethod::OptionValidators::SkipOnlyValidator.new(options: clean_options),
97
- GraphqlDevise::MountMethod::OptionValidators::ProvidedOperationsValidator.new(
128
+ MountMethod::OptionValidators::SkipOnlyValidator.new(options: clean_options),
129
+ MountMethod::OptionValidators::ProvidedOperationsValidator.new(
98
130
  options: clean_options, supported_operations: @default_operations
99
131
  )
100
132
  ]
@@ -0,0 +1,13 @@
1
+ module GraphqlDevise
2
+ module RouteMounter
3
+ def mount_graphql_devise_for(resource, options = {})
4
+ clean_options = ResourceLoader.new(resource, options, true).call(
5
+ Types::QueryType,
6
+ Types::MutationType
7
+ )
8
+
9
+ post clean_options.at, to: 'graphql_devise/graphql#auth'
10
+ get clean_options.at, to: 'graphql_devise/graphql#auth'
11
+ end
12
+ end
13
+ end
@@ -4,7 +4,7 @@ module GraphqlDevise
4
4
  class SchemaPlugin
5
5
  # NOTE: Based on GQL-Ruby docs https://graphql-ruby.org/schema/introspection.html
6
6
  INTROSPECTION_FIELDS = ['__schema', '__type', '__typename']
7
- DEFAULT_NOT_AUTHENTICATED = ->(field) { raise GraphqlDevise::AuthenticationError, "#{field} field requires authentication" }
7
+ DEFAULT_NOT_AUTHENTICATED = ->(field) { raise AuthenticationError, "#{field} field requires authentication" }
8
8
 
9
9
  def initialize(query: nil, mutation: nil, authenticate_default: true, public_introspection: !Rails.env.production?, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
10
10
  @query = query
@@ -30,22 +30,7 @@ module GraphqlDevise
30
30
  auth_required = authenticate_option(field, trace_data)
31
31
  context = context_from_data(trace_data)
32
32
 
33
- if context.key?(:resource_name)
34
- ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
35
- Providing `resource_name` as part of the GQL context, or doing so by using the `graphql_context(resource_name)`
36
- method on your controller is deprecated and will be removed in a future version of this gem.
37
- Please use `gql_devise_context` in you controller instead.
38
-
39
- EXAMPLE
40
- include GraphqlDevise::SetUserByToken
41
-
42
- DummySchema.execute(params[:query], context: gql_devise_context(User))
43
- DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
44
- DEPRECATION
45
- end
46
-
47
33
  if auth_required && !(public_introspection && introspection_field?(field))
48
- context = set_current_resource(context)
49
34
  raise_on_missing_resource(context, field, auth_required)
50
35
  end
51
36
 
@@ -56,25 +41,6 @@ module GraphqlDevise
56
41
 
57
42
  attr_reader :public_introspection
58
43
 
59
- def set_current_resource(context)
60
- controller = context[:controller]
61
- resource_names = Array(context[:resource_name])
62
-
63
- context[:current_resource] ||= resource_names.find do |resource_name|
64
- unless Devise.mappings.key?(resource_name)
65
- raise(
66
- GraphqlDevise::Error,
67
- "Invalid resource_name `#{resource_name}` provided to `graphql_context`. Possible values are: #{Devise.mappings.keys}."
68
- )
69
- end
70
-
71
- found = controller.set_resource_by_token(resource_name)
72
- break found if found
73
- end
74
-
75
- context
76
- end
77
-
78
44
  def raise_on_missing_resource(context, field, auth_required)
79
45
  @unauthenticated_proc.call(field.name) if context[:current_resource].blank?
80
46
 
@@ -113,7 +79,11 @@ module GraphqlDevise
113
79
  auth_required = if trace_data[:context]
114
80
  field.metadata[:authenticate]
115
81
  else
116
- if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.13.1')
82
+ if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
83
+ # authenticate will only be defined if "field_class GraphqlDevise::Types::BaseField" is added to the type
84
+ # returning nil here will use the default value used when mounting the plugin
85
+ field.try(:authenticate)
86
+ elsif Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.13.1')
117
87
  field.graphql_definition(silence_deprecation_warning: true).metadata[:authenticate]
118
88
  else
119
89
  field.graphql_definition.metadata[:authenticate]
@@ -125,7 +95,7 @@ module GraphqlDevise
125
95
 
126
96
  def load_fields
127
97
  @resource_loaders.each do |resource_loader|
128
- raise Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(GraphqlDevise::ResourceLoader)
98
+ raise ::GraphqlDevise::Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(ResourceLoader)
129
99
 
130
100
  resource_loader.call(@query, @mutation)
131
101
  end
@@ -136,6 +106,3 @@ module GraphqlDevise
136
106
  end
137
107
  end
138
108
  end
139
-
140
- GraphQL::Field.accepts_definitions(authenticate: GraphQL::Define.assign_metadata_key(:authenticate))
141
- GraphQL::Schema::Field.accepts_definition(:authenticate)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GraphqlDevise
4
4
  module Types
5
- class AuthenticatableType < GraphQL::Schema::Object
5
+ class AuthenticatableType < BaseType
6
6
  field :email, String, null: false
7
7
  end
8
8
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlDevise
4
+ module Types
5
+ class BaseField < GraphQL::Schema::Field
6
+ include FieldAuthentication
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlDevise
4
+ module Types
5
+ class BaseType < GraphQL::Schema::Object
6
+ end
7
+ end
8
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GraphqlDevise
4
4
  module Types
5
- class CredentialType < GraphQL::Schema::Object
5
+ class CredentialType < BaseType
6
6
  field :access_token, String, null: false
7
7
  field :uid, String, null: false
8
8
  field :token_type, String, null: false
@@ -3,6 +3,7 @@
3
3
  module GraphqlDevise
4
4
  module Types
5
5
  class MutationType < GraphQL::Schema::Object
6
+ field_class GraphqlDevise::Types::BaseField if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
6
7
  end
7
8
  end
8
9
  end