From 19d3e613d916057cbe63dbd43c65854d2e1a4fff Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Thu, 10 Sep 2020 22:25:57 +0200 Subject: [PATCH 01/15] * Update rails to 6.0 (set autoloader to classic) * set graphql dependency to rails 6.0 * update version for gem * rspec dummy: add manifest to make rails 6 happy * rspec dummy: remove empty query type because this runs into an error * rspec dummy: add manifest to make rails 6 happy --- Gemfile | 2 +- graphql-1.9.gemfile | 2 +- graphql-auth.gemspec | 4 ++-- lib/graphql-auth/version.rb | 2 +- spec/dummy/app/assets/config/manifest.js | 0 spec/dummy/app/graphql/graphql_schema.rb | 2 +- spec/dummy/config/application.rb | 5 ++++- 7 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 spec/dummy/app/assets/config/manifest.js diff --git a/Gemfile b/Gemfile index 1a49130..bf015c5 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' gem 'byebug' -gem 'rails', '~> 5.2' +gem 'rails', '~> 6.0' gem 'graphql', '~> 1.9.6' diff --git a/graphql-1.9.gemfile b/graphql-1.9.gemfile index e81403d..538f49b 100644 --- a/graphql-1.9.gemfile +++ b/graphql-1.9.gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' gem 'byebug' gem 'coveralls' -gem 'rails', '~> 5.2' +gem 'rails', '~> 6.0' gem 'graphql', '~> 1.9.6' gemspec \ No newline at end of file diff --git a/graphql-auth.gemspec b/graphql-auth.gemspec index 2941f9e..08ef0d7 100644 --- a/graphql-auth.gemspec +++ b/graphql-auth.gemspec @@ -17,12 +17,12 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 2.4.5' - spec.add_dependency "rails", "~> 5.1" + spec.add_dependency "rails", "~> 6.0" spec.add_dependency 'graphql', '~> 1.9', '>= 1.9.6' spec.add_dependency 'devise', '~> 4.6', '>= 4.6.2' spec.add_dependency 'jwt', '~> 1.5' - spec.add_development_dependency 'sqlite3', '~> 1.3.6' + spec.add_development_dependency 'sqlite3', '~> 1.4' spec.add_development_dependency 'bundler', '~> 2.0' spec.add_development_dependency 'rake', '~> 10.0' spec.add_development_dependency 'rspec', '~> 3.0' diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index bd1f349..ee0d7d6 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.6.1' + VERSION = '0.7.0' end end \ No newline at end of file diff --git a/spec/dummy/app/assets/config/manifest.js b/spec/dummy/app/assets/config/manifest.js new file mode 100644 index 0000000..e69de29 diff --git a/spec/dummy/app/graphql/graphql_schema.rb b/spec/dummy/app/graphql/graphql_schema.rb index 39d1556..ad9cd2e 100644 --- a/spec/dummy/app/graphql/graphql_schema.rb +++ b/spec/dummy/app/graphql/graphql_schema.rb @@ -2,7 +2,7 @@ class GraphqlSchema < GraphQL::Schema mutation Types::MutationType - query Types::QueryType + # query Types::QueryType end GraphqlSchema.graphql_definition diff --git a/spec/dummy/config/application.rb b/spec/dummy/config/application.rb index 2cbcf67..9d00f18 100644 --- a/spec/dummy/config/application.rb +++ b/spec/dummy/config/application.rb @@ -8,7 +8,10 @@ module Dummy class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.2 + config.load_defaults 6.0 + + config.autoloader = :classic + # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers From af270f55edbab9e01ac8fc8ed2f5a780e92b025d Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Fri, 11 Sep 2020 11:18:37 +0200 Subject: [PATCH 02/15] * update jwt --- graphql-auth.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphql-auth.gemspec b/graphql-auth.gemspec index 08ef0d7..979b476 100644 --- a/graphql-auth.gemspec +++ b/graphql-auth.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |spec| spec.add_dependency "rails", "~> 6.0" spec.add_dependency 'graphql', '~> 1.9', '>= 1.9.6' spec.add_dependency 'devise', '~> 4.6', '>= 4.6.2' - spec.add_dependency 'jwt', '~> 1.5' + spec.add_dependency 'jwt', '~> 2.1' spec.add_development_dependency 'sqlite3', '~> 1.4' spec.add_development_dependency 'bundler', '~> 2.0' From 087b1d8f30052a0b62654e6975e9f8e2b8d8cee7 Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Fri, 11 Sep 2020 11:20:21 +0200 Subject: [PATCH 03/15] update version --- lib/graphql-auth/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index ee0d7d6..90851bb 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.0' + VERSION = '0.7.1' end end \ No newline at end of file From f592899a94e344d1aa0e7f115ea1925fa1470ab2 Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Sun, 20 Sep 2020 09:07:18 +0200 Subject: [PATCH 04/15] Check confirmable module efore logging in. --- app/graphql/mutations/auth/sign_in.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/graphql/mutations/auth/sign_in.rb b/app/graphql/mutations/auth/sign_in.rb index db13808..c189e17 100644 --- a/app/graphql/mutations/auth/sign_in.rb +++ b/app/graphql/mutations/auth/sign_in.rb @@ -31,6 +31,20 @@ def resolve(email:, password:, remember_me:) valid_sign_in = user.present? && user.valid_password?(password) + # check confirmable + if valid_sign_in && user.respond_to?(:confirmed?) && !user.active_for_authentication? + return { + errors: [ + { + field: :_error, + message: I18n.t('devise.failure.unconfirmed') + } + ], + success: false, + user: nil + } + end + if valid_sign_in generate_access_token(user, response) set_current_user(user) From 8cc2a9f25d157a2fb8bc30f4008168da9298e3ff Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Sun, 20 Sep 2020 09:08:24 +0200 Subject: [PATCH 05/15] increase version --- lib/graphql-auth/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index 90851bb..0832c42 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.1' + VERSION = '0.7.2' end end \ No newline at end of file From 16cd5e0cf15eced7c41f686de170317baec13aee Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Sun, 20 Sep 2020 09:57:20 +0200 Subject: [PATCH 06/15] add resend confirmation instruction mutation --- README.md | 2 + .../auth/resend_confirmation_instructions.rb | 29 +++++ app/graphql/types/graphql_auth.rb | 4 + lib/graphql-auth/configuration.rb | 2 + lib/graphql-auth/version.rb | 2 +- spec/dummy/app/models/user.rb | 4 +- .../dummy/config/initializers/graphql_auth.rb | 1 + spec/dummy/config/routes.rb | 2 +- .../20190108110416_devise_create_users.rb | 8 +- spec/dummy/db/schema.rb | 15 ++- .../mutations/auth/forgot_password_spec.rb | 4 +- .../resend_confirmation_instructions_spec.rb | 115 ++++++++++++++++++ spec/graphql/mutations/auth/sign_in_spec.rb | 2 +- 13 files changed, 174 insertions(+), 16 deletions(-) create mode 100644 app/graphql/mutations/auth/resend_confirmation_instructions.rb create mode 100644 spec/graphql/mutations/auth/resend_confirmation_instructions_spec.rb diff --git a/README.md b/README.md index 0590d1e..4fedac1 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ GraphQL::Auth.configure do |config| # config.allow_sign_up = true # config.allow_lock_account = false # config.allow_unlock_account = false + # config.allow_email_confirmable = false + # Allow custom mutations for signup and update account # config.sign_up_mutation = '::Mutations::Auth::SignUp' diff --git a/app/graphql/mutations/auth/resend_confirmation_instructions.rb b/app/graphql/mutations/auth/resend_confirmation_instructions.rb new file mode 100644 index 0000000..ccbd304 --- /dev/null +++ b/app/graphql/mutations/auth/resend_confirmation_instructions.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class Mutations::Auth::ResendConfirmationInstructions < GraphQL::Schema::Mutation + include ::Graphql::AccountLockHelper + + argument :email, String, required: true do + description 'The email to confirm.' + end + + field :errors, [::Types::Auth::Error], null: false + field :success, Boolean, null: false + field :valid, Boolean, null: false + + def resolve(email:) + if lockable? + user = User.where(locked_at: nil).find_by email: email + else + user = User.find_by email: email + end + + user.send_confirmation_instructions if user.present? + + { + errors: [], + success: true, + valid: true + } + end +end diff --git a/app/graphql/types/graphql_auth.rb b/app/graphql/types/graphql_auth.rb index 85bea84..b9e436f 100644 --- a/app/graphql/types/graphql_auth.rb +++ b/app/graphql/types/graphql_auth.rb @@ -16,6 +16,10 @@ module Types::GraphqlAuth field :validate_token, mutation: ::Mutations::Auth::ValidateToken + if GraphQL::Auth.configuration.allow_email_confirmable + field :resend_confirmation_instructions, mutation: ::Mutations::Auth::ResendConfirmationInstructions + end + if GraphQL::Auth.configuration.allow_lock_account field :lock_account, mutation: Mutations::Auth::LockAccount end diff --git a/lib/graphql-auth/configuration.rb b/lib/graphql-auth/configuration.rb index 6a8b781..18e3d37 100644 --- a/lib/graphql-auth/configuration.rb +++ b/lib/graphql-auth/configuration.rb @@ -8,6 +8,7 @@ class Configuration :allow_sign_up, :allow_lock_account, :allow_unlock_account, + :allow_email_confirmable, :sign_up_mutation, :update_account_mutation @@ -22,6 +23,7 @@ def initialize @allow_sign_up = true @allow_lock_account = false @allow_unlock_account = false + @allow_email_confirmable = false # Allow custom mutations for signup and update account @sign_up_mutation = '::Mutations::Auth::SignUp' diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index 0832c42..fc93d0a 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.2' + VERSION = '0.7.3' end end \ No newline at end of file diff --git a/spec/dummy/app/models/user.rb b/spec/dummy/app/models/user.rb index 40a343d..f28f392 100644 --- a/spec/dummy/app/models/user.rb +++ b/spec/dummy/app/models/user.rb @@ -4,7 +4,7 @@ class User < ApplicationRecord extend Devise::Models # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + # :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :lockable, :registerable, - :recoverable, :rememberable, :validatable + :recoverable, :rememberable, :validatable, :confirmable end diff --git a/spec/dummy/config/initializers/graphql_auth.rb b/spec/dummy/config/initializers/graphql_auth.rb index 40920c5..9bf928b 100644 --- a/spec/dummy/config/initializers/graphql_auth.rb +++ b/spec/dummy/config/initializers/graphql_auth.rb @@ -10,6 +10,7 @@ config.allow_sign_up = true config.allow_lock_account = true config.allow_unlock_account = true + config.allow_email_confirmable = true # Allow custom mutations for signup and update account # config.sign_up_mutation = '::Mutations::Auth::SignUp' diff --git a/spec/dummy/config/routes.rb b/spec/dummy/config/routes.rb index 79de989..768df5d 100644 --- a/spec/dummy/config/routes.rb +++ b/spec/dummy/config/routes.rb @@ -1,5 +1,5 @@ Rails.application.routes.draw do post '/graphql', to: 'graphql#execute' - devise_for :users, skip: :all + devise_for :users#, skip: :all end \ No newline at end of file diff --git a/spec/dummy/db/migrate/20190108110416_devise_create_users.rb b/spec/dummy/db/migrate/20190108110416_devise_create_users.rb index e4fe133..6004021 100644 --- a/spec/dummy/db/migrate/20190108110416_devise_create_users.rb +++ b/spec/dummy/db/migrate/20190108110416_devise_create_users.rb @@ -22,10 +22,10 @@ def change # t.inet :last_sign_in_ip ## Confirmable - # t.string :confirmation_token - # t.datetime :confirmed_at - # t.datetime :confirmation_sent_at - # t.string :unconfirmed_email # Only if using reconfirmable + t.string :confirmation_token + t.datetime :confirmed_at + t.datetime :confirmation_sent_at + t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb index 88ca44d..a7dff7e 100644 --- a/spec/dummy/db/schema.rb +++ b/spec/dummy/db/schema.rb @@ -2,11 +2,11 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `rails +# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. @@ -39,6 +39,10 @@ t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" + t.string "unconfirmed_email" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "refresh_token" @@ -47,4 +51,5 @@ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" end diff --git a/spec/graphql/mutations/auth/forgot_password_spec.rb b/spec/graphql/mutations/auth/forgot_password_spec.rb index 0b35bdc..985d121 100644 --- a/spec/graphql/mutations/auth/forgot_password_spec.rb +++ b/spec/graphql/mutations/auth/forgot_password_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Mutations::Auth::ForgotPassword, type: :request do - let!(:user) { User.create!(email: 'user@example.com', password: 'password') } + let!(:user) { User.create!(email: 'user@example.com', password: 'password', confirmed_at: DateTime.now) } let(:result) do GraphqlSchema.execute( @@ -87,7 +87,7 @@ end context 'when user is locked' do - let!(:locked_user) { User.create!(email: 'locked_user@example.com', password: 'password') } + let!(:locked_user) { User.create!(email: 'locked_user@example.com', password: 'password', confirmed_at: DateTime.now) } let(:variables) do { diff --git a/spec/graphql/mutations/auth/resend_confirmation_instructions_spec.rb b/spec/graphql/mutations/auth/resend_confirmation_instructions_spec.rb new file mode 100644 index 0000000..d0b735d --- /dev/null +++ b/spec/graphql/mutations/auth/resend_confirmation_instructions_spec.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Auth::ResendConfirmationInstructions, type: :request do + let!(:user) { User.create!(email: 'unconfirmed_user@example.com', password: 'password') } + + let(:result) do + GraphqlSchema.execute( + query_string, + variables: variables, + context: context + ) + end + + let(:query_string) do + <<-GRAPHQL + mutation($email: String!) { + resendConfirmationInstructions(email: $email) { + errors { + field + message + } + success + valid + } + } + GRAPHQL + end + + let(:context) do + { + current_user: nil, + response: ResponseMock.new(headers: {}), + } + end + + subject { result } + + context 'when valid parameters are given' do + let(:variables) do + { + 'email' => user.email + } + end + + before do + subject + end + + it 'sends a email confirmation instructions email' do + email = ActionMailer::Base.deliveries.find{|email| email[:To].value == variables['email'] } + + expect(email[:To].value).to eq(user.email) + expect(email[:Subject].value).to eq('Confirmation instructions') + end + + it 'returns a success' do + expect(result['data']['resendConfirmationInstructions']['errors']).to match_array([]) + expect(result['data']['resendConfirmationInstructions']['success']).to be_truthy + expect(result['data']['resendConfirmationInstructions']['valid']).to be_truthy + end + end + + context 'when invalid parameters are given' do + let(:variables) do + { + 'email' => 'bademail@example.com' + } + end + + before do + subject + end + + it 'does not sends a email confirmation instructions email' do + email = ActionMailer::Base.deliveries.find{|email| email[:To].value == variables['email'] } + expect(email).to be_nil + end + + it 'gives no clue about the failure' do + subject + expect(result['data']['resendConfirmationInstructions']['errors']).to match_array([]) + expect(result['data']['resendConfirmationInstructions']['success']).to be_truthy + expect(result['data']['resendConfirmationInstructions']['valid']).to be_truthy + end + end + + context 'when user is locked' do + let!(:locked_user) { User.create!(email: 'unconfirmed_locked_user@example.com', password: 'password') } + + let(:variables) do + { + 'email' => locked_user.email + } + end + + before do + locked_user.lock_access! + subject + end + + it 'does not sends a email confirmation instructions email' do + emails = ActionMailer::Base.deliveries.find_all{|email| email[:To].value == variables['email'] } + expect(emails.count).to eq(1) # because when created the user he already got one mail + end + + it 'gives no clue about the failure' do + subject + expect(result['data']['resendConfirmationInstructions']['errors']).to match_array([]) + expect(result['data']['resendConfirmationInstructions']['success']).to be_truthy + expect(result['data']['resendConfirmationInstructions']['valid']).to be_truthy + end + end +end diff --git a/spec/graphql/mutations/auth/sign_in_spec.rb b/spec/graphql/mutations/auth/sign_in_spec.rb index c9a3fd7..80fed5d 100644 --- a/spec/graphql/mutations/auth/sign_in_spec.rb +++ b/spec/graphql/mutations/auth/sign_in_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Mutations::Auth::SignUp, type: :request do let!(:user) do - User.create!(email: 'email@example.com', password: 'password') + User.create!(email: 'email@example.com', password: 'password', confirmed_at: DateTime.now) end let(:result) do From 0986bf43f16f024f464c173db670ad0accda51ed Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Sun, 20 Sep 2020 09:58:02 +0200 Subject: [PATCH 07/15] devise need a base url config for emails --- spec/dummy/config/environments/development.rb | 2 ++ spec/dummy/config/environments/test.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/spec/dummy/config/environments/development.rb b/spec/dummy/config/environments/development.rb index 366e75a..84b3ccf 100644 --- a/spec/dummy/config/environments/development.rb +++ b/spec/dummy/config/environments/development.rb @@ -58,4 +58,6 @@ # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. # config.file_watcher = ActiveSupport::EventedFileUpdateChecker + config.action_mailer.default_url_options = { host: '0.0.0.0:3000' } + end diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb index 0a38fd3..5c48b98 100644 --- a/spec/dummy/config/environments/test.rb +++ b/spec/dummy/config/environments/test.rb @@ -43,4 +43,6 @@ # Raises error for missing translations # config.action_view.raise_on_missing_translations = true + + config.action_mailer.default_url_options = { host: '0.0.0.0:3000' } end From 41a4dc6144a95afa2dca7f47112b260e82490a29 Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Thu, 19 Nov 2020 11:41:34 +0100 Subject: [PATCH 08/15] change active_for_authentication to valid_for_authentication --- app/graphql/mutations/auth/sign_in.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/graphql/mutations/auth/sign_in.rb b/app/graphql/mutations/auth/sign_in.rb index c189e17..d8a81a1 100644 --- a/app/graphql/mutations/auth/sign_in.rb +++ b/app/graphql/mutations/auth/sign_in.rb @@ -32,7 +32,7 @@ def resolve(email:, password:, remember_me:) valid_sign_in = user.present? && user.valid_password?(password) # check confirmable - if valid_sign_in && user.respond_to?(:confirmed?) && !user.active_for_authentication? + if valid_sign_in && user.respond_to?(:confirmed?) && !user.valid_for_authentication? return { errors: [ { From 0e00e2b64a4eac78f2ba20212402787fb485965a Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Thu, 19 Nov 2020 11:42:11 +0100 Subject: [PATCH 09/15] update version --- lib/graphql-auth/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index fc93d0a..238c355 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.3' + VERSION = '0.7.4' end end \ No newline at end of file From 5dabdf89605b8033b0521a2c626b7cd6c4f30444 Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Thu, 19 Nov 2020 11:46:02 +0100 Subject: [PATCH 10/15] make valid check before pw check --- app/graphql/mutations/auth/sign_in.rb | 4 ++-- lib/graphql-auth/version.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/graphql/mutations/auth/sign_in.rb b/app/graphql/mutations/auth/sign_in.rb index d8a81a1..5caff54 100644 --- a/app/graphql/mutations/auth/sign_in.rb +++ b/app/graphql/mutations/auth/sign_in.rb @@ -29,10 +29,10 @@ def resolve(email:, password:, remember_me:) user = User.find_by email: email end - valid_sign_in = user.present? && user.valid_password?(password) + valid_sign_in = user.present? && user.valid_for_authentication? && user.valid_password?(password) # check confirmable - if valid_sign_in && user.respond_to?(:confirmed?) && !user.valid_for_authentication? + if valid_sign_in && user.respond_to?(:confirmed?) && !user.active_for_authentication? return { errors: [ { diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index 238c355..0915286 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.4' + VERSION = '0.7.5' end end \ No newline at end of file From 381bb3e825d9f8a82f9085227e7a73c265f69f81 Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Thu, 19 Nov 2020 13:20:28 +0100 Subject: [PATCH 11/15] Update sign in mutation to track failed attempts --- app/graphql/mutations/auth/sign_in.rb | 69 ++++++++++++++++----------- lib/graphql-auth/version.rb | 2 +- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/app/graphql/mutations/auth/sign_in.rb b/app/graphql/mutations/auth/sign_in.rb index 5caff54..3da597e 100644 --- a/app/graphql/mutations/auth/sign_in.rb +++ b/app/graphql/mutations/auth/sign_in.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - class Mutations::Auth::SignIn < GraphQL::Schema::Mutation include ::Graphql::AccountLockHelper include ::Graphql::TokenHelper @@ -23,45 +21,58 @@ class Mutations::Auth::SignIn < GraphQL::Schema::Mutation def resolve(email:, password:, remember_me:) response = context[:response] - if lockable? - user = User.where(locked_at: nil).find_by email: email - else - user = User.find_by email: email - end + user = User.find_by email: email + valid_sign_in = user.present? && user.valid_password?(password) - valid_sign_in = user.present? && user.valid_for_authentication? && user.valid_password?(password) + device_lockable_enabled = user.lock_strategy_enabled?(:failed_attempts) - # check confirmable - if valid_sign_in && user.respond_to?(:confirmed?) && !user.active_for_authentication? - return { - errors: [ - { - field: :_error, - message: I18n.t('devise.failure.unconfirmed') + if device_lockable_enabled + if user.access_locked? + return { + errors: [ + { + field: :_error, + message: I18n.t('devise.failure.locked') + } + ], + success: false, + user: nil + } + end + + user.increment_failed_attempts + + if user.send('attempts_exceeded?') + user.lock_access! unless user.access_locked? + + return { + errors: [ + { + field: :_error, + message: I18n.t('devise.failure.locked') + } + ], + success: false, + user: nil } - ], - success: false, - user: nil - } + else + user.save(validate: false) + end end + # TODO return locked message, when account locked + + if valid_sign_in generate_access_token(user, response) set_current_user(user) remember_me ? set_refresh_token(user, response) : delete_refresh_token(user) - - { - errors: [], - success: true, - user: user - } else - { + return { errors: [ { field: :_error, - message: I18n.t('devise.failure.invalid', - authentication_keys: I18n.t('activerecord.attributes.user.email')) + message: I18n.t('devise.failure.noaccess') } ], success: false, @@ -69,4 +80,4 @@ def resolve(email:, password:, remember_me:) } end end -end +end \ No newline at end of file diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index 0915286..69409ae 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.5' + VERSION = '0.7.6' end end \ No newline at end of file From 2136dafc258d43498f77531f1ea5d2bac397bfd3 Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Fri, 20 Nov 2020 10:24:52 +0100 Subject: [PATCH 12/15] update increment failed attempts --- app/graphql/mutations/auth/sign_in.rb | 28 +++++++++++++-------------- lib/graphql-auth/version.rb | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/graphql/mutations/auth/sign_in.rb b/app/graphql/mutations/auth/sign_in.rb index 3da597e..58a330b 100644 --- a/app/graphql/mutations/auth/sign_in.rb +++ b/app/graphql/mutations/auth/sign_in.rb @@ -26,20 +26,20 @@ def resolve(email:, password:, remember_me:) device_lockable_enabled = user.lock_strategy_enabled?(:failed_attempts) - if device_lockable_enabled - if user.access_locked? - return { - errors: [ - { - field: :_error, - message: I18n.t('devise.failure.locked') - } - ], - success: false, - user: nil - } - end + if user.access_locked? + return { + errors: [ + { + field: :_error, + message: I18n.t('devise.failure.locked') + } + ], + success: false, + user: nil + } + end + if device_lockable_enabled && !valid_sign_in user.increment_failed_attempts if user.send('attempts_exceeded?') @@ -60,7 +60,7 @@ def resolve(email:, password:, remember_me:) end end - # TODO return locked message, when account locked + # TODO tests && error messages if valid_sign_in diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index 69409ae..b31e1b7 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.6' + VERSION = '0.7.7' end end \ No newline at end of file From da83b062af1b944dd1fccdce1b5ed4ac69b486eb Mon Sep 17 00:00:00 2001 From: Simon Franzen Date: Fri, 20 Nov 2020 10:32:21 +0100 Subject: [PATCH 13/15] return correct success after login --- app/graphql/mutations/auth/sign_in.rb | 5 +++++ lib/graphql-auth/version.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/graphql/mutations/auth/sign_in.rb b/app/graphql/mutations/auth/sign_in.rb index 58a330b..6e61f4a 100644 --- a/app/graphql/mutations/auth/sign_in.rb +++ b/app/graphql/mutations/auth/sign_in.rb @@ -67,6 +67,11 @@ def resolve(email:, password:, remember_me:) generate_access_token(user, response) set_current_user(user) remember_me ? set_refresh_token(user, response) : delete_refresh_token(user) + { + errors: [], + success: true, + user: user + } else return { errors: [ diff --git a/lib/graphql-auth/version.rb b/lib/graphql-auth/version.rb index b31e1b7..897b874 100644 --- a/lib/graphql-auth/version.rb +++ b/lib/graphql-auth/version.rb @@ -1,5 +1,5 @@ module GraphQL module Auth - VERSION = '0.7.7' + VERSION = '0.7.8' end end \ No newline at end of file From 57f58e1e60af6119dfbe0665d7707143452eeff9 Mon Sep 17 00:00:00 2001 From: Brice Sanchez Date: Sat, 21 Nov 2020 01:14:25 -0500 Subject: [PATCH 14/15] Remove circular require warning: loading in progress, circular require considered harmful --- lib/graphql-auth/jwt_manager.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/graphql-auth/jwt_manager.rb b/lib/graphql-auth/jwt_manager.rb index b2574f7..6a70af1 100644 --- a/lib/graphql-auth/jwt_manager.rb +++ b/lib/graphql-auth/jwt_manager.rb @@ -1,5 +1,4 @@ require 'jwt' -require 'graphql-auth' module GraphQL module Auth From b6589c94af4212c2e9e691cd8667d9b6850987ad Mon Sep 17 00:00:00 2001 From: Brice Sanchez Date: Sat, 21 Nov 2020 01:14:51 -0500 Subject: [PATCH 15/15] Fix autoload_paths It allows to start the application with zeitwerk --- lib/graphql-auth/engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/graphql-auth/engine.rb b/lib/graphql-auth/engine.rb index d85710c..6a815c7 100644 --- a/lib/graphql-auth/engine.rb +++ b/lib/graphql-auth/engine.rb @@ -3,7 +3,7 @@ module Auth class Engine < ::Rails::Engine isolate_namespace GraphQL::Auth - config.autoload_paths += Dir["#{config.root}/app/**/"] + config.autoload_paths += Dir["#{config.root}/app/**/*.rb"] end end end \ No newline at end of file