graphql_devise 0.18.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +25 -2
- data/.gitignore +4 -0
- data/.rubocop.yml +9 -10
- data/Appraisals +72 -35
- data/CHANGELOG.md +63 -0
- data/README.md +71 -142
- data/app/controllers/graphql_devise/graphql_controller.rb +3 -3
- data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +1 -5
- data/config/routes.rb +0 -2
- data/graphql_devise.gemspec +8 -6
- data/lib/generators/graphql_devise/install_generator.rb +1 -1
- data/lib/graphql_devise/concerns/additional_controller_methods.rb +48 -0
- data/lib/graphql_devise/concerns/additional_model_methods.rb +17 -0
- data/lib/graphql_devise/concerns/authenticatable.rb +1 -1
- data/lib/graphql_devise/concerns/controller_methods.rb +79 -91
- data/lib/graphql_devise/concerns/field_authentication.rb +14 -0
- data/lib/graphql_devise/concerns/set_user_by_token.rb +1 -1
- data/lib/graphql_devise/default_operations.rb +16 -0
- data/lib/graphql_devise/engine.rb +0 -2
- data/lib/graphql_devise/model/with_email_updater.rb +5 -30
- data/lib/graphql_devise/mount_method/operation_preparer.rb +0 -7
- data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +1 -1
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
- data/lib/graphql_devise/mount_method/operation_sanitizer.rb +0 -12
- data/lib/graphql_devise/mount_method/option_sanitizer.rb +0 -2
- data/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb +2 -2
- data/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb +2 -2
- data/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb +1 -1
- data/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb +1 -1
- data/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +0 -2
- data/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +1 -1
- data/lib/graphql_devise/mount_method/option_validators/supported_operations_validator.rb +1 -1
- data/lib/graphql_devise/mount_method/options_validator.rb +0 -3
- data/lib/graphql_devise/mount_method/supported_options.rb +0 -5
- data/lib/graphql_devise/mutations/base.rb +1 -1
- data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +2 -2
- data/lib/graphql_devise/mutations/login.rb +2 -2
- data/lib/graphql_devise/mutations/register.rb +2 -2
- data/lib/graphql_devise/mutations/update_password_with_token.rb +2 -2
- data/lib/graphql_devise/resolvers/base.rb +1 -1
- data/lib/graphql_devise/resource_loader.rb +71 -39
- data/lib/graphql_devise/route_mounter.rb +13 -0
- data/lib/graphql_devise/schema_plugin.rb +11 -40
- data/lib/graphql_devise/types/authenticatable_type.rb +1 -1
- data/lib/graphql_devise/types/base_field.rb +9 -0
- data/lib/graphql_devise/types/base_type.rb +8 -0
- data/lib/graphql_devise/types/credential_type.rb +1 -1
- data/lib/graphql_devise/types/mutation_type.rb +1 -0
- data/lib/graphql_devise/types/query_type.rb +1 -0
- data/lib/graphql_devise/version.rb +1 -1
- data/lib/graphql_devise.rb +21 -29
- data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +2 -16
- data/spec/dummy/app/graphql/dummy_schema.rb +1 -5
- data/spec/dummy/app/graphql/interpreter_schema.rb +6 -2
- data/spec/dummy/app/graphql/mutations/base_mutation.rb +6 -0
- data/spec/dummy/app/graphql/mutations/update_user.rb +2 -4
- data/spec/dummy/app/graphql/types/admin_type.rb +1 -1
- data/spec/dummy/app/graphql/types/custom_admin_type.rb +1 -1
- data/spec/dummy/app/graphql/types/mutation_type.rb +3 -1
- data/spec/dummy/app/graphql/types/query_type.rb +3 -1
- data/spec/dummy/app/graphql/types/user_type.rb +1 -1
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/routes.rb +5 -9
- data/spec/generators/graphql_devise/install_generator_spec.rb +2 -2
- data/spec/graphql_devise/model/with_email_updater_spec.rb +17 -35
- data/spec/rails_helper.rb +5 -5
- data/spec/requests/mutations/login_spec.rb +34 -0
- data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +2 -3
- data/spec/requests/user_controller_spec.rb +1 -33
- data/spec/services/resource_loader_spec.rb +53 -3
- data/spec/spec_helper.rb +1 -1
- metadata +62 -55
- data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +0 -72
- data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +0 -21
- data/app/helpers/graphql_devise/mailer_helper.rb +0 -37
- data/app/models/graphql_devise/concerns/additional_model_methods.rb +0 -21
- data/app/models/graphql_devise/concerns/model.rb +0 -25
- data/lib/graphql_devise/default_operations/mutations.rb +0 -32
- data/lib/graphql_devise/default_operations/resolvers.rb +0 -14
- data/lib/graphql_devise/mutations/resend_confirmation.rb +0 -45
- data/lib/graphql_devise/mutations/send_password_reset.rb +0 -38
- data/lib/graphql_devise/mutations/sign_up.rb +0 -61
- data/lib/graphql_devise/mutations/update_password.rb +0 -46
- data/lib/graphql_devise/rails/routes.rb +0 -15
- data/lib/graphql_devise/resolvers/check_password_token.rb +0 -43
- data/lib/graphql_devise/resolvers/confirm_account.rb +0 -42
- data/spec/dummy/app/graphql/mutations/sign_up.rb +0 -14
- data/spec/dummy/app/graphql/resolvers/confirm_admin_account.rb +0 -13
- data/spec/requests/mutations/resend_confirmation_spec.rb +0 -153
- data/spec/requests/mutations/send_password_reset_spec.rb +0 -103
- data/spec/requests/mutations/sign_up_spec.rb +0 -170
- data/spec/requests/mutations/update_password_spec.rb +0 -116
- data/spec/requests/queries/check_password_token_spec.rb +0 -149
- data/spec/requests/queries/confirm_account_spec.rb +0 -137
|
@@ -6,95 +6,127 @@ module GraphqlDevise
|
|
|
6
6
|
@resource = resource
|
|
7
7
|
@options = options
|
|
8
8
|
@routing = routing
|
|
9
|
-
@default_operations =
|
|
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 =
|
|
14
|
+
clean_options = MountMethod::OptionSanitizer.new(@options).call!
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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?(
|
|
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
|
-
|
|
30
|
+
Types::AuthenticatableType
|
|
40
31
|
|
|
41
|
-
prepared_mutations = prepare_mutations(
|
|
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
|
-
|
|
48
|
-
|
|
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(
|
|
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
|
-
|
|
58
|
-
|
|
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(
|
|
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
|
-
|
|
102
|
+
MountMethod::OperationPreparer.new(
|
|
71
103
|
model: model,
|
|
72
104
|
custom: clean_options.operations,
|
|
73
105
|
additional_operations: clean_options.additional_queries,
|
|
74
|
-
preparer:
|
|
75
|
-
selected_operations:
|
|
76
|
-
default:
|
|
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
|
-
|
|
114
|
+
MountMethod::OperationPreparer.new(
|
|
83
115
|
model: model,
|
|
84
116
|
custom: clean_options.operations,
|
|
85
117
|
additional_operations: clean_options.additional_mutations,
|
|
86
|
-
preparer:
|
|
87
|
-
selected_operations:
|
|
88
|
-
default:
|
|
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
|
-
|
|
126
|
+
MountMethod::OptionsValidator.new(
|
|
95
127
|
[
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
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,15 @@ module GraphqlDevise
|
|
|
113
79
|
auth_required = if trace_data[:context]
|
|
114
80
|
field.metadata[:authenticate]
|
|
115
81
|
else
|
|
116
|
-
|
|
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')
|
|
87
|
+
field.graphql_definition(silence_deprecation_warning: true).metadata[:authenticate]
|
|
88
|
+
else
|
|
89
|
+
field.graphql_definition.metadata[:authenticate]
|
|
90
|
+
end
|
|
117
91
|
end
|
|
118
92
|
|
|
119
93
|
auth_required.nil? ? @authenticate_default : auth_required
|
|
@@ -121,7 +95,7 @@ module GraphqlDevise
|
|
|
121
95
|
|
|
122
96
|
def load_fields
|
|
123
97
|
@resource_loaders.each do |resource_loader|
|
|
124
|
-
raise Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(
|
|
98
|
+
raise ::GraphqlDevise::Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(ResourceLoader)
|
|
125
99
|
|
|
126
100
|
resource_loader.call(@query, @mutation)
|
|
127
101
|
end
|
|
@@ -132,6 +106,3 @@ module GraphqlDevise
|
|
|
132
106
|
end
|
|
133
107
|
end
|
|
134
108
|
end
|
|
135
|
-
|
|
136
|
-
GraphQL::Field.accepts_definitions(authenticate: GraphQL::Define.assign_metadata_key(:authenticate))
|
|
137
|
-
GraphQL::Schema::Field.accepts_definition(:authenticate)
|
data/lib/graphql_devise.rb
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rails'
|
|
4
|
+
require 'rails/generators'
|
|
4
5
|
require 'graphql'
|
|
5
6
|
require 'devise_token_auth'
|
|
7
|
+
require 'zeitwerk'
|
|
8
|
+
|
|
9
|
+
if Gem::Version.new(GraphQL::VERSION) < Gem::Version.new('2.0')
|
|
10
|
+
GraphQL::Field.accepts_definitions(authenticate: GraphQL::Define.assign_metadata_key(:authenticate))
|
|
11
|
+
GraphQL::Schema::Field.accepts_definition(:authenticate)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
loader = Zeitwerk::Loader.for_gem
|
|
15
|
+
|
|
16
|
+
loader.collapse("#{__dir__}/graphql_devise/concerns")
|
|
17
|
+
loader.collapse("#{__dir__}/graphql_devise/errors")
|
|
18
|
+
loader.ignore("#{__dir__}/generators")
|
|
19
|
+
|
|
20
|
+
loader.inflector.inflect('error_codes' => 'ERROR_CODES')
|
|
21
|
+
loader.inflector.inflect('supported_options' => 'SUPPORTED_OPTIONS')
|
|
22
|
+
|
|
23
|
+
loader.setup
|
|
6
24
|
|
|
7
25
|
module GraphqlDevise
|
|
8
26
|
class Error < StandardError; end
|
|
9
27
|
|
|
10
|
-
class InvalidMountOptionsError < GraphqlDevise::Error; end
|
|
28
|
+
class InvalidMountOptionsError < ::GraphqlDevise::Error; end
|
|
11
29
|
|
|
12
30
|
@schema_loaded = false
|
|
13
31
|
@mounted_resources = []
|
|
@@ -52,32 +70,6 @@ module GraphqlDevise
|
|
|
52
70
|
end
|
|
53
71
|
end
|
|
54
72
|
|
|
73
|
+
ActionDispatch::Routing::Mapper.include(GraphqlDevise::RouteMounter)
|
|
74
|
+
|
|
55
75
|
require 'graphql_devise/engine'
|
|
56
|
-
require 'graphql_devise/version'
|
|
57
|
-
require 'graphql_devise/errors/error_codes'
|
|
58
|
-
require 'graphql_devise/errors/execution_error'
|
|
59
|
-
require 'graphql_devise/errors/user_error'
|
|
60
|
-
require 'graphql_devise/errors/authentication_error'
|
|
61
|
-
require 'graphql_devise/errors/detailed_user_error'
|
|
62
|
-
|
|
63
|
-
# TODO: Remove when merged into master
|
|
64
|
-
require 'graphql_devise/concerns/authenticatable'
|
|
65
|
-
require 'graphql_devise/concerns/set_user_by_token.rb'
|
|
66
|
-
|
|
67
|
-
require 'graphql_devise/concerns/controller_methods'
|
|
68
|
-
require 'graphql_devise/schema'
|
|
69
|
-
require 'graphql_devise/types/authenticatable_type'
|
|
70
|
-
require 'graphql_devise/types/credential_type'
|
|
71
|
-
require 'graphql_devise/types/mutation_type'
|
|
72
|
-
require 'graphql_devise/types/query_type'
|
|
73
|
-
require 'graphql_devise/default_operations/mutations'
|
|
74
|
-
require 'graphql_devise/default_operations/resolvers'
|
|
75
|
-
require 'graphql_devise/resolvers/dummy'
|
|
76
|
-
|
|
77
|
-
require 'graphql_devise/mount_method/option_sanitizer'
|
|
78
|
-
require 'graphql_devise/mount_method/options_validator'
|
|
79
|
-
require 'graphql_devise/mount_method/operation_preparer'
|
|
80
|
-
require 'graphql_devise/mount_method/operation_sanitizer'
|
|
81
|
-
|
|
82
|
-
require 'graphql_devise/resource_loader'
|
|
83
|
-
require 'graphql_devise/schema_plugin'
|
|
@@ -4,6 +4,7 @@ module Api
|
|
|
4
4
|
module V1
|
|
5
5
|
class GraphqlController < ApplicationController
|
|
6
6
|
include GraphqlDevise::SetUserByToken
|
|
7
|
+
include ActionController::Cookies
|
|
7
8
|
|
|
8
9
|
def graphql
|
|
9
10
|
result = DummySchema.execute(params[:query], **execute_params(params))
|
|
@@ -15,28 +16,13 @@ module Api
|
|
|
15
16
|
render json: InterpreterSchema.execute(params[:query], **execute_params(params))
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
def failing_resource_name
|
|
19
|
-
render json: DummySchema.execute(params[:query], context: graphql_context([:user, :fail]))
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def controller_auth
|
|
23
|
-
result = DummySchema.execute(
|
|
24
|
-
params[:query],
|
|
25
|
-
operation_name: params[:operationName],
|
|
26
|
-
variables: ensure_hash(params[:variables]),
|
|
27
|
-
context: gql_devise_context(SchemaUser, User)
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
render json: result unless performed?
|
|
31
|
-
end
|
|
32
|
-
|
|
33
19
|
private
|
|
34
20
|
|
|
35
21
|
def execute_params(item)
|
|
36
22
|
{
|
|
37
23
|
operation_name: item[:operationName],
|
|
38
24
|
variables: ensure_hash(item[:variables]),
|
|
39
|
-
context:
|
|
25
|
+
context: gql_devise_context(SchemaUser, User)
|
|
40
26
|
}
|
|
41
27
|
end
|
|
42
28
|
|
|
@@ -10,11 +10,7 @@ class DummySchema < GraphQL::Schema
|
|
|
10
10
|
User,
|
|
11
11
|
only: [
|
|
12
12
|
:login,
|
|
13
|
-
:
|
|
14
|
-
:send_password_reset,
|
|
15
|
-
:resend_confirmation,
|
|
16
|
-
:resend_confirmation_with_token,
|
|
17
|
-
:check_password_token
|
|
13
|
+
:resend_confirmation_with_token
|
|
18
14
|
]
|
|
19
15
|
),
|
|
20
16
|
GraphqlDevise::ResourceLoader.new(Guest, only: [:logout]),
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class InterpreterSchema < GraphQL::Schema
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.9.0') && Gem::Version.new(GraphQL::VERSION) < Gem::Version.new('2.0')
|
|
5
|
+
use GraphQL::Execution::Interpreter
|
|
6
|
+
end
|
|
7
|
+
if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.10.0') && Gem::Version.new(GraphQL::VERSION) < Gem::Version.new('2.0')
|
|
8
|
+
use GraphQL::Analysis::AST
|
|
9
|
+
end
|
|
6
10
|
|
|
7
11
|
use GraphqlDevise::SchemaPlugin.new(query: Types::QueryType, authenticate_default: false)
|
|
8
12
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Mutations
|
|
4
|
-
class UpdateUser <
|
|
4
|
+
class UpdateUser < BaseMutation
|
|
5
5
|
field :user, Types::UserType, null: false
|
|
6
6
|
|
|
7
7
|
argument :email, String, required: false
|
|
@@ -10,10 +10,8 @@ module Mutations
|
|
|
10
10
|
def resolve(**attrs)
|
|
11
11
|
user = context[:current_resource]
|
|
12
12
|
|
|
13
|
-
schema_url = context[:controller].full_url_without_params
|
|
14
|
-
|
|
15
13
|
user.update_with_email(
|
|
16
|
-
attrs.merge(
|
|
14
|
+
attrs.merge(confirmation_url: 'https://google.com')
|
|
17
15
|
)
|
|
18
16
|
|
|
19
17
|
{ user: user }
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Types
|
|
4
|
-
class MutationType <
|
|
4
|
+
class MutationType < BaseObject
|
|
5
|
+
field_class GraphqlDevise::Types::BaseField if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
|
|
6
|
+
|
|
5
7
|
field :dummy_mutation, String, null: false, authenticate: true
|
|
6
8
|
field :update_user, mutation: Mutations::UpdateUser
|
|
7
9
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Types
|
|
4
|
-
class QueryType <
|
|
4
|
+
class QueryType < BaseObject
|
|
5
|
+
field_class GraphqlDevise::Types::BaseField if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
|
|
6
|
+
|
|
5
7
|
field :user, resolver: Resolvers::UserShow
|
|
6
8
|
field :public_field, String, null: false, authenticate: false
|
|
7
9
|
field :private_field, String, null: false, authenticate: true
|
|
@@ -43,5 +43,5 @@ Rails.application.configure do
|
|
|
43
43
|
config.active_support.deprecation = :stderr
|
|
44
44
|
|
|
45
45
|
# Raises error for missing translations
|
|
46
|
-
config.action_view.raise_on_missing_translations = true
|
|
46
|
+
config.action_view.raise_on_missing_translations = true if Rails::VERSION::MAJOR < 7
|
|
47
47
|
end
|
data/spec/dummy/config/routes.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
Rails.application.routes.draw do
|
|
4
|
-
mount_graphql_devise_for
|
|
4
|
+
mount_graphql_devise_for User, at: '/api/v1/graphql_auth', operations: {
|
|
5
5
|
login: Mutations::Login,
|
|
6
|
-
sign_up: Mutations::SignUp,
|
|
7
6
|
register: Mutations::Register
|
|
8
7
|
}, additional_mutations: {
|
|
9
8
|
register_confirmed_user: Mutations::RegisterConfirmedUser
|
|
@@ -14,22 +13,21 @@ Rails.application.routes.draw do
|
|
|
14
13
|
mount_graphql_devise_for(
|
|
15
14
|
Admin,
|
|
16
15
|
authenticatable_type: Types::CustomAdminType,
|
|
17
|
-
skip: [:
|
|
16
|
+
skip: [:register],
|
|
18
17
|
operations: {
|
|
19
|
-
confirm_account: Resolvers::ConfirmAdminAccount,
|
|
20
18
|
update_password_with_token: Mutations::ResetAdminPasswordWithToken
|
|
21
19
|
},
|
|
22
20
|
at: '/api/v1/admin/graphql_auth'
|
|
23
21
|
)
|
|
24
22
|
|
|
25
23
|
mount_graphql_devise_for(
|
|
26
|
-
|
|
27
|
-
only: [:login, :logout, :
|
|
24
|
+
Guest,
|
|
25
|
+
only: [:login, :logout, :register],
|
|
28
26
|
at: '/api/v1/guest/graphql_auth'
|
|
29
27
|
)
|
|
30
28
|
|
|
31
29
|
mount_graphql_devise_for(
|
|
32
|
-
|
|
30
|
+
Users::Customer,
|
|
33
31
|
only: [:login],
|
|
34
32
|
at: '/api/v1/user_customer/graphql_auth'
|
|
35
33
|
)
|
|
@@ -37,6 +35,4 @@ Rails.application.routes.draw do
|
|
|
37
35
|
get '/api/v1/graphql', to: 'api/v1/graphql#graphql'
|
|
38
36
|
post '/api/v1/graphql', to: 'api/v1/graphql#graphql'
|
|
39
37
|
post '/api/v1/interpreter', to: 'api/v1/graphql#interpreter'
|
|
40
|
-
post '/api/v1/failing', to: 'api/v1/graphql#failing_resource_name'
|
|
41
|
-
post '/api/v1/controller_auth', to: 'api/v1/graphql#controller_auth'
|
|
42
38
|
end
|
|
@@ -41,7 +41,7 @@ RSpec.describe GraphqlDevise::InstallGenerator, type: :generator do
|
|
|
41
41
|
let(:args) { [] }
|
|
42
42
|
|
|
43
43
|
it 'creates and updated required files' do
|
|
44
|
-
assert_file 'config/routes.rb', /^\s{2}mount_graphql_devise_for
|
|
44
|
+
assert_file 'config/routes.rb', /^\s{2}mount_graphql_devise_for User, at: 'graphql_auth'/
|
|
45
45
|
expect(routes_content).not_to match(dta_route)
|
|
46
46
|
|
|
47
47
|
assert_file 'config/initializers/devise.rb'
|
|
@@ -60,7 +60,7 @@ RSpec.describe GraphqlDevise::InstallGenerator, type: :generator do
|
|
|
60
60
|
let(:args) { %w[Admin api] }
|
|
61
61
|
|
|
62
62
|
it 'creates and updated required files' do
|
|
63
|
-
assert_file 'config/routes.rb', /^\s{2}mount_graphql_devise_for
|
|
63
|
+
assert_file 'config/routes.rb', /^\s{2}mount_graphql_devise_for Admin, at: 'api'/
|
|
64
64
|
expect(routes_content).not_to match(dta_route)
|
|
65
65
|
|
|
66
66
|
assert_file 'config/initializers/devise.rb'
|