graphql_devise 0.18.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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