graphql_devise 0.11.2 → 0.12.2

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rspec +1 -0
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +50 -1
  6. data/README.md +185 -32
  7. data/app/controllers/graphql_devise/application_controller.rb +4 -1
  8. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +25 -0
  9. data/app/controllers/graphql_devise/graphql_controller.rb +2 -0
  10. data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
  11. data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +1 -1
  12. data/app/views/graphql_devise/mailer/reset_password_instructions.html.erb +1 -1
  13. data/config/locales/en.yml +1 -0
  14. data/config/routes.rb +2 -0
  15. data/graphql_devise.gemspec +6 -4
  16. data/lib/generators/graphql_devise/install_generator.rb +63 -30
  17. data/lib/graphql_devise.rb +24 -10
  18. data/lib/graphql_devise/default_operations/mutations.rb +6 -6
  19. data/lib/graphql_devise/default_operations/resolvers.rb +2 -2
  20. data/lib/graphql_devise/errors/authentication_error.rb +7 -0
  21. data/lib/graphql_devise/{detailed_user_error.rb → errors/detailed_user_error.rb} +1 -1
  22. data/lib/graphql_devise/errors/error_codes.rb +6 -0
  23. data/lib/graphql_devise/errors/execution_error.rb +4 -0
  24. data/lib/graphql_devise/{user_error.rb → errors/user_error.rb} +1 -1
  25. data/lib/graphql_devise/mount_method/operation_preparer.rb +2 -2
  26. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +6 -2
  27. data/lib/graphql_devise/mount_method/operation_preparers/gql_name_setter.rb +1 -1
  28. data/lib/graphql_devise/mount_method/operation_preparers/mutation_field_setter.rb +3 -2
  29. data/lib/graphql_devise/mount_method/operation_preparers/resolver_type_setter.rb +1 -1
  30. data/lib/graphql_devise/mount_method/operation_preparers/resource_name_setter.rb +2 -2
  31. data/lib/graphql_devise/mutations/resend_confirmation.rb +3 -5
  32. data/lib/graphql_devise/mutations/send_password_reset.rb +5 -2
  33. data/lib/graphql_devise/mutations/sign_up.rb +3 -6
  34. data/lib/graphql_devise/rails/routes.rb +5 -72
  35. data/lib/graphql_devise/resource_loader.rb +87 -0
  36. data/lib/graphql_devise/schema_plugin.rb +106 -0
  37. data/lib/graphql_devise/version.rb +1 -1
  38. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +41 -3
  39. data/spec/dummy/app/controllers/application_controller.rb +1 -0
  40. data/spec/dummy/app/graphql/dummy_schema.rb +18 -0
  41. data/spec/dummy/app/graphql/interpreter_schema.rb +9 -0
  42. data/spec/dummy/app/graphql/types/mutation_type.rb +1 -1
  43. data/spec/dummy/app/graphql/types/query_type.rb +10 -0
  44. data/spec/dummy/config/routes.rb +3 -0
  45. data/spec/generators/graphql_devise/install_generator_spec.rb +62 -30
  46. data/spec/rails_helper.rb +4 -1
  47. data/spec/requests/graphql_controller_spec.rb +80 -0
  48. data/spec/requests/mutations/resend_confirmation_spec.rb +44 -29
  49. data/spec/requests/mutations/send_password_reset_spec.rb +40 -12
  50. data/spec/requests/queries/confirm_account_spec.rb +7 -1
  51. data/spec/requests/user_controller_spec.rb +189 -24
  52. data/spec/services/mount_method/operation_preparer_spec.rb +8 -3
  53. data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +1 -1
  54. data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +15 -8
  55. data/spec/services/mount_method/operation_preparers/mutation_field_setter_spec.rb +18 -4
  56. data/spec/services/mount_method/operation_preparers/resource_name_setter_spec.rb +1 -1
  57. data/spec/services/resource_loader_spec.rb +82 -0
  58. data/spec/services/schema_plugin_spec.rb +26 -0
  59. data/spec/spec_helper.rb +1 -1
  60. metadata +107 -89
  61. data/lib/graphql_devise/error_codes.rb +0 -5
  62. data/spec/support/generators/file_helpers.rb +0 -12
@@ -1,5 +1,30 @@
1
1
  module GraphqlDevise
2
2
  module Concerns
3
3
  SetUserByToken = DeviseTokenAuth::Concerns::SetUserByToken
4
+
5
+ SetUserByToken.module_eval do
6
+ attr_accessor :client_id, :token, :resource
7
+
8
+ def set_resource_by_token(resource)
9
+ set_user_by_token(resource)
10
+ end
11
+
12
+ def graphql_context(resource_name)
13
+ {
14
+ resource_name: resource_name,
15
+ controller: self
16
+ }
17
+ end
18
+
19
+ def build_redirect_headers(access_token, client, redirect_header_options = {})
20
+ {
21
+ DeviseTokenAuth.headers_names[:"access-token"] => access_token,
22
+ DeviseTokenAuth.headers_names[:client] => client,
23
+ :config => params[:config],
24
+ :client_id => client,
25
+ :token => access_token
26
+ }.merge(redirect_header_options)
27
+ end
28
+ end
4
29
  end
5
30
  end
@@ -2,6 +2,8 @@ require_dependency 'graphql_devise/application_controller'
2
2
 
3
3
  module GraphqlDevise
4
4
  class GraphqlController < ApplicationController
5
+ include GraphqlDevise::Concerns::SetUserByToken
6
+
5
7
  def auth
6
8
  result = if params[:_json]
7
9
  GraphqlDevise::Schema.multiplex(
@@ -1,7 +1,7 @@
1
1
  module GraphqlDevise
2
2
  module MailerHelper
3
3
  def confirmation_query(resource_name:, token:, redirect_url:)
4
- name = "#{resource_name.camelize(:lower)}ConfirmAccount"
4
+ name = "#{resource_name.underscore.tr('/', '_').camelize(:lower)}ConfirmAccount"
5
5
  raw = <<-GRAPHQL
6
6
  query($token:String!,$redirectUrl:String!){
7
7
  #{name}(confirmationToken:$token,redirectUrl:$redirectUrl){
@@ -17,7 +17,7 @@ module GraphqlDevise
17
17
  end
18
18
 
19
19
  def password_reset_query(token:, redirect_url:, resource_name:)
20
- name = "#{resource_name.camelize(:lower)}CheckPasswordToken"
20
+ name = "#{resource_name.underscore.tr('/', '_').camelize(:lower)}CheckPasswordToken"
21
21
  raw = <<-GRAPHQL
22
22
  query($token:String!,$redirectUrl:String!){
23
23
  #{name}(resetPasswordToken:$token,redirectUrl:$redirectUrl){
@@ -2,4 +2,4 @@
2
2
 
3
3
  <p><%= t('.confirm_link_msg') %></p>
4
4
 
5
- <p><%= link_to t('.confirm_account_link'), url_for(controller: 'graphql_devise/graphql', action: :auth, **confirmation_query(resource_name: @resource.class.to_s, redirect_url: message['redirect-url'], token: @token)) %></p>
5
+ <p><%= link_to t('.confirm_account_link'), url_for(controller: message['controller'], action: message['action'], **confirmation_query(resource_name: @resource.class.to_s, redirect_url: message['redirect-url'], token: @token)) %></p>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <p><%= t('.request_reset_link_msg') %></p>
4
4
 
5
- <p><%= link_to t('.password_change_link'), url_for(controller: 'graphql_devise/graphql', action: :auth, **password_reset_query(token: @token, redirect_url: message['redirect-url'], resource_name: @resource.class.to_s)) %></p>
5
+ <p><%= link_to t('.password_change_link'), url_for(controller: message['controller'], action: message['action'], **password_reset_query(token: @token, redirect_url: message['redirect-url'], resource_name: @resource.class.to_s)) %></p>
6
6
 
7
7
  <p><%= t('.ignore_mail_msg') %></p>
8
8
  <p><%= t('.no_changes_msg') %></p>
@@ -14,6 +14,7 @@ en:
14
14
  password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
15
15
  reset_token_not_found: "No user found for the specified reset token."
16
16
  reset_token_expired: "Reset password token is no longer valid."
17
+ send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
17
18
  sessions:
18
19
  bad_credentials: "Invalid login credentials. Please try again."
19
20
  not_confirmed: "A confirmation email was sent to your account at '%{email}'. You must follow the instructions in the email before your account can be activated"
@@ -12,5 +12,7 @@ GraphqlDevise::Engine.routes.draw do
12
12
  GraphqlDevise::Schema.query(GraphqlDevise::Types::QueryType)
13
13
 
14
14
  GraphqlDevise.load_schema
15
+
16
+ Devise.mailer.helper(GraphqlDevise::MailerHelper)
15
17
  end
16
18
  end
@@ -21,13 +21,15 @@ Gem::Specification.new do |spec|
21
21
  spec.bindir = 'exe'
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
- spec.test_files = Dir['spec/**/*']
24
+ spec.test_files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").select { |f| f.match(%r{^spec/}) }
26
+ end
25
27
 
26
28
  spec.required_ruby_version = '>= 2.2.0'
27
29
 
28
- spec.add_dependency 'devise_token_auth', '>= 0.1.43'
29
- spec.add_dependency 'graphql', '>= 1.8'
30
- spec.add_dependency 'rails', '>= 4.2'
30
+ spec.add_dependency 'devise_token_auth', '>= 0.1.43', '< 2.0'
31
+ spec.add_dependency 'graphql', '>= 1.8', '< 1.11.0'
32
+ spec.add_dependency 'rails', '>= 4.2', '< 6.2'
31
33
 
32
34
  spec.add_development_dependency 'appraisal'
33
35
  spec.add_development_dependency 'coveralls'
@@ -5,62 +5,95 @@ module GraphqlDevise
5
5
  argument :user_class, type: :string, default: 'User'
6
6
  argument :mount_path, type: :string, default: 'auth'
7
7
 
8
+ class_option :mount, type: :string, default: 'separate_route'
9
+
8
10
  def execute_devise_installer
9
11
  generate 'devise:install'
10
12
  end
11
13
 
12
14
  def execute_dta_installer
15
+ # Necessary in case of a re-run of the generator, for DTA to detect concerns already included
16
+ if File.exist?(File.expand_path("app/models/#{user_class.underscore}.rb", destination_root))
17
+ gsub_file(
18
+ "app/models/#{user_class.underscore}.rb",
19
+ 'GraphqlDevise::Concerns::Model',
20
+ 'DeviseTokenAuth::Concerns::User'
21
+ )
22
+ end
23
+ gsub_file(
24
+ 'app/controllers/application_controller.rb',
25
+ 'GraphqlDevise::Concerns::SetUserByToken',
26
+ 'DeviseTokenAuth::Concerns::SetUserByToken'
27
+ )
28
+
13
29
  generate 'devise_token_auth:install', "#{user_class} #{mount_path}"
14
30
  end
15
31
 
16
32
  def mount_resource_route
17
33
  routes_file = 'config/routes.rb'
18
- routes_path = File.join(destination_root, routes_file)
19
- gem_helper = 'mount_graphql_devise_for'
20
- gem_route = "#{gem_helper} '#{user_class}', at: '#{mount_path}'"
21
34
  dta_route = "mount_devise_token_auth_for '#{user_class}', at: '#{mount_path}'"
22
- file_start = 'Rails.application.routes.draw do'
23
35
 
24
- if File.exist?(routes_path)
25
- current_route = parse_file_for_line(routes_path, gem_route)
36
+ if options['mount'] != 'separate_route'
37
+ gsub_file(routes_file, /^\s+#{Regexp.escape(dta_route + "\n")}/i, '')
38
+ else
39
+ gem_route = "mount_graphql_devise_for '#{user_class}', at: '#{mount_path}'"
40
+
41
+ if file_contains_str?(routes_file, gem_route)
42
+ gsub_file(routes_file, /^\s+#{Regexp.escape(dta_route + "\n")}/i, '')
26
43
 
27
- if current_route.present?
28
44
  say_status('skipped', "Routes already exist for #{user_class} at #{mount_path}")
29
45
  else
30
- current_dta_route = parse_file_for_line(routes_path, dta_route)
31
-
32
- if current_dta_route.present?
33
- replace_line(routes_path, dta_route, gem_route)
34
- else
35
- insert_text_after_line(routes_path, file_start, gem_route)
36
- end
46
+ gsub_file(routes_file, /#{Regexp.escape(dta_route)}/i, gem_route)
37
47
  end
38
- else
39
- say_status('skipped', "#{routes_file} not found. Add \"#{gem_route}\" to your routes file.")
40
48
  end
41
49
  end
42
50
 
43
- private
51
+ def replace_model_concern
52
+ gsub_file(
53
+ "app/models/#{user_class.underscore}.rb",
54
+ /^\s+include DeviseTokenAuth::Concerns::User/,
55
+ ' include GraphqlDevise::Concerns::Model'
56
+ )
57
+ end
44
58
 
45
- def insert_text_after_line(filename, line, str)
46
- gsub_file(filename, /(#{Regexp.escape(line)})/mi) do |match|
47
- "#{match}\n #{str}"
48
- end
59
+ def replace_controller_concern
60
+ gsub_file(
61
+ 'app/controllers/application_controller.rb',
62
+ /^\s+include DeviseTokenAuth::Concerns::SetUserByToken/,
63
+ ' include GraphqlDevise::Concerns::SetUserByToken'
64
+ )
49
65
  end
50
66
 
51
- def replace_line(filename, old_line, new_line)
52
- gsub_file(filename, /(#{Regexp.escape(old_line)})/mi, " #{new_line}")
67
+ def set_change_headers_on_each_request_false
68
+ gsub_file(
69
+ 'config/initializers/devise_token_auth.rb',
70
+ '# config.change_headers_on_each_request = true',
71
+ 'config.change_headers_on_each_request = false'
72
+ )
53
73
  end
54
74
 
55
- def parse_file_for_line(filename, str)
56
- match = false
75
+ def mount_in_schema
76
+ return if options['mount'] == 'separate_route'
57
77
 
58
- File.open(filename) do |f|
59
- f.each_line do |line|
60
- match = line if line =~ /(#{Regexp.escape(str)})/mi
61
- end
78
+ inject_into_file "app/graphql/#{options['mount'].underscore}.rb", after: "< GraphQL::Schema\n" do
79
+ <<-RUBY
80
+ use GraphqlDevise::SchemaPlugin.new(
81
+ query: Types::QueryType,
82
+ mutation: Types::MutationType,
83
+ resource_loaders: [
84
+ GraphqlDevise::ResourceLoader.new('#{user_class}'),
85
+ ]
86
+ )
87
+ RUBY
62
88
  end
63
- match
89
+ end
90
+
91
+ private
92
+
93
+ def file_contains_str?(filename, regex_str)
94
+ path = File.join(destination_root, filename)
95
+
96
+ File.read(path) =~ /(#{Regexp.escape(regex_str)})/i
64
97
  end
65
98
  end
66
99
  end
@@ -18,15 +18,32 @@ module GraphqlDevise
18
18
  @schema_loaded = true
19
19
  end
20
20
 
21
- def self.mount_resource(resource)
22
- @mounted_resources << resource
21
+ def self.resource_mounted?(mapping_name)
22
+ @mounted_resources.include?(mapping_name)
23
23
  end
24
24
 
25
- def self.resource_mounted?(resource)
26
- @mounted_resources.include?(resource)
25
+ def self.mount_resource(mapping_name)
26
+ @mounted_resources << mapping_name
27
+ end
28
+
29
+ def self.add_mapping(mapping_name, resource)
30
+ return if Devise.mappings.key?(mapping_name)
31
+
32
+ Devise.add_mapping(
33
+ mapping_name.to_s.pluralize.to_sym,
34
+ module: :devise, class_name: resource
35
+ )
27
36
  end
28
37
  end
29
38
 
39
+ require 'graphql_devise/engine'
40
+ require 'graphql_devise/version'
41
+ require 'graphql_devise/errors/error_codes'
42
+ require 'graphql_devise/errors/execution_error'
43
+ require 'graphql_devise/errors/user_error'
44
+ require 'graphql_devise/errors/authentication_error'
45
+ require 'graphql_devise/errors/detailed_user_error'
46
+
30
47
  require 'graphql_devise/concerns/controller_methods'
31
48
  require 'graphql_devise/schema'
32
49
  require 'graphql_devise/types/authenticatable_type'
@@ -37,13 +54,10 @@ require 'graphql_devise/default_operations/mutations'
37
54
  require 'graphql_devise/default_operations/resolvers'
38
55
  require 'graphql_devise/resolvers/dummy'
39
56
 
40
- require 'graphql_devise/engine'
41
- require 'graphql_devise/version'
42
- require 'graphql_devise/error_codes'
43
- require 'graphql_devise/user_error'
44
- require 'graphql_devise/detailed_user_error'
45
-
46
57
  require 'graphql_devise/mount_method/option_sanitizer'
47
58
  require 'graphql_devise/mount_method/options_validator'
48
59
  require 'graphql_devise/mount_method/operation_preparer'
49
60
  require 'graphql_devise/mount_method/operation_sanitizer'
61
+
62
+ require 'graphql_devise/resource_loader'
63
+ require 'graphql_devise/schema_plugin'
@@ -9,12 +9,12 @@ require 'graphql_devise/mutations/update_password'
9
9
  module GraphqlDevise
10
10
  module DefaultOperations
11
11
  MUTATIONS = {
12
- login: GraphqlDevise::Mutations::Login,
13
- logout: GraphqlDevise::Mutations::Logout,
14
- sign_up: GraphqlDevise::Mutations::SignUp,
15
- update_password: GraphqlDevise::Mutations::UpdatePassword,
16
- send_password_reset: GraphqlDevise::Mutations::SendPasswordReset,
17
- resend_confirmation: GraphqlDevise::Mutations::ResendConfirmation
12
+ login: { klass: GraphqlDevise::Mutations::Login, authenticatable: true },
13
+ logout: { klass: GraphqlDevise::Mutations::Logout, authenticatable: true },
14
+ sign_up: { klass: GraphqlDevise::Mutations::SignUp, authenticatable: true },
15
+ update_password: { klass: GraphqlDevise::Mutations::UpdatePassword, authenticatable: true },
16
+ send_password_reset: { klass: GraphqlDevise::Mutations::SendPasswordReset, authenticatable: false },
17
+ resend_confirmation: { klass: GraphqlDevise::Mutations::ResendConfirmation, authenticatable: false }
18
18
  }.freeze
19
19
  end
20
20
  end
@@ -5,8 +5,8 @@ require 'graphql_devise/resolvers/confirm_account'
5
5
  module GraphqlDevise
6
6
  module DefaultOperations
7
7
  QUERIES = {
8
- confirm_account: GraphqlDevise::Resolvers::ConfirmAccount,
9
- check_password_token: GraphqlDevise::Resolvers::CheckPasswordToken
8
+ confirm_account: { klass: GraphqlDevise::Resolvers::ConfirmAccount },
9
+ check_password_token: { klass: GraphqlDevise::Resolvers::CheckPasswordToken }
10
10
  }.freeze
11
11
  end
12
12
  end
@@ -0,0 +1,7 @@
1
+ module GraphqlDevise
2
+ class AuthenticationError < ExecutionError
3
+ def to_h
4
+ super.merge(extensions: { code: ERROR_CODES.fetch(:authentication_error) })
5
+ end
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  module GraphqlDevise
2
- class DetailedUserError < GraphQL::ExecutionError
2
+ class DetailedUserError < ExecutionError
3
3
  def initialize(message, errors:)
4
4
  @message = message
5
5
  @errors = errors
@@ -0,0 +1,6 @@
1
+ module GraphqlDevise
2
+ ERROR_CODES = {
3
+ user_error: 'USER_ERROR',
4
+ authentication_error: 'AUTHENTICATION_ERROR'
5
+ }.freeze
6
+ end
@@ -0,0 +1,4 @@
1
+ module GraphqlDevise
2
+ class ExecutionError < GraphQL::ExecutionError
3
+ end
4
+ end
@@ -1,5 +1,5 @@
1
1
  module GraphqlDevise
2
- class UserError < GraphQL::ExecutionError
2
+ class UserError < ExecutionError
3
3
  def to_h
4
4
  super.merge(extensions: { code: ERROR_CODES.fetch(:user_error) })
5
5
  end
@@ -8,10 +8,10 @@ require_relative 'operation_preparers/custom_operation_preparer'
8
8
  module GraphqlDevise
9
9
  module MountMethod
10
10
  class OperationPreparer
11
- def initialize(resource:, selected_operations:, preparer:, custom:, additional_operations:)
11
+ def initialize(mapping_name:, selected_operations:, preparer:, custom:, additional_operations:)
12
12
  @selected_operations = selected_operations
13
13
  @preparer = preparer
14
- @mapping_name = resource.underscore.tr('/', '_')
14
+ @mapping_name = mapping_name
15
15
  @custom = custom
16
16
  @additional_operations = additional_operations
17
17
  end
@@ -10,14 +10,18 @@ module GraphqlDevise
10
10
  end
11
11
 
12
12
  def call
13
- @selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation), result|
13
+ @selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
14
14
  mapped_action = "#{@mapping_name}_#{action}"
15
+ operation = operation_info[:klass]
16
+ options = operation_info.except(:klass)
15
17
 
16
18
  result[mapped_action.to_sym] = [
17
19
  OperationPreparers::GqlNameSetter.new(mapped_action),
18
20
  @preparer,
19
21
  OperationPreparers::ResourceNameSetter.new(@mapping_name)
20
- ].reduce(child_class(operation)) { |prepared_operation, preparer| preparer.call(prepared_operation) }
22
+ ].reduce(child_class(operation)) do |prepared_operation, preparer|
23
+ preparer.call(prepared_operation, **options)
24
+ end
21
25
  end
22
26
  end
23
27
 
@@ -6,7 +6,7 @@ module GraphqlDevise
6
6
  @mapping_name = mapping_name
7
7
  end
8
8
 
9
- def call(operation)
9
+ def call(operation, **)
10
10
  operation.graphql_name(graphql_name)
11
11
 
12
12
  operation
@@ -6,9 +6,10 @@ module GraphqlDevise
6
6
  @authenticatable_type = authenticatable_type
7
7
  end
8
8
 
9
- def call(mutation)
10
- mutation.field(:authenticatable, @authenticatable_type, null: false)
9
+ def call(mutation, authenticatable: true)
10
+ return mutation unless authenticatable
11
11
 
12
+ mutation.field(:authenticatable, @authenticatable_type, null: false)
12
13
  mutation
13
14
  end
14
15
  end
@@ -6,7 +6,7 @@ module GraphqlDevise
6
6
  @authenticatable_type = authenticatable_type
7
7
  end
8
8
 
9
- def call(resolver)
9
+ def call(resolver, **)
10
10
  resolver.type(@authenticatable_type, null: false)
11
11
 
12
12
  resolver
@@ -6,8 +6,8 @@ module GraphqlDevise
6
6
  @name = name
7
7
  end
8
8
 
9
- def call(operation)
10
- operation.instance_variable_set(:@resource_name, @name.to_sym)
9
+ def call(operation, **)
10
+ operation.instance_variable_set(:@resource_name, @name)
11
11
 
12
12
  operation
13
13
  end
@@ -19,13 +19,11 @@ module GraphqlDevise
19
19
 
20
20
  resource.send_confirmation_instructions(
21
21
  redirect_url: redirect_url,
22
- template_path: ['graphql_devise/mailer']
22
+ template_path: ['graphql_devise/mailer'],
23
+ **controller.params.permit('controller', 'action').to_h.symbolize_keys
23
24
  )
24
25
 
25
- {
26
- authenticatable: resource,
27
- message: I18n.t('graphql_devise.confirmations.send_instructions', email: email)
28
- }
26
+ { message: I18n.t('graphql_devise.confirmations.send_instructions', email: email) }
29
27
  else
30
28
  raise_user_error(I18n.t('graphql_devise.confirmations.user_not_found', email: email))
31
29
  end