graphql_devise 0.14.1 → 0.17.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +118 -0
- data/Appraisals +26 -6
- data/CHANGELOG.md +72 -6
- data/README.md +184 -69
- data/Rakefile +2 -1
- data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +72 -0
- data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +5 -27
- data/app/controllers/graphql_devise/graphql_controller.rb +1 -1
- data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
- data/app/models/graphql_devise/concerns/additional_model_methods.rb +21 -0
- data/app/models/graphql_devise/concerns/model.rb +6 -9
- data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +7 -1
- data/graphql_devise.gemspec +1 -1
- data/lib/generators/graphql_devise/install_generator.rb +1 -1
- data/lib/graphql_devise.rb +20 -6
- data/lib/graphql_devise/concerns/controller_methods.rb +3 -3
- data/lib/graphql_devise/default_operations/mutations.rb +14 -8
- data/lib/graphql_devise/default_operations/resolvers.rb +2 -2
- data/lib/graphql_devise/model/with_email_updater.rb +34 -8
- data/lib/graphql_devise/mount_method/operation_preparer.rb +6 -6
- data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +6 -4
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +7 -5
- data/lib/graphql_devise/mount_method/operation_preparers/{resource_name_setter.rb → resource_klass_setter.rb} +4 -4
- data/lib/graphql_devise/mount_method/operation_sanitizer.rb +13 -1
- data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +30 -0
- data/lib/graphql_devise/mutations/register.rb +60 -0
- data/lib/graphql_devise/mutations/resend_confirmation_with_token.rb +44 -0
- data/lib/graphql_devise/mutations/sign_up.rb +1 -1
- data/lib/graphql_devise/resolvers/confirm_account.rb +1 -1
- data/lib/graphql_devise/resource_loader.rb +26 -11
- data/lib/graphql_devise/schema_plugin.rb +31 -10
- data/lib/graphql_devise/version.rb +1 -1
- data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +13 -2
- data/spec/dummy/app/graphql/dummy_schema.rb +8 -6
- data/spec/dummy/app/graphql/mutations/register.rb +14 -0
- data/spec/dummy/app/graphql/types/query_type.rb +5 -0
- data/spec/dummy/config/routes.rb +7 -5
- data/spec/dummy/db/migrate/20200623003142_create_schema_users.rb +0 -1
- data/spec/dummy/db/migrate/20210516211417_add_vip_to_users.rb +5 -0
- data/spec/dummy/db/schema.rb +4 -4
- data/spec/generators/graphql_devise/install_generator_spec.rb +1 -1
- data/spec/graphql/user_queries_spec.rb +3 -1
- data/spec/graphql_devise/model/with_email_updater_spec.rb +97 -68
- data/spec/requests/graphql_controller_spec.rb +12 -11
- data/spec/requests/mutations/confirm_registration_with_token_spec.rb +117 -0
- data/spec/requests/mutations/register_spec.rb +166 -0
- data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +137 -0
- data/spec/requests/queries/introspection_query_spec.rb +149 -0
- data/spec/requests/user_controller_spec.rb +86 -25
- data/spec/services/mount_method/operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/{resource_name_setter_spec.rb → resource_klass_setter_spec.rb} +6 -6
- data/spec/services/mount_method/operation_sanitizer_spec.rb +3 -3
- data/spec/services/resource_loader_spec.rb +5 -5
- data/spec/support/contexts/graphql_request.rb +11 -3
- metadata +29 -12
- data/.travis.yml +0 -86
@@ -4,19 +4,21 @@ module GraphqlDevise
|
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
6
|
class CustomOperationPreparer
|
7
|
-
def initialize(selected_keys:, custom_operations:,
|
7
|
+
def initialize(selected_keys:, custom_operations:, model:)
|
8
8
|
@selected_keys = selected_keys
|
9
9
|
@custom_operations = custom_operations
|
10
|
-
@
|
10
|
+
@model = model
|
11
11
|
end
|
12
12
|
|
13
13
|
def call
|
14
|
+
mapping_name = GraphqlDevise.to_mapping_name(@model)
|
15
|
+
|
14
16
|
@custom_operations.slice(*@selected_keys).each_with_object({}) do |(action, operation), result|
|
15
|
-
mapped_action = "#{
|
17
|
+
mapped_action = "#{mapping_name}_#{action}"
|
16
18
|
|
17
19
|
result[mapped_action.to_sym] = [
|
18
20
|
OperationPreparers::GqlNameSetter.new(mapped_action),
|
19
|
-
OperationPreparers::
|
21
|
+
OperationPreparers::ResourceKlassSetter.new(@model)
|
20
22
|
].reduce(operation) { |prepared_operation, preparer| preparer.call(prepared_operation) }
|
21
23
|
end
|
22
24
|
end
|
@@ -4,23 +4,25 @@ module GraphqlDevise
|
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
6
|
class DefaultOperationPreparer
|
7
|
-
def initialize(selected_operations:, custom_keys:,
|
7
|
+
def initialize(selected_operations:, custom_keys:, model:, preparer:)
|
8
8
|
@selected_operations = selected_operations
|
9
9
|
@custom_keys = custom_keys
|
10
|
-
@
|
10
|
+
@model = model
|
11
11
|
@preparer = preparer
|
12
12
|
end
|
13
13
|
|
14
14
|
def call
|
15
|
+
mapping_name = GraphqlDevise.to_mapping_name(@model)
|
16
|
+
|
15
17
|
@selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
|
16
|
-
mapped_action = "#{
|
18
|
+
mapped_action = "#{mapping_name}_#{action}"
|
17
19
|
operation = operation_info[:klass]
|
18
|
-
options = operation_info.except(:klass)
|
20
|
+
options = operation_info.except(:klass, :deprecation_reason)
|
19
21
|
|
20
22
|
result[mapped_action.to_sym] = [
|
21
23
|
OperationPreparers::GqlNameSetter.new(mapped_action),
|
22
24
|
@preparer,
|
23
|
-
OperationPreparers::
|
25
|
+
OperationPreparers::ResourceKlassSetter.new(@model)
|
24
26
|
].reduce(child_class(operation)) do |prepared_operation, preparer|
|
25
27
|
preparer.call(prepared_operation, **options)
|
26
28
|
end
|
@@ -3,13 +3,13 @@
|
|
3
3
|
module GraphqlDevise
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
|
-
class
|
7
|
-
def initialize(
|
8
|
-
@
|
6
|
+
class ResourceKlassSetter
|
7
|
+
def initialize(klass)
|
8
|
+
@klass = klass
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(operation, **)
|
12
|
-
operation.instance_variable_set(:@
|
12
|
+
operation.instance_variable_set(:@resource_klass, @klass)
|
13
13
|
|
14
14
|
operation
|
15
15
|
end
|
@@ -18,13 +18,25 @@ module GraphqlDevise
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def call
|
21
|
-
if @only.present?
|
21
|
+
operations = if @only.present?
|
22
22
|
@default.slice(*@only)
|
23
23
|
elsif @skipped.present?
|
24
24
|
@default.except(*@skipped)
|
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
|
28
40
|
end
|
29
41
|
end
|
30
42
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlDevise
|
4
|
+
module Mutations
|
5
|
+
class ConfirmRegistrationWithToken < Base
|
6
|
+
argument :confirmation_token, String, required: true
|
7
|
+
|
8
|
+
field :credentials,
|
9
|
+
GraphqlDevise::Types::CredentialType,
|
10
|
+
null: true,
|
11
|
+
description: 'Authentication credentials. Null unless user is signed in after confirmation.'
|
12
|
+
|
13
|
+
def resolve(confirmation_token:)
|
14
|
+
resource = resource_class.confirm_by_token(confirmation_token)
|
15
|
+
|
16
|
+
if resource.errors.empty?
|
17
|
+
yield resource if block_given?
|
18
|
+
|
19
|
+
response_payload = { authenticatable: resource }
|
20
|
+
|
21
|
+
response_payload[:credentials] = set_auth_headers(resource) if resource.active_for_authentication?
|
22
|
+
|
23
|
+
response_payload
|
24
|
+
else
|
25
|
+
raise_user_error(I18n.t('graphql_devise.confirmations.invalid_token'))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlDevise
|
4
|
+
module Mutations
|
5
|
+
class Register < Base
|
6
|
+
argument :email, String, required: true
|
7
|
+
argument :password, String, required: true
|
8
|
+
argument :password_confirmation, String, required: true
|
9
|
+
argument :confirm_url, String, required: false
|
10
|
+
|
11
|
+
field :credentials,
|
12
|
+
GraphqlDevise::Types::CredentialType,
|
13
|
+
null: true,
|
14
|
+
description: 'Authentication credentials. Null if after signUp resource is not active for authentication (e.g. Email confirmation required).'
|
15
|
+
|
16
|
+
def resolve(confirm_url: nil, **attrs)
|
17
|
+
resource = build_resource(attrs.merge(provider: provider))
|
18
|
+
raise_user_error(I18n.t('graphql_devise.resource_build_failed')) if resource.blank?
|
19
|
+
|
20
|
+
redirect_url = confirm_url || DeviseTokenAuth.default_confirm_success_url
|
21
|
+
if confirmable_enabled? && redirect_url.blank?
|
22
|
+
raise_user_error(I18n.t('graphql_devise.registrations.missing_confirm_redirect_url'))
|
23
|
+
end
|
24
|
+
|
25
|
+
check_redirect_url_whitelist!(redirect_url)
|
26
|
+
|
27
|
+
resource.skip_confirmation_notification! if resource.respond_to?(:skip_confirmation_notification!)
|
28
|
+
|
29
|
+
if resource.save
|
30
|
+
yield resource if block_given?
|
31
|
+
|
32
|
+
unless resource.confirmed?
|
33
|
+
resource.send_confirmation_instructions(
|
34
|
+
redirect_url: redirect_url,
|
35
|
+
template_path: ['graphql_devise/mailer']
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
response_payload = { authenticatable: resource }
|
40
|
+
|
41
|
+
response_payload[:credentials] = set_auth_headers(resource) if resource.active_for_authentication?
|
42
|
+
|
43
|
+
response_payload
|
44
|
+
else
|
45
|
+
resource.try(:clean_up_passwords)
|
46
|
+
raise_user_error_list(
|
47
|
+
I18n.t('graphql_devise.registration_failed'),
|
48
|
+
errors: resource.errors.full_messages
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def build_resource(attrs)
|
56
|
+
resource_class.new(attrs)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlDevise
|
4
|
+
module Mutations
|
5
|
+
class ResendConfirmationWithToken < Base
|
6
|
+
argument :email, String, required: true
|
7
|
+
argument :confirm_url, String, required: true
|
8
|
+
|
9
|
+
field :message, String, null: false
|
10
|
+
|
11
|
+
def resolve(email:, confirm_url:)
|
12
|
+
check_redirect_url_whitelist!(confirm_url)
|
13
|
+
|
14
|
+
resource = find_confirmable_resource(email)
|
15
|
+
|
16
|
+
if resource
|
17
|
+
yield resource if block_given?
|
18
|
+
|
19
|
+
if resource.confirmed? && !resource.pending_reconfirmation?
|
20
|
+
raise_user_error(I18n.t('graphql_devise.confirmations.already_confirmed'))
|
21
|
+
end
|
22
|
+
|
23
|
+
resource.send_confirmation_instructions(
|
24
|
+
redirect_url: confirm_url,
|
25
|
+
template_path: ['graphql_devise/mailer']
|
26
|
+
)
|
27
|
+
|
28
|
+
{ message: I18n.t('graphql_devise.confirmations.send_instructions', email: email) }
|
29
|
+
else
|
30
|
+
raise_user_error(I18n.t('graphql_devise.confirmations.user_not_found', email: email))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def find_confirmable_resource(email)
|
37
|
+
email_insensitive = get_case_insensitive_field(:email, email)
|
38
|
+
resource = find_resource(:unconfirmed_email, email_insensitive) if resource_class.reconfirmable
|
39
|
+
resource ||= find_resource(:email, email_insensitive)
|
40
|
+
resource
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -31,7 +31,7 @@ module GraphqlDevise
|
|
31
31
|
|
32
32
|
unless resource.confirmed?
|
33
33
|
resource.send_confirmation_instructions(
|
34
|
-
redirect_url:
|
34
|
+
redirect_url: redirect_url,
|
35
35
|
template_path: ['graphql_devise/mailer'],
|
36
36
|
schema_url: controller.full_url_without_params
|
37
37
|
)
|
@@ -10,12 +10,27 @@ module GraphqlDevise
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(query, mutation)
|
13
|
-
mapping_name = @resource.to_s.underscore.tr('/', '_').to_sym
|
14
|
-
|
15
13
|
# clean_options responds to all keys defined in GraphqlDevise::MountMethod::SUPPORTED_OPTIONS
|
16
14
|
clean_options = GraphqlDevise::MountMethod::OptionSanitizer.new(@options).call!
|
17
15
|
|
18
|
-
|
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
|
30
|
+
end
|
31
|
+
|
32
|
+
# 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
|
19
34
|
|
20
35
|
validate_options!(clean_options)
|
21
36
|
|
@@ -23,7 +38,7 @@ module GraphqlDevise
|
|
23
38
|
"Types::#{@resource}Type".safe_constantize ||
|
24
39
|
GraphqlDevise::Types::AuthenticatableType
|
25
40
|
|
26
|
-
prepared_mutations = prepare_mutations(
|
41
|
+
prepared_mutations = prepare_mutations(model, clean_options, authenticatable_type)
|
27
42
|
|
28
43
|
if prepared_mutations.any? && mutation.blank?
|
29
44
|
raise GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped'
|
@@ -33,7 +48,7 @@ module GraphqlDevise
|
|
33
48
|
mutation.field(action, mutation: prepared_mutation, authenticate: false)
|
34
49
|
end
|
35
50
|
|
36
|
-
prepared_resolvers = prepare_resolvers(
|
51
|
+
prepared_resolvers = prepare_resolvers(model, clean_options, authenticatable_type)
|
37
52
|
|
38
53
|
if prepared_resolvers.any? && query.blank?
|
39
54
|
raise GraphqlDevise::Error, 'You need to provide a query type unless all queries are skipped'
|
@@ -43,17 +58,17 @@ module GraphqlDevise
|
|
43
58
|
query.field(action, resolver: resolver, authenticate: false)
|
44
59
|
end
|
45
60
|
|
46
|
-
GraphqlDevise.add_mapping(
|
47
|
-
GraphqlDevise.mount_resource(
|
61
|
+
GraphqlDevise.add_mapping(GraphqlDevise.to_mapping_name(@resource).to_sym, @resource)
|
62
|
+
GraphqlDevise.mount_resource(model) if @routing
|
48
63
|
|
49
64
|
clean_options
|
50
65
|
end
|
51
66
|
|
52
67
|
private
|
53
68
|
|
54
|
-
def prepare_resolvers(
|
69
|
+
def prepare_resolvers(model, clean_options, authenticatable_type)
|
55
70
|
GraphqlDevise::MountMethod::OperationPreparer.new(
|
56
|
-
|
71
|
+
model: model,
|
57
72
|
custom: clean_options.operations,
|
58
73
|
additional_operations: clean_options.additional_queries,
|
59
74
|
preparer: GraphqlDevise::MountMethod::OperationPreparers::ResolverTypeSetter.new(authenticatable_type),
|
@@ -63,9 +78,9 @@ module GraphqlDevise
|
|
63
78
|
).call
|
64
79
|
end
|
65
80
|
|
66
|
-
def prepare_mutations(
|
81
|
+
def prepare_mutations(model, clean_options, authenticatable_type)
|
67
82
|
GraphqlDevise::MountMethod::OperationPreparer.new(
|
68
|
-
|
83
|
+
model: model,
|
69
84
|
custom: clean_options.operations,
|
70
85
|
additional_operations: clean_options.additional_mutations,
|
71
86
|
preparer: GraphqlDevise::MountMethod::OperationPreparers::MutationFieldSetter.new(authenticatable_type),
|
@@ -2,18 +2,20 @@
|
|
2
2
|
|
3
3
|
module GraphqlDevise
|
4
4
|
class SchemaPlugin
|
5
|
+
# NOTE: Based on GQL-Ruby docs https://graphql-ruby.org/schema/introspection.html
|
6
|
+
INTROSPECTION_FIELDS = ['__schema', '__type', '__typename']
|
5
7
|
DEFAULT_NOT_AUTHENTICATED = ->(field) { raise GraphqlDevise::AuthenticationError, "#{field} field requires authentication" }
|
6
8
|
|
7
|
-
def initialize(query: nil, mutation: nil, authenticate_default: true, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
|
9
|
+
def initialize(query: nil, mutation: nil, authenticate_default: true, public_introspection: !Rails.env.production?, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
|
8
10
|
@query = query
|
9
11
|
@mutation = mutation
|
10
12
|
@resource_loaders = resource_loaders
|
11
13
|
@authenticate_default = authenticate_default
|
14
|
+
@public_introspection = public_introspection
|
12
15
|
@unauthenticated_proc = unauthenticated_proc
|
13
16
|
|
14
17
|
# Must happen on initialize so operations are loaded before the types are added to the schema on GQL < 1.10
|
15
18
|
load_fields
|
16
|
-
reconfigure_warden!
|
17
19
|
end
|
18
20
|
|
19
21
|
def use(schema_definition)
|
@@ -28,9 +30,23 @@ module GraphqlDevise
|
|
28
30
|
auth_required = authenticate_option(field, trace_data)
|
29
31
|
context = context_from_data(trace_data)
|
30
32
|
|
31
|
-
if
|
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::Concerns::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
|
+
if auth_required && !(public_introspection && introspection_field?(field))
|
32
48
|
context = set_current_resource(context)
|
33
|
-
raise_on_missing_resource(context, field)
|
49
|
+
raise_on_missing_resource(context, field, auth_required)
|
34
50
|
end
|
35
51
|
|
36
52
|
yield
|
@@ -38,6 +54,8 @@ module GraphqlDevise
|
|
38
54
|
|
39
55
|
private
|
40
56
|
|
57
|
+
attr_reader :public_introspection
|
58
|
+
|
41
59
|
def set_current_resource(context)
|
42
60
|
controller = context[:controller]
|
43
61
|
resource_names = Array(context[:resource_name])
|
@@ -57,8 +75,12 @@ module GraphqlDevise
|
|
57
75
|
context
|
58
76
|
end
|
59
77
|
|
60
|
-
def raise_on_missing_resource(context, field)
|
78
|
+
def raise_on_missing_resource(context, field, auth_required)
|
61
79
|
@unauthenticated_proc.call(field.name) if context[:current_resource].blank?
|
80
|
+
|
81
|
+
if auth_required.respond_to?(:call) && !auth_required.call(context[:current_resource])
|
82
|
+
@unauthenticated_proc.call(field.name)
|
83
|
+
end
|
62
84
|
end
|
63
85
|
|
64
86
|
def context_from_data(trace_data)
|
@@ -97,11 +119,6 @@ module GraphqlDevise
|
|
97
119
|
auth_required.nil? ? @authenticate_default : auth_required
|
98
120
|
end
|
99
121
|
|
100
|
-
def reconfigure_warden!
|
101
|
-
Devise.class_variable_set(:@@warden_configured, nil)
|
102
|
-
Devise.configure_warden!
|
103
|
-
end
|
104
|
-
|
105
122
|
def load_fields
|
106
123
|
@resource_loaders.each do |resource_loader|
|
107
124
|
raise Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(GraphqlDevise::ResourceLoader)
|
@@ -109,6 +126,10 @@ module GraphqlDevise
|
|
109
126
|
resource_loader.call(@query, @mutation)
|
110
127
|
end
|
111
128
|
end
|
129
|
+
|
130
|
+
def introspection_field?(field)
|
131
|
+
INTROSPECTION_FIELDS.include?(field.name)
|
132
|
+
end
|
112
133
|
end
|
113
134
|
end
|
114
135
|
|