Skip to content

Commit 5d2d437

Browse files
Merge pull request #100 from graphql-devise/gqld-98-insecure-password-reset-mutation
Avoid returning user information on password reset mutation
2 parents 03f5f97 + 8c62e0f commit 5d2d437

15 files changed

Lines changed: 73 additions & 49 deletions

File tree

config/locales/en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ en:
1414
password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
1515
reset_token_not_found: "No user found for the specified reset token."
1616
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."
1718
sessions:
1819
bad_credentials: "Invalid login credentials. Please try again."
1920
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"

lib/graphql_devise/default_operations/mutations.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
module GraphqlDevise
1010
module DefaultOperations
1111
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 }
1818
}.freeze
1919
end
2020
end

lib/graphql_devise/default_operations/resolvers.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
module GraphqlDevise
66
module DefaultOperations
77
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 }
1010
}.freeze
1111
end
1212
end

lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ def initialize(selected_operations:, custom_keys:, mapping_name:, preparer:)
1010
end
1111

1212
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|
1414
mapped_action = "#{@mapping_name}_#{action}"
15+
operation = operation_info[:klass]
16+
options = operation_info.except(:klass)
1517

1618
result[mapped_action.to_sym] = [
1719
OperationPreparers::GqlNameSetter.new(mapped_action),
1820
@preparer,
1921
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
2125
end
2226
end
2327

lib/graphql_devise/mount_method/operation_preparers/gql_name_setter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def initialize(mapping_name)
66
@mapping_name = mapping_name
77
end
88

9-
def call(operation)
9+
def call(operation, **)
1010
operation.graphql_name(graphql_name)
1111

1212
operation

lib/graphql_devise/mount_method/operation_preparers/mutation_field_setter.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ def initialize(authenticatable_type)
66
@authenticatable_type = authenticatable_type
77
end
88

9-
def call(mutation)
10-
mutation.field(:authenticatable, @authenticatable_type, null: false)
9+
def call(mutation, authenticatable: true)
10+
return mutation unless authenticatable
1111

12+
mutation.field(:authenticatable, @authenticatable_type, null: false)
1213
mutation
1314
end
1415
end

lib/graphql_devise/mount_method/operation_preparers/resolver_type_setter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def initialize(authenticatable_type)
66
@authenticatable_type = authenticatable_type
77
end
88

9-
def call(resolver)
9+
def call(resolver, **)
1010
resolver.type(@authenticatable_type, null: false)
1111

1212
resolver

lib/graphql_devise/mount_method/operation_preparers/resource_name_setter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def initialize(name)
66
@name = name
77
end
88

9-
def call(operation)
9+
def call(operation, **)
1010
operation.instance_variable_set(:@resource_name, @name)
1111

1212
operation

lib/graphql_devise/mutations/resend_confirmation.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ def resolve(email:, redirect_url:)
2222
template_path: ['graphql_devise/mailer']
2323
)
2424

25-
{
26-
authenticatable: resource,
27-
message: I18n.t('graphql_devise.confirmations.send_instructions', email: email)
28-
}
25+
{ message: I18n.t('graphql_devise.confirmations.send_instructions', email: email) }
2926
else
3027
raise_user_error(I18n.t('graphql_devise.confirmations.user_not_found', email: email))
3128
end

lib/graphql_devise/mutations/send_password_reset.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ class SendPasswordReset < Base
44
argument :email, String, required: true
55
argument :redirect_url, String, required: true
66

7+
field :message, String, null: false
8+
79
def resolve(email:, redirect_url:)
810
resource = find_resource(:email, get_case_insensitive_field(:email, email))
911

@@ -18,7 +20,7 @@ def resolve(email:, redirect_url:)
1820
)
1921

2022
if resource.errors.empty?
21-
{ authenticatable: resource }
23+
{ message: I18n.t('graphql_devise.passwords.send_instructions') }
2224
else
2325
raise_user_error_list(I18n.t('graphql_devise.invalid_resource'), errors: resource.errors.full_messages)
2426
end

0 commit comments

Comments
 (0)